Merge branch 'bugfix-2.1.x' into pr/27035
This commit is contained in:
@@ -14,6 +14,8 @@ on:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- test/**
|
||||
- Marlin/tests/**
|
||||
- '**/*.md'
|
||||
push:
|
||||
branches:
|
||||
@@ -23,6 +25,8 @@ on:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- test/**
|
||||
- Marlin/tests/**
|
||||
- '**/*.md'
|
||||
|
||||
jobs:
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# ci-validate-pins.yml
|
||||
# Validate that all of the pins files are unchanged by pinsformat.py
|
||||
#
|
||||
|
||||
name: CI - Validate Pins Files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- bugfix-2.1.x
|
||||
# Cannot be enabled on 2.1.x until it contains the unit test framework
|
||||
#- 2.1.x
|
||||
paths:
|
||||
- 'Marlin/src/pins/*/**'
|
||||
push:
|
||||
branches:
|
||||
- bugfix-2.1.x
|
||||
# Cannot be enabled on 2.1.x until it contains the unit test framework
|
||||
#- 2.1.x
|
||||
paths:
|
||||
- 'Marlin/src/pins/*/**'
|
||||
|
||||
jobs:
|
||||
validate_pins_files:
|
||||
name: Validate Pins Files
|
||||
if: github.repository == 'MarlinFirmware/Marlin'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out the PR
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: Select Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.9'
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Validate all pins files
|
||||
run: |
|
||||
make validate-pins -j
|
||||
@@ -2,22 +2,23 @@ SCRIPTS_DIR := buildroot/share/scripts
|
||||
CONTAINER_RT_BIN := docker
|
||||
CONTAINER_RT_OPTS := --rm -v $(PWD):/code -v platformio-cache:/root/.platformio
|
||||
CONTAINER_IMAGE := marlin-dev
|
||||
UNIT_TEST_CONFIG ?= default
|
||||
|
||||
help:
|
||||
@echo "Tasks for local development:"
|
||||
@echo "make marlin : Build marlin for the configured board"
|
||||
@echo "make format-pins : Reformat all pins files"
|
||||
@echo "make format-pins -j : Reformat all pins files (-j for parallel execution)"
|
||||
@echo "make validate-pins -j : Validate all pins files, fails if any require reformatting"
|
||||
@echo "make tests-single-ci : Run a single test from inside the CI"
|
||||
@echo "make tests-single-local : Run a single test locally"
|
||||
@echo "make tests-single-local-docker : Run a single test locally, using docker"
|
||||
@echo "make tests-all-local : Run all tests locally"
|
||||
@echo "make tests-all-local-docker : Run all tests locally, using docker"
|
||||
# @echo "make unit-test-single-ci : Run a single code test from inside the CI"
|
||||
# @echo "make unit-test-single-local : Run a single code test locally"
|
||||
# @echo "make unit-test-single-local-docker : Run a single code test locally, using docker-compose"
|
||||
@echo "make unit-test-single-local : Run unit tests for a single config locally"
|
||||
@echo "make unit-test-single-local-docker : Run unit tests for a single config locally, using docker"
|
||||
@echo "make unit-test-all-local : Run all code tests locally"
|
||||
@echo "make unit-test-all-local-docker : Run all code tests locally, using docker-compose"
|
||||
@echo "make setup-local-docker : Setup local docker-compose"
|
||||
@echo "make unit-test-all-local-docker : Run all code tests locally, using docker"
|
||||
@echo "make setup-local-docker : Setup local docker using buildx"
|
||||
@echo ""
|
||||
@echo "Options for testing:"
|
||||
@echo " TEST_TARGET Set when running tests-single-*, to select the"
|
||||
@@ -27,6 +28,9 @@ help:
|
||||
@echo " run on GitHub CI"
|
||||
@echo " ONLY_TEST Limit tests to only those that contain this, or"
|
||||
@echo " the index of the test (1-based)"
|
||||
@echo " UNIT_TEST_CONFIG Set the name of the config from the test folder, without"
|
||||
@echo " the leading number. Default is 'default'". Used with the
|
||||
@echo " unit-test-single-* tasks"
|
||||
@echo " VERBOSE_PLATFORMIO If you want the full PIO output, set any value"
|
||||
@echo " GIT_RESET_HARD Used by CI: reset all local changes. WARNING:"
|
||||
@echo " THIS WILL UNDO ANY CHANGES YOU'VE MADE!"
|
||||
@@ -51,27 +55,29 @@ tests-single-local-docker:
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
|
||||
|
||||
tests-all-local:
|
||||
@python -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "python -m pip install pyyaml"' && exit 1)
|
||||
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
|
||||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
||||
&& for TEST_TARGET in $$($(SCRIPTS_DIR)/get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
|
||||
&& for TEST_TARGET in $$(python $(SCRIPTS_DIR)/get_test_targets.py) ; do \
|
||||
if [ "$$TEST_TARGET" = "linux_native" ] && [ "$$(uname)" = "Darwin" ]; then \
|
||||
echo "Skipping tests for $$TEST_TARGET on macOS" ; \
|
||||
continue ; \
|
||||
fi ; \
|
||||
echo "Running tests for $$TEST_TARGET" ; \
|
||||
run_tests . $$TEST_TARGET || exit 1 ; \
|
||||
sleep 5; \
|
||||
done
|
||||
|
||||
tests-all-local-docker:
|
||||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
|
||||
|
||||
#unit-test-single-ci:
|
||||
# export GIT_RESET_HARD=true
|
||||
# $(MAKE) unit-test-single-local TEST_TARGET=$(TEST_TARGET)
|
||||
unit-test-single-local:
|
||||
platformio run -t marlin_$(UNIT_TEST_CONFIG) -e linux_native_test
|
||||
|
||||
# TODO: How can we limit tests with ONLY_TEST with platformio?
|
||||
#unit-test-single-local:
|
||||
# @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make unit-test-all-local" ; return 1; fi
|
||||
# platformio run -t marlin_$(TEST_TARGET)
|
||||
|
||||
#unit-test-single-local-docker:
|
||||
# @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make unit-test-all-local-docker" ; return 1; fi
|
||||
# @if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
# $(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-single-local TEST_TARGET=$(TEST_TARGET) ONLY_TEST="$(ONLY_TEST)"
|
||||
unit-test-single-local-docker:
|
||||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-single-local UNIT_TEST_CONFIG=$(UNIT_TEST_CONFIG)
|
||||
|
||||
unit-test-all-local:
|
||||
platformio run -t test-marlin -e linux_native_test
|
||||
@@ -85,7 +91,14 @@ setup-local-docker:
|
||||
|
||||
PINS := $(shell find Marlin/src/pins -mindepth 2 -name '*.h')
|
||||
|
||||
.PHONY: $(PINS) format-pins validate-pins
|
||||
|
||||
$(PINS): %:
|
||||
@echo "Formatting $@" && node $(SCRIPTS_DIR)/pinsformat.js $@
|
||||
@echo "Formatting $@"
|
||||
@python $(SCRIPTS_DIR)/pinsformat.py $< $@
|
||||
|
||||
format-pins: $(PINS)
|
||||
|
||||
validate-pins: format-pins
|
||||
@echo "Validating pins files"
|
||||
@git diff --exit-code || (git status && echo "\nError: Pins files are not formatted correctly. Run \"make format-pins\" to fix.\n" && exit 1)
|
||||
|
||||
@@ -672,7 +672,7 @@
|
||||
* MPCTEMP : Predictive Model temperature control. (~1.8K without auto-tune)
|
||||
*/
|
||||
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
|
||||
//#define MPCTEMP // ** EXPERIMENTAL ** See https://marlinfw.org/docs/features/model_predictive_control.html
|
||||
//#define MPCTEMP // See https://marlinfw.org/docs/features/model_predictive_control.html
|
||||
|
||||
#define PID_MAX 255 // Limit hotend current while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
|
||||
#define PID_K1 0.95 // Smoothing factor within any PID loop
|
||||
@@ -2218,7 +2218,7 @@
|
||||
#if ENABLED(LCD_BED_TRAMMING)
|
||||
#define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
|
||||
#define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at tramming points
|
||||
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between tramming points
|
||||
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z raise between tramming points
|
||||
//#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
|
||||
//#define BED_TRAMMING_USE_PROBE
|
||||
#if ENABLED(BED_TRAMMING_USE_PROBE)
|
||||
|
||||
@@ -4261,7 +4261,8 @@
|
||||
|
||||
/**
|
||||
* Instant freeze / unfreeze functionality
|
||||
* Potentially useful for emergency stop that allows being resumed.
|
||||
* Potentially useful for rapid stop that allows being resumed. Halts stepper movement.
|
||||
* Note this does NOT pause spindles, lasers, fans, heaters or any other auxiliary device.
|
||||
* @section interface
|
||||
*/
|
||||
//#define FREEZE_FEATURE
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
//#define STRING_DISTRIBUTION_DATE "2024-04-19"
|
||||
//#define STRING_DISTRIBUTION_DATE "2024-05-13"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
#else
|
||||
#define G2_PWM_Z 0
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
#define G2_PWM_E 1
|
||||
#else
|
||||
#define G2_PWM_E 0
|
||||
|
||||
@@ -148,6 +148,25 @@
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
|
||||
//
|
||||
// Debug port disable
|
||||
// JTMS / SWDIO = PA13
|
||||
// JTCK / SWCLK = PA14
|
||||
// JTDI = PA15
|
||||
// JTDO = PB3
|
||||
// NJTRST = PB4
|
||||
//
|
||||
#define DBG_SWCLK _BV(0)
|
||||
#define DBG_SWDIO _BV(1)
|
||||
#define DBG_TDO _BV(2)
|
||||
#define DBG_TDI _BV(3)
|
||||
#define DBG_TRST _BV(4)
|
||||
#define DBG_ALL (DBG_SWCLK | DBG_SWDIO | DBG_TDO | DBG_TDI | DBG_TRST)
|
||||
|
||||
#define JTAGSWD_RESET() PORT_DebugPortSetting(DBG_ALL, Enable);
|
||||
#define JTAG_DISABLE() PORT_DebugPortSetting(DBG_TDO | DBG_TDI | DBG_TRST, Disable);
|
||||
#define JTAGSWD_DISABLE() PORT_DebugPortSetting(DBG_ALL, Disable);
|
||||
|
||||
//
|
||||
// MarlinHAL implementation
|
||||
//
|
||||
|
||||
@@ -31,8 +31,8 @@
|
||||
|
||||
struct MarlinSerial : public Usart {
|
||||
MarlinSerial(
|
||||
struct usart_config_t *usart_device,
|
||||
gpio_pin_t tx_pin,
|
||||
struct usart_config_t *usart_device,
|
||||
gpio_pin_t tx_pin,
|
||||
gpio_pin_t rx_pin
|
||||
#if ENABLED(SERIAL_DMA)
|
||||
, M4_DMA_TypeDef *dma_unit = nullptr,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* app_config.h is included by the hc32f460 arduino build script for every source file.
|
||||
* it is used to configure the arduino core (and ddl) automatically according
|
||||
* it is used to configure the arduino core (and ddl) automatically according
|
||||
* to the settings in Configuration.h and Configuration_adv.h.
|
||||
*/
|
||||
#pragma once
|
||||
@@ -44,7 +44,7 @@
|
||||
#define DISABLE_SERIAL_GLOBALS 1
|
||||
|
||||
// increase the size of the Usart buffers (both RX and TX)
|
||||
// NOTE:
|
||||
// NOTE:
|
||||
// the heap usage will increase by (SERIAL_BUFFER_SIZE - 64) * "number of serial ports used"
|
||||
// if running out of heap, the system may become unstable
|
||||
//#define SERIAL_BUFFER_SIZE 256
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#endif
|
||||
|
||||
#if ARDUINO_CORE_VERSION_INT < GET_VERSION_INT(1, 1, 0)
|
||||
// because we use app_config.h introduced in arduino core version 1.1.0, the
|
||||
// because we use app_config.h introduced in arduino core version 1.1.0, the
|
||||
// HAL is not compatible with older versions
|
||||
#error "The HC32 HAL is not compatible with Arduino Core versions < 1.1.0. Consider updating the Arduino Core."
|
||||
#endif
|
||||
|
||||
@@ -266,7 +266,7 @@ PGMSTR(M112_KILL_STR, "M112 Shutdown");
|
||||
MarlinState marlin_state = MF_INITIALIZING;
|
||||
|
||||
// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
|
||||
bool wait_for_heatup = true;
|
||||
bool wait_for_heatup = false;
|
||||
|
||||
// For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop
|
||||
#if HAS_RESUME_CONTINUE
|
||||
|
||||
@@ -383,9 +383,9 @@
|
||||
#define BOARD_CREALITY_V452 5050 // Creality v4.5.2 (STM32F103RC / STM32F103RE)
|
||||
#define BOARD_CREALITY_V453 5051 // Creality v4.5.3 (STM32F103RC / STM32F103RE)
|
||||
#define BOARD_CREALITY_V521 5052 // Creality v5.2.1 (STM32F103VE) as found in the SV04
|
||||
#define BOARD_CREALITY_V24S1 5053 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7
|
||||
#define BOARD_CREALITY_V24S1_301 5054 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1
|
||||
#define BOARD_CREALITY_V25S1 5055 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro
|
||||
#define BOARD_CREALITY_V24S1 5053 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) CR-FDM-v2.4.S1_v101 as found in the Ender-7
|
||||
#define BOARD_CREALITY_V24S1_301 5054 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) CR-FDM-v24S1_301 as found in the Ender-3 S1
|
||||
#define BOARD_CREALITY_V25S1 5055 // Creality v2.5.S1 (STM32F103RE) CR-FDM-v2.5.S1_100 as found in the CR-10 Smart Pro
|
||||
#define BOARD_TRIGORILLA_PRO 5056 // Trigorilla Pro (STM32F103ZE)
|
||||
#define BOARD_FLY_MINI 5057 // FLYmaker FLY MINI (STM32F103RC)
|
||||
#define BOARD_FLSUN_HISPEED 5058 // FLSUN HiSpeedV1 (STM32F103VE)
|
||||
|
||||
@@ -143,13 +143,13 @@ public:
|
||||
|
||||
// Set with format string and arguments, like printf
|
||||
template<typename... Args>
|
||||
MString& setf_P(PGM_P const fmt, Args... more) { SNPRINTF_P(str, SIZE, fmt, more...); debug(F("setf_P")); return *this; }
|
||||
MString& setf_P(PGM_P const pfmt, Args... more) { SNPRINTF_P(str, SIZE, pfmt, more...); debug(F("setf_P")); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
MString& setf(const char *fmt, Args... more) { SNPRINTF(str, SIZE, fmt, more...); debug(F("setf")); return *this; }
|
||||
MString& setf(const char *fmt, Args... more) { SNPRINTF(str, SIZE, fmt, more...); debug(F("setf")); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
MString& setf(FSTR_P const fmt, Args... more) { return setf_P(FTOP(fmt), more...); }
|
||||
MString& setf(FSTR_P const ffmt, Args... more) { return setf_P(FTOP(ffmt), more...); }
|
||||
|
||||
// Chainable String appenders
|
||||
MString& append() { debug(F("nil")); return *this; } // for macros that might emit no output
|
||||
@@ -206,9 +206,9 @@ public:
|
||||
MString& append(const spaces_t &s) { return append(repchr_t(' ', s.count)); }
|
||||
|
||||
template<typename... Args>
|
||||
MString& appendf_P(PGM_P const fmt, Args... more) {
|
||||
MString& appendf_P(PGM_P const pfmt, Args... more) {
|
||||
int sz = length();
|
||||
if (sz < SIZE) SNPRINTF_P(str + sz, SIZE - sz, fmt, more...);
|
||||
if (sz < SIZE) SNPRINTF_P(str + sz, SIZE - sz, pfmt, more...);
|
||||
debug(F("appendf_P"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -271,13 +271,13 @@ public:
|
||||
SString& set() { super::set(); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
SString& setf_P(PGM_P const fmt, Args... more) { super::setf_P(fmt, more...); return *this; }
|
||||
SString& setf_P(PGM_P const pfmt, Args... more) { super::setf_P(pfmt, more...); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
SString& setf(const char *fmt, Args... more) { super::setf(fmt, more...); return *this; }
|
||||
SString& setf(const char *fmt, Args... more) { super::setf(fmt, more...); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
SString& setf(FSTR_P const fmt, Args... more) { super::setf(fmt, more...); return *this; }
|
||||
SString& setf(FSTR_P const ffmt, Args... more) { super::setf(ffmt, more...); return *this; }
|
||||
|
||||
template <typename T>
|
||||
SString& set(const T &v) { super::set(v); return *this; }
|
||||
|
||||
+10
-2
@@ -46,6 +46,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define NUM_AXIS_DECL(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W)
|
||||
#define MAIN_AXIS_NAMES_LC NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)
|
||||
#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
|
||||
#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E)
|
||||
@@ -58,17 +59,21 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K, U, V, W)
|
||||
#define LOGICAL_AXIS_NAMES_LC LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)
|
||||
#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES)
|
||||
#define LOGICAL_AXIS_MAP_LC(F) MAP(F, LOGICAL_AXIS_NAMES_LC)
|
||||
#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
|
||||
#if NUM_AXES
|
||||
#define NUM_AXES_SEP ,
|
||||
#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES)
|
||||
#define MAIN_AXIS_MAP_LC(F) MAP(F, MAIN_AXIS_NAMES_LC)
|
||||
#define OPTARGS_NUM(T) , NUM_AXIS_ARGS(T)
|
||||
#define OPTARGS_LOGICAL(T) , LOGICAL_AXIS_ARGS(T)
|
||||
#else
|
||||
#define NUM_AXES_SEP
|
||||
#define MAIN_AXIS_MAP(F)
|
||||
#define MAIN_AXIS_MAP_LC(F)
|
||||
#define OPTARGS_NUM(T)
|
||||
#define OPTARGS_LOGICAL(T)
|
||||
#endif
|
||||
@@ -79,6 +84,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define NUM_AXIS_ARGS_(T) NUM_AXIS_ARGS(T) NUM_AXES_SEP
|
||||
#define NUM_AXIS_ELEM_(T) NUM_AXIS_ELEM(T) NUM_AXES_SEP
|
||||
#define MAIN_AXIS_NAMES_ MAIN_AXIS_NAMES NUM_AXES_SEP
|
||||
#define MAIN_AXIS_NAMES_LC_ MAIN_AXIS_NAMES_LC NUM_AXES_SEP
|
||||
|
||||
#if LOGICAL_AXES
|
||||
#define LOGICAL_AXES_SEP ,
|
||||
@@ -92,6 +98,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define LOGICAL_AXIS_ARGS_(T) LOGICAL_AXIS_ARGS(T) LOGICAL_AXES_SEP
|
||||
#define LOGICAL_AXIS_ELEM_(T) LOGICAL_AXIS_ELEM(T) LOGICAL_AXES_SEP
|
||||
#define LOGICAL_AXIS_NAMES_ LOGICAL_AXIS_NAMES LOGICAL_AXES_SEP
|
||||
#define LOGICAL_AXIS_NAMES_LC_ LOGICAL_AXIS_NAMES_LC LOGICAL_AXES_SEP
|
||||
|
||||
#define SECONDARY_AXIS_GANG(V...) GANG_N(SECONDARY_AXES, V)
|
||||
#define SECONDARY_AXIS_CODE(V...) CODE_N(SECONDARY_AXES, V)
|
||||
@@ -159,7 +166,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
// General Flags for some number of states
|
||||
template<size_t N>
|
||||
struct Flags {
|
||||
typedef uvalue_t(N) flagbits_t;
|
||||
typedef bits_t(N) flagbits_t;
|
||||
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } N8;
|
||||
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1; } N16;
|
||||
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1,
|
||||
@@ -219,7 +226,7 @@ typedef struct {
|
||||
//
|
||||
// - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space
|
||||
// - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians
|
||||
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
|
||||
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for axes on Core kinematics
|
||||
//
|
||||
enum AxisEnum : uint8_t {
|
||||
|
||||
@@ -1084,6 +1091,7 @@ public:
|
||||
FI bool toggle(const AxisEnum n) { TBI(bits, n); return TEST(bits, n); }
|
||||
FI void bset(const AxisEnum n) { SBI(bits, n); }
|
||||
FI void bclr(const AxisEnum n) { CBI(bits, n); }
|
||||
FI void bset(const AxisEnum n, const bool b) { if (b) bset(n); else bclr(n); }
|
||||
|
||||
// Accessor via an AxisEnum (or any integer) [index]
|
||||
FI bool operator[](const int n) const { return TEST(bits, n); }
|
||||
|
||||
@@ -765,7 +765,7 @@ void unified_bed_leveling::shift_mesh_height() {
|
||||
|
||||
const grid_count_t point_num = (GRID_MAX_POINTS - count) + 1;
|
||||
SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
|
||||
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
|
||||
|
||||
#if HAS_MARLINUI_MENU
|
||||
@@ -1494,7 +1494,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
||||
|
||||
for (uint8_t i = 0; i < 3; ++i) {
|
||||
SERIAL_ECHOLNPGM("Tilting mesh (", i + 1, "/3)");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_LCD_TILTING_MESH), i + 1));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_LCD_TILTING_MESH), i + 1));
|
||||
|
||||
measured_z = probe.probe_at_point(points[i], i < 2 ? PROBE_PT_RAISE : PROBE_PT_LAST_STOW, param.V_verbosity);
|
||||
if ((abort_flag = isnan(measured_z))) break;
|
||||
@@ -1550,7 +1550,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_LCD_TILTING_MESH), point_num, total_points));
|
||||
|
||||
measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
|
||||
// Retract by moving from a faux E position back to the current E position
|
||||
current_retract[active_extruder] = base_retract;
|
||||
prepare_internal_move_to_destination( // set current from destination
|
||||
settings.retract_feedrate_mm_s * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS))
|
||||
MUL_TERN(RETRACT_SYNC_MIXING, settings.retract_feedrate_mm_s, MIXING_STEPPERS)
|
||||
);
|
||||
|
||||
// Is a Z hop set, and has the hop not yet been done?
|
||||
@@ -165,8 +165,7 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
|
||||
|
||||
// Recover E, set_current_to_destination
|
||||
prepare_internal_move_to_destination(
|
||||
(swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s)
|
||||
* TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS))
|
||||
MUL_TERN(RETRACT_SYNC_MIXING, swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s, MIXING_STEPPERS)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
}
|
||||
|
||||
// Accessors
|
||||
static uint16_t pixels() { return adaneo1.numPixels() * TERN1(NEOPIXEL2_INSERIES, 2); }
|
||||
static uint16_t pixels() { return MUL_TERN(NEOPIXEL2_INSERIES, adaneo1.numPixels(), 2); }
|
||||
|
||||
static uint32_t pixel_color(const uint16_t n) {
|
||||
#if ENABLED(NEOPIXEL2_INSERIES)
|
||||
|
||||
@@ -31,7 +31,7 @@ static uint32_t axis_plug_backward = 0;
|
||||
void stepper_driver_backward_error(FSTR_P const fstr) {
|
||||
SERIAL_ERROR_START();
|
||||
SERIAL_ECHOLN(fstr, F(" driver is backward!"));
|
||||
ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT(MSG_DRIVER_BACKWARD));
|
||||
ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT_F(MSG_DRIVER_BACKWARD));
|
||||
}
|
||||
|
||||
void stepper_driver_backward_check() {
|
||||
|
||||
@@ -683,7 +683,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
if (TERN0(IS_KINEMATIC, !probe.can_reach(abl.probePos))) continue;
|
||||
|
||||
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", abl.abl_points, ".");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
|
||||
|
||||
#if ENABLED(BD_SENSOR_PROBE_NO_STOP)
|
||||
if (PR_INNER_VAR == inStart) {
|
||||
@@ -782,7 +782,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
|
||||
for (uint8_t i = 0; i < 3; ++i) {
|
||||
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3.");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_PROBING_POINT), int(i + 1)));
|
||||
|
||||
// Retain the last probe position
|
||||
abl.probePos = xy_pos_t(points[i]);
|
||||
|
||||
@@ -253,7 +253,7 @@ void GcodeSuite::G29() {
|
||||
|
||||
if (state == MeshNext) {
|
||||
SERIAL_ECHOLNPGM("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS);
|
||||
if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
|
||||
if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
|
||||
}
|
||||
|
||||
report_current_position();
|
||||
|
||||
@@ -149,7 +149,7 @@ void GcodeSuite::M48() {
|
||||
for (uint8_t n = 0; n < n_samples; ++n) {
|
||||
#if HAS_STATUS_MESSAGE
|
||||
// Display M48 progress in the status bar
|
||||
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT_F(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
#endif
|
||||
|
||||
// When there are "legs" of movement move around the point before probing
|
||||
|
||||
@@ -68,7 +68,7 @@ void GcodeSuite::M907() {
|
||||
#define HAS_X_Y_XY_I_J_K_U_V_W 1
|
||||
#endif
|
||||
|
||||
#if HAS_X_Y_XY_I_J_K_U_V_W || ANY_PIN(MOTOR_CURRENT_PWM_E, MOTOR_CURRENT_PWM_Z)
|
||||
#if HAS_X_Y_XY_I_J_K_U_V_W || HAS_MOTOR_CURRENT_PWM_E || PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
|
||||
if (!parser.seen("S"
|
||||
#if HAS_X_Y_XY_I_J_K_U_V_W
|
||||
@@ -77,7 +77,7 @@ void GcodeSuite::M907() {
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
"Z"
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
"E"
|
||||
#endif
|
||||
)) return M907_report();
|
||||
@@ -94,7 +94,7 @@ void GcodeSuite::M907() {
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
if (parser.seenval('Z')) stepper.set_digipot_current(1, parser.value_int());
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
if (parser.seenval('E')) stepper.set_digipot_current(2, parser.value_int());
|
||||
#endif
|
||||
|
||||
@@ -133,7 +133,7 @@ void GcodeSuite::M907() {
|
||||
SERIAL_ECHOLNPGM_P( // PWM-based has 3 values:
|
||||
PSTR(" M907 X"), stepper.motor_current_setting[0] // X, Y, (I, J, K, U, V, W)
|
||||
, SP_Z_STR, stepper.motor_current_setting[1] // Z
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
, SP_E_STR, stepper.motor_current_setting[2] // E
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -893,10 +893,11 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// FSMC/SPI TFT Panels (LVGL)
|
||||
// FSMC/SPI TFT Panels (LVGL) with encoder click wheel
|
||||
#if ENABLED(TFT_LVGL_UI)
|
||||
#define HAS_TFT_LVGL_UI 1
|
||||
#define SERIAL_RUNTIME_HOOK 1
|
||||
#define STD_ENCODER_PULSES_PER_STEP 4
|
||||
#endif
|
||||
|
||||
// FSMC/SPI TFT Panels
|
||||
@@ -976,6 +977,17 @@
|
||||
#define DETECT_I2C_LCD_DEVICE 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Ender-3 V2 DWIN with Encoder
|
||||
*/
|
||||
#if ANY(DWIN_CREALITY_LCD, DWIN_LCD_PROUI)
|
||||
#define HAS_DWIN_E3V2_BASIC 1
|
||||
#endif
|
||||
#if ANY(HAS_DWIN_E3V2_BASIC, DWIN_CREALITY_LCD_JYERSUI)
|
||||
#define HAS_DWIN_E3V2 1
|
||||
#define STD_ENCODER_PULSES_PER_STEP 4
|
||||
#endif
|
||||
|
||||
// Encoder behavior
|
||||
#ifndef STD_ENCODER_PULSES_PER_STEP
|
||||
#if ENABLED(TOUCH_SCREEN)
|
||||
@@ -997,10 +1009,12 @@
|
||||
#define ENCODER_FEEDRATE_DEADZONE 6
|
||||
#endif
|
||||
|
||||
// Shift register panels
|
||||
// ---------------------
|
||||
// 2 wire Non-latching LCD SR from:
|
||||
// https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection
|
||||
/**
|
||||
* Shift register panels
|
||||
* ---------------------
|
||||
* 2 wire Non-latching LCD SR from:
|
||||
* https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection
|
||||
*/
|
||||
#if ENABLED(FF_INTERFACEBOARD)
|
||||
#define SR_LCD_3W_NL // Non latching 3 wire shift register
|
||||
#define IS_ULTIPANEL 1
|
||||
@@ -1040,11 +1054,6 @@
|
||||
#define EXTENSIBLE_UI
|
||||
#endif
|
||||
|
||||
// Aliases for LCD features
|
||||
#if ANY(DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
|
||||
#define HAS_DWIN_E3V2 1
|
||||
#endif
|
||||
|
||||
// E3V2 extras
|
||||
#if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI
|
||||
#define SERIAL_CATCHALL 0
|
||||
@@ -1594,8 +1603,6 @@
|
||||
#endif
|
||||
#if CORE_IS_XY || CORE_IS_XZ || CORE_IS_YZ
|
||||
#define IS_CORE 1
|
||||
#endif
|
||||
#if IS_CORE
|
||||
#if CORE_IS_XY
|
||||
#define CORE_AXIS_1 A_AXIS
|
||||
#define CORE_AXIS_2 B_AXIS
|
||||
|
||||
@@ -1185,7 +1185,7 @@
|
||||
#elif HAS_DRIVER(A4988)
|
||||
#define MINIMUM_STEPPER_POST_DIR_DELAY 200
|
||||
#elif HAS_TRINAMIC_CONFIG || HAS_TRINAMIC_STANDALONE
|
||||
#define MINIMUM_STEPPER_POST_DIR_DELAY 70
|
||||
#define MINIMUM_STEPPER_POST_DIR_DELAY 100
|
||||
#else
|
||||
#define MINIMUM_STEPPER_POST_DIR_DELAY 0 // Expect at least 10µS since one Stepper ISR must transpire
|
||||
#endif
|
||||
|
||||
@@ -2814,7 +2814,7 @@
|
||||
#if PIN_EXISTS(DIGIPOTSS)
|
||||
#define HAS_MOTOR_CURRENT_SPI 1
|
||||
#endif
|
||||
#if HAS_EXTRUDERS && PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if ANY_PIN(MOTOR_CURRENT_PWM_E, MOTOR_CURRENT_PWM_E0, MOTOR_CURRENT_PWM_E1)
|
||||
#define HAS_MOTOR_CURRENT_PWM_E 1
|
||||
#endif
|
||||
#if HAS_MOTOR_CURRENT_PWM_E || ANY_PIN(MOTOR_CURRENT_PWM_X, MOTOR_CURRENT_PWM_Y, MOTOR_CURRENT_PWM_XY, MOTOR_CURRENT_PWM_Z, MOTOR_CURRENT_PWM_I, MOTOR_CURRENT_PWM_J, MOTOR_CURRENT_PWM_K, MOTOR_CURRENT_PWM_U, MOTOR_CURRENT_PWM_V, MOTOR_CURRENT_PWM_W)
|
||||
|
||||
@@ -1545,6 +1545,9 @@ static_assert(NUM_SERVOS <= NUM_SERVO_PLUGS, "NUM_SERVOS (or some servo index) i
|
||||
#error "BED_TRAMMING_USE_PROBE is incompatible with SENSORLESS_PROBING."
|
||||
#endif
|
||||
#endif
|
||||
static_assert(BED_TRAMMING_Z_HOP >= 0, "BED_TRAMMING_Z_HOP must be >= 0.");
|
||||
#elif ANY(DGUS_LCD_UI_RELOADED, DGUS_LCD_UI_E3S1PRO)
|
||||
#error "LCD_BED_TRAMMING is required for the selected display."
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
* version was tagged.
|
||||
*/
|
||||
#ifndef STRING_DISTRIBUTION_DATE
|
||||
#define STRING_DISTRIBUTION_DATE "2024-04-19"
|
||||
#define STRING_DISTRIBUTION_DATE "2024-05-13"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -99,8 +99,8 @@
|
||||
#warning "Warning! Don't use dummy thermistors (998/999) for final build!"
|
||||
#endif
|
||||
|
||||
#if NONE(HAS_RESUME_CONTINUE, HOST_PROMPT_SUPPORT, UNIT_TEST)
|
||||
#warning "Your Configuration provides no method to acquire user feedback!"
|
||||
#if NONE(HAS_RESUME_CONTINUE, HOST_PROMPT_SUPPORT, UNIT_TEST, NO_USER_FEEDBACK_WARNING)
|
||||
#warning "Your Configuration provides no method to acquire user feedback! (Define NO_USER_FEEDBACK_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
|
||||
#if MB(DUE3DOM_MINI) && PIN_EXISTS(TEMP_2) && !TEMP_SENSOR_BOARD
|
||||
@@ -690,8 +690,12 @@
|
||||
#warning "To prevent step loss, motion will pause for PRINTCOUNTER auto-save."
|
||||
#endif
|
||||
|
||||
#if HOMING_Z_WITH_PROBE && IS_CARTESIAN && DISABLED(Z_SAFE_HOMING)
|
||||
#error "Z_SAFE_HOMING is recommended when homing with a probe. Enable Z_SAFE_HOMING or comment out this line to continue."
|
||||
#if HOMING_Z_WITH_PROBE && IS_CARTESIAN && NONE(Z_SAFE_HOMING, NO_Z_SAFE_HOMING_WARNING)
|
||||
#error "Z_SAFE_HOMING is recommended when homing with a probe. (Enable Z_SAFE_HOMING or define NO_Z_SAFE_HOMING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
|
||||
#if ENABLED(BIQU_MICROPROBE_V2) && NONE(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN, NO_MICROPROBE_WARNING)
|
||||
#warning "BIQU MicroProbe V2 detect signal requires a strong pull-up. Some processors have weak internal pull-up capabilities, so we recommended connecting MicroProbe SIGNAL / GND to Z-MIN / Z-STOP instead of the dedicated PROBE port. (Define NO_MICROPROBE_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -714,8 +718,8 @@
|
||||
#warning "Disabled CONFIGURATION_EMBEDDING because the target usually has less flash storage. Define FORCE_CONFIG_EMBED to override."
|
||||
#endif
|
||||
|
||||
#if HAS_LCD_CONTRAST && LCD_CONTRAST_MIN >= LCD_CONTRAST_MAX
|
||||
#warning "Contrast cannot be changed when LCD_CONTRAST_MIN >= LCD_CONTRAST_MAX."
|
||||
#if HAS_LCD_CONTRAST && LCD_CONTRAST_MIN >= LCD_CONTRAST_MAX && DISABLED(NO_LCD_CONTRAST_WARNING)
|
||||
#warning "Contrast cannot be changed when LCD_CONTRAST_MIN >= LCD_CONTRAST_MAX. (Define NO_LCD_CONTRAST_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
|
||||
#if PROGRESS_MSG_EXPIRE > 0 && HAS_STATUS_MESSAGE_TIMEOUT
|
||||
|
||||
@@ -24,9 +24,9 @@
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
#if ((!HAS_ADC_BUTTONS && IS_NEWPANEL) || BUTTONS_EXIST(EN1, EN2)) && !IS_TFTGLCD_PANEL
|
||||
#define HAS_ENCODER_WHEEL 1
|
||||
#define HAS_MARLINUI_ENCODER 1
|
||||
#endif
|
||||
#if (HAS_ENCODER_WHEEL || ANY_BUTTON(ENC, BACK, UP, DOWN, LEFT, RIGHT)) && DISABLED(TOUCH_UI_FTDI_EVE)
|
||||
#if (HAS_MARLINUI_ENCODER || ANY_BUTTON(ENC, BACK, UP, DOWN, LEFT, RIGHT)) && DISABLED(TOUCH_UI_FTDI_EVE)
|
||||
#define HAS_DIGITAL_BUTTONS 1
|
||||
#endif
|
||||
#if !HAS_ADC_BUTTONS && (IS_RRW_KEYPAD || (HAS_WIRED_LCD && !IS_NEWPANEL))
|
||||
|
||||
@@ -377,10 +377,10 @@ void MarlinUI::draw_kill_screen() {
|
||||
void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
|
||||
|
||||
#if HAS_DISPLAY_SLEEP
|
||||
void MarlinUI::sleep_display(const bool sleep/*=true*/) {
|
||||
void MarlinUI::sleep_display(const bool sleep/*=true*/) {
|
||||
static bool asleep = false;
|
||||
if (asleep != sleep){
|
||||
sleep ? u8g.sleepOn() : u8g.sleepOff();
|
||||
sleep ? u8g.sleepOn() : u8g.sleepOff();
|
||||
asleep = sleep;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,10 +42,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef ENCODER_PULSES_PER_STEP
|
||||
#define ENCODER_PULSES_PER_STEP 4
|
||||
#endif
|
||||
|
||||
EncoderRate encoderRate;
|
||||
|
||||
// TODO: Replace with ui.quick_feedback
|
||||
@@ -53,32 +49,12 @@ void Encoder_tick() {
|
||||
TERN_(HAS_BEEPER, if (ui.sound_on) buzzer.click(10));
|
||||
}
|
||||
|
||||
// Encoder initialization
|
||||
void encoderConfiguration() {
|
||||
#if BUTTON_EXISTS(EN1)
|
||||
SET_INPUT_PULLUP(BTN_EN1);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN2)
|
||||
SET_INPUT_PULLUP(BTN_EN2);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC)
|
||||
SET_INPUT_PULLUP(BTN_ENC);
|
||||
#endif
|
||||
#if HAS_BEEPER
|
||||
SET_OUTPUT(BEEPER_PIN); // TODO: Use buzzer.h which already inits this
|
||||
#endif
|
||||
}
|
||||
|
||||
// Analyze encoder value and return state
|
||||
EncoderState encoderReceiveAnalyze() {
|
||||
const millis_t now = millis();
|
||||
static uint8_t lastEncoderBits;
|
||||
uint8_t newbutton = 0;
|
||||
static signed char temp_diff = 0;
|
||||
static int8_t temp_diff = 0; // Cleared on each full step, as configured
|
||||
|
||||
EncoderState temp_diffState = ENCODER_DIFF_NO;
|
||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
||||
if (BUTTON_PRESSED(ENC)) {
|
||||
static millis_t next_click_update_ms;
|
||||
if (ELAPSED(now, next_click_update_ms)) {
|
||||
@@ -98,71 +74,47 @@ EncoderState encoderReceiveAnalyze() {
|
||||
}
|
||||
else return ENCODER_DIFF_NO;
|
||||
}
|
||||
if (newbutton != lastEncoderBits) {
|
||||
switch (newbutton) {
|
||||
case 0:
|
||||
if (lastEncoderBits == 1) temp_diff++;
|
||||
else if (lastEncoderBits == 2) temp_diff--;
|
||||
break;
|
||||
case 2:
|
||||
if (lastEncoderBits == 0) temp_diff++;
|
||||
else if (lastEncoderBits == 3) temp_diff--;
|
||||
break;
|
||||
case 3:
|
||||
if (lastEncoderBits == 2) temp_diff++;
|
||||
else if (lastEncoderBits == 1) temp_diff--;
|
||||
break;
|
||||
case 1:
|
||||
if (lastEncoderBits == 3) temp_diff++;
|
||||
else if (lastEncoderBits == 0) temp_diff--;
|
||||
break;
|
||||
}
|
||||
lastEncoderBits = newbutton;
|
||||
}
|
||||
|
||||
if (ABS(temp_diff) >= ENCODER_PULSES_PER_STEP) {
|
||||
if (temp_diff > 0) temp_diffState = TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CCW, ENCODER_DIFF_CW);
|
||||
else temp_diffState = TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CW, ENCODER_DIFF_CCW);
|
||||
temp_diff += ui.get_encoder_delta();
|
||||
|
||||
const int8_t abs_diff = ABS(temp_diff);
|
||||
if (abs_diff >= ENCODER_PULSES_PER_STEP) {
|
||||
temp_diffState = temp_diff > 0
|
||||
? TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CCW, ENCODER_DIFF_CW)
|
||||
: TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CW, ENCODER_DIFF_CCW);
|
||||
|
||||
int32_t encoder_multiplier = 1;
|
||||
|
||||
#if ENABLED(ENCODER_RATE_MULTIPLIER)
|
||||
|
||||
millis_t ms = millis();
|
||||
int32_t encoder_multiplier = 1;
|
||||
const millis_t ms = millis();
|
||||
|
||||
// if must encoder rati multiplier
|
||||
// Encoder rate multiplier
|
||||
if (encoderRate.enabled) {
|
||||
const float abs_diff = ABS(temp_diff),
|
||||
encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP);
|
||||
if (encoderRate.lastEncoderTime) {
|
||||
// Note that the rate is always calculated between two passes through the
|
||||
// loop and that the abs of the temp_diff value is tracked.
|
||||
const float encoderStepRate = encoderMovementSteps / float(ms - encoderRate.lastEncoderTime) * 1000;
|
||||
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 100;
|
||||
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 10;
|
||||
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 5;
|
||||
}
|
||||
// Note that the rate is always calculated between two passes through the
|
||||
// loop and that the abs of the temp_diff value is tracked.
|
||||
const float encoderStepRate = ((float(abs_diff) / float(ENCODER_PULSES_PER_STEP)) * 1000.0f) / float(ms - encoderRate.lastEncoderTime);
|
||||
encoderRate.lastEncoderTime = ms;
|
||||
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 100;
|
||||
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 10;
|
||||
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 5;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
constexpr int32_t encoder_multiplier = 1;
|
||||
|
||||
#endif
|
||||
|
||||
// encoderRate.encoderMoveValue += (temp_diff * encoder_multiplier) / (ENCODER_PULSES_PER_STEP);
|
||||
encoderRate.encoderMoveValue = (temp_diff * encoder_multiplier) / (ENCODER_PULSES_PER_STEP);
|
||||
if (encoderRate.encoderMoveValue < 0) encoderRate.encoderMoveValue = -encoderRate.encoderMoveValue;
|
||||
encoderRate.encoderMoveValue = abs_diff * encoder_multiplier / (ENCODER_PULSES_PER_STEP);
|
||||
|
||||
temp_diff = 0;
|
||||
}
|
||||
|
||||
if (temp_diffState != ENCODER_DIFF_NO) {
|
||||
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
|
||||
if (!ui.backlight) ui.refresh_brightness();
|
||||
}
|
||||
|
||||
return temp_diffState;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,6 @@ typedef enum {
|
||||
|
||||
#define ENCODER_WAIT_MS TERN(DWIN_LCD_PROUI, 10, 20)
|
||||
|
||||
// Encoder initialization
|
||||
void encoderConfiguration();
|
||||
|
||||
// Analyze encoder value and return state
|
||||
EncoderState encoderReceiveAnalyze();
|
||||
|
||||
|
||||
@@ -4078,7 +4078,6 @@ void hmiInit() {
|
||||
}
|
||||
|
||||
void dwinInitScreen() {
|
||||
encoderConfiguration();
|
||||
hmiInit();
|
||||
hmiSetLanguageCache();
|
||||
hmiStartFrame(true);
|
||||
|
||||
@@ -5143,7 +5143,6 @@ void MarlinUI::init_lcd() {
|
||||
if (dwinHandshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error.");
|
||||
dwinFrameSetDir(1); // Orientation 90°
|
||||
dwinUpdateLCD(); // Show bootscreen (first image)
|
||||
encoderConfiguration();
|
||||
for (uint16_t t = 0; t <= 100; t += 2) {
|
||||
dwinIconShow(ICON, ICON_Bar, 15, 260);
|
||||
dwinDrawRectangle(1, COLOR_BG_BLACK, 15 + t * 242 / 100, 260, 257, 280);
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
|
||||
/**
|
||||
* Bed Level Tools for Pro UI
|
||||
* Extended by: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Version: 3.2.0
|
||||
* Date: 2023/05/03
|
||||
*
|
||||
* Based on the original work of: Henri-J-Norden
|
||||
* https://github.com/Jyers/Marlin/pull/126
|
||||
|
||||
@@ -22,9 +22,6 @@
|
||||
|
||||
/**
|
||||
* Bed Level Tools for Pro UI
|
||||
* Extended by: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Version: 3.2.0
|
||||
* Date: 2023/05/03
|
||||
*
|
||||
* Based on the original work of: Henri-J-Norden
|
||||
* https://github.com/Jyers/Marlin/pull/126
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.25.3
|
||||
* Date: 2023/05/18
|
||||
*/
|
||||
@@ -37,6 +38,7 @@
|
||||
|
||||
#include "../../utf8.h"
|
||||
#include "../../marlinui.h"
|
||||
#include "../../extui/ui_api.h"
|
||||
#include "../../../MarlinCore.h"
|
||||
#include "../../../core/serial.h"
|
||||
#include "../../../core/macros.h"
|
||||
@@ -1311,7 +1313,7 @@ void eachMomentUpdate() {
|
||||
TERN_(PIDTEMP, if (hmiValue.tempControl == PIDTEMP_START) { plot.update(thermalManager.wholeDegHotend(0)); })
|
||||
TERN_(PIDTEMPBED, if (hmiValue.tempControl == PIDTEMPBED_START) { plot.update(thermalManager.wholeDegBed()); })
|
||||
TERN_(PIDTEMPCHAMBER, if (hmiValue.tempControl == PIDTEMPCHAMBER_START) { plot.update(thermalManager.wholeDegChamber()); })
|
||||
TERN_(MPCTEMP, if (hmiValue.tempControl == MPCTEMP_START) { plot.update(thermalManager.wholeDegHotend(0)); })
|
||||
TERN_(MPCTEMP, if (hmiValue.tempControl == MPC_STARTED) { plot.update(thermalManager.wholeDegHotend(0)); })
|
||||
if (hmiFlag.abort_flag || hmiFlag.pause_flag || print_job_timer.isPaused()) {
|
||||
hmiReturnScreen();
|
||||
}
|
||||
@@ -1566,7 +1568,7 @@ void dwinLevelingDone() {
|
||||
switch (hmiValue.tempControl) {
|
||||
default: return;
|
||||
#if ENABLED(MPC_AUTOTUNE)
|
||||
case MPCTEMP_START:
|
||||
case MPC_STARTED:
|
||||
DWINUI::drawCenteredString(hmiData.colorPopupTxt, 70, GET_TEXT_F(MSG_MPC_AUTOTUNE));
|
||||
DWINUI::drawString(hmiData.colorPopupTxt, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("MPC target: Celsius"));
|
||||
DWINUI::drawCenteredString(hmiData.colorPopupTxt, 92, GET_TEXT_F(MSG_PID_FOR_NOZZLE));
|
||||
@@ -1619,7 +1621,7 @@ void dwinLevelingDone() {
|
||||
|
||||
switch (result) {
|
||||
#if ENABLED(MPCTEMP)
|
||||
case MPCTEMP_START:
|
||||
case MPC_STARTED:
|
||||
#elif ENABLED(PIDTEMP)
|
||||
case PIDTEMP_START:
|
||||
#endif
|
||||
@@ -1655,7 +1657,7 @@ void dwinLevelingDone() {
|
||||
|
||||
void drawHPlot() {
|
||||
TERN_(PIDTEMP, dwinDrawPlot(PIDTEMP_START));
|
||||
TERN_(MPCTEMP, dwinDrawPlot(MPCTEMP_START));
|
||||
TERN_(MPCTEMP, dwinDrawPlot(MPC_STARTED));
|
||||
}
|
||||
void drawBPlot() {
|
||||
TERN_(PIDTEMPBED, dwinDrawPlot(PIDTEMPBED_START));
|
||||
@@ -1741,7 +1743,7 @@ void dwinLevelingDone() {
|
||||
void dwinMPCTuning(tempcontrol_t result) {
|
||||
hmiValue.tempControl = result;
|
||||
switch (result) {
|
||||
case MPCTEMP_START:
|
||||
case MPC_STARTED:
|
||||
hmiSaveProcessID(ID_MPCProcess);
|
||||
#if PROUI_TUNING_GRAPH
|
||||
dwinDrawPIDMPCPopup();
|
||||
@@ -1909,7 +1911,6 @@ void MarlinUI::init_lcd() {
|
||||
const bool hs = dwinHandshake(); UNUSED(hs);
|
||||
dwinFrameSetDir(1);
|
||||
dwinJPGCacheTo1(Language_English);
|
||||
encoderConfiguration();
|
||||
}
|
||||
|
||||
void dwinInitScreen() {
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.25.3
|
||||
* Date: 2023/05/18
|
||||
*/
|
||||
@@ -90,7 +91,7 @@ enum processID : uint8_t {
|
||||
PID_TUNING_TIMEOUT,
|
||||
#endif
|
||||
#if ENABLED(MPC_AUTOTUNE)
|
||||
MPCTEMP_START,
|
||||
MPC_STARTED,
|
||||
MPC_TEMP_ERROR,
|
||||
MPC_INTERRUPTED,
|
||||
#endif
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* DWIN general defines and data structs for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.12.2
|
||||
* Date: 2022/08/08
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.12.1
|
||||
* Date: 2023/01/22
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.12.1
|
||||
* Date: 2023/01/22
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.11.1
|
||||
* Date: 2022/02/28
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.11.1
|
||||
* Date: 2022/02/28
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.21.1
|
||||
* Date: 2023/03/21
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Enhanced implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 3.21.1
|
||||
* Date: 2023/03/21
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* DWIN Endstops diagnostic page for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 1.4.3
|
||||
* Date: 2023/05/10
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* DWIN End Stops diagnostic page for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 1.4.3
|
||||
* Date: 2023/05/10
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* Lock screen implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 2.3.2
|
||||
* Date: 2022/11/20
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* Lock screen implementation for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 2.3.2
|
||||
* Date: 2022/11/20
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* Mesh Viewer for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* version: 4.2.1
|
||||
* Date: 2023/05/05
|
||||
*/
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* Mesh Viewer for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* version: 4.2.1
|
||||
* Date: 2023/05/05
|
||||
*/
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
|
||||
/**
|
||||
* Print Stats page for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 1.4.0
|
||||
* Date: 2022/12/03
|
||||
*/
|
||||
@@ -55,9 +56,9 @@ void PrintStats::draw() {
|
||||
DWINUI::drawString(MRG, 80, TS(GET_TEXT_F(MSG_INFO_PRINT_COUNT), F(": "), ps.totalPrints));
|
||||
DWINUI::drawString(MRG, 100, TS(GET_TEXT_F(MSG_INFO_COMPLETED_PRINTS), F(": "), ps.finishedPrints));
|
||||
duration_t(print_job_timer.getStats().printTime).toDigital(str, true);
|
||||
DWINUI::drawString(MRG, 120, MString<50>(GET_TEXT_F(MSG_INFO_PRINT_TIME), F(": "), str));
|
||||
DWINUI::drawString(MRG, 120, TS(GET_TEXT_F(MSG_INFO_PRINT_TIME), F(": "), str));
|
||||
duration_t(print_job_timer.getStats().longestPrint).toDigital(str, true);
|
||||
DWINUI::drawString(MRG, 140, MString<50>(GET_TEXT(MSG_INFO_PRINT_LONGEST), F(": "), str));
|
||||
DWINUI::drawString(MRG, 140, TS(GET_TEXT_F(MSG_INFO_PRINT_LONGEST), F(": "), str));
|
||||
DWINUI::drawString(MRG, 160, TS(GET_TEXT_F(MSG_INFO_PRINT_FILAMENT), F(": "), p_float_t(ps.filamentUsed / 1000, 2), F(" m")));
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
|
||||
/**
|
||||
* Print Stats page for PRO UI
|
||||
* Author: Miguel A. Risco-Castillo (MRISCOC)
|
||||
* Based on the original work of: Miguel Risco-Castillo (MRISCOC)
|
||||
* https://github.com/mriscoc/Ender3V2S1
|
||||
* Version: 1.4.0
|
||||
* Date: 2022/12/03
|
||||
*/
|
||||
|
||||
@@ -222,7 +222,7 @@ namespace ExtUI {
|
||||
void onMPCTuning(const mpcresult_t rst) {
|
||||
// Called for temperature MPC tuning result
|
||||
switch (rst) {
|
||||
case MPC_STARTED: dwinMPCTuning(MPCTEMP_START); break;
|
||||
case MPC_STARTED: dwinMPCTuning(MPC_STARTED); break;
|
||||
case MPC_TEMP_ERROR: dwinMPCTuning(MPC_TEMP_ERROR); break;
|
||||
case MPC_INTERRUPTED: dwinMPCTuning(MPC_INTERRUPTED); break;
|
||||
case MPC_DONE: dwinMPCTuning(AUTOTUNE_DONE); break;
|
||||
|
||||
@@ -780,11 +780,11 @@ void ChironTFT::panelProcess(uint8_t req) {
|
||||
DEBUG_ECHOLNPGM("Moving to mesh point at x: ", pos.x, " y: ", pos.y, " z: ", pos_z);
|
||||
#endif
|
||||
// Go up before moving
|
||||
setAxisPosition_mm(3.0,Z);
|
||||
setAxisPosition_mm(3.0f, Z);
|
||||
|
||||
setAxisPosition_mm(17 + (93 * pos.x), X);
|
||||
setAxisPosition_mm(20 + (93 * pos.y), Y);
|
||||
setAxisPosition_mm(0.0, Z);
|
||||
setAxisPosition_mm(17.0f + (93.0f * pos.x), X);
|
||||
setAxisPosition_mm(20.0f + (93.0f * pos.y), Y);
|
||||
setAxisPosition_mm(0.0f, Z);
|
||||
#if ACDEBUG(AC_INFO)
|
||||
DEBUG_ECHOLNPGM("Current Z: ", getAxisPosition_mm(Z));
|
||||
#endif
|
||||
|
||||
@@ -401,15 +401,14 @@ static void _gotoTrammingPoint(unsigned char point) {
|
||||
switch (point) {
|
||||
default: return;
|
||||
case 1: x = X_CENTER; y = Y_CENTER; break;
|
||||
case 2: x = X_MIN_POS + lfrb[0]; y = Y_MIN_POS + lfrb[1]; break;
|
||||
case 3: x = X_MAX_POS - lfrb[2]; y = Y_MIN_POS + lfrb[1]; break;
|
||||
case 4: x = X_MAX_POS - lfrb[2]; y = Y_MAX_POS - lfrb[3]; break;
|
||||
case 5: x = X_MIN_POS + lfrb[0]; y = Y_MAX_POS - lfrb[3]; break;
|
||||
case 2: x = X_MIN_BED + lfrb[0]; y = Y_MIN_BED + lfrb[1]; break;
|
||||
case 3: x = X_MAX_BED - lfrb[2]; y = Y_MIN_BED + lfrb[1]; break;
|
||||
case 4: x = X_MAX_BED - lfrb[2]; y = Y_MAX_BED - lfrb[3]; break;
|
||||
case 5: x = X_MIN_BED + lfrb[0]; y = Y_MAX_BED - lfrb[3]; break;
|
||||
}
|
||||
|
||||
if (ExtUI::getAxisPosition_mm(ExtUI::Z) < (Z_MIN_POS) + (BED_TRAMMING_Z_HOP))
|
||||
ExtUI::setAxisPosition_mm((Z_MIN_POS) + (BED_TRAMMING_Z_HOP), ExtUI::Z);
|
||||
|
||||
if (BED_TRAMMING_Z_HOP)
|
||||
ExtUI::setAxisPosition_mm(ExtUI::getAxisPosition_mm(ExtUI::Z) + (BED_TRAMMING_Z_HOP), ExtUI::Z);
|
||||
ExtUI::setAxisPosition_mm(x, ExtUI::X);
|
||||
ExtUI::setAxisPosition_mm(y, ExtUI::Y);
|
||||
ExtUI::setAxisPosition_mm((Z_MIN_POS) + (BED_TRAMMING_HEIGHT), ExtUI::Z);
|
||||
|
||||
@@ -45,13 +45,3 @@
|
||||
#ifndef DGUS_STATUS_EXPIRATION_MS
|
||||
#define DGUS_STATUS_EXPIRATION_MS 30000
|
||||
#endif
|
||||
|
||||
#ifndef BED_TRAMMING_Z_HOP
|
||||
#define BED_TRAMMING_Z_HOP 4.0
|
||||
#endif
|
||||
|
||||
#ifndef BED_TRAMMING_HEIGHT
|
||||
#define BED_TRAMMING_HEIGHT 0.0
|
||||
#endif
|
||||
|
||||
static_assert(BED_TRAMMING_Z_HOP >= 0, "BED_TRAMMING_Z_HOP must be >= 0. Please update your configuration.");
|
||||
|
||||
@@ -474,29 +474,28 @@ void DGUSRxHandler::moveToPoint(DGUS_VP &vp, void *data_ptr) {
|
||||
y = DGUS_LEVEL_CENTER_Y;
|
||||
break;
|
||||
case 2:
|
||||
x = X_MIN_POS + lfrb[0];
|
||||
y = Y_MIN_POS + lfrb[1];
|
||||
x = X_MIN_BED + lfrb[0];
|
||||
y = Y_MIN_BED + lfrb[1];
|
||||
break;
|
||||
case 3:
|
||||
x = X_MAX_POS - lfrb[2];
|
||||
y = Y_MIN_POS + lfrb[1];
|
||||
x = X_MAX_BED - lfrb[2];
|
||||
y = Y_MIN_BED + lfrb[1];
|
||||
break;
|
||||
case 4:
|
||||
x = X_MAX_POS - lfrb[2];
|
||||
y = Y_MAX_POS - lfrb[3];
|
||||
x = X_MAX_BED - lfrb[2];
|
||||
y = Y_MAX_BED - lfrb[3];
|
||||
break;
|
||||
case 5:
|
||||
x = X_MIN_POS + lfrb[0];
|
||||
y = Y_MAX_POS - lfrb[3];
|
||||
x = X_MIN_BED + lfrb[0];
|
||||
y = Y_MAX_BED - lfrb[3];
|
||||
break;
|
||||
}
|
||||
|
||||
if (ExtUI::getAxisPosition_mm(ExtUI::Z) < Z_MIN_POS + BED_TRAMMING_Z_HOP) {
|
||||
ExtUI::setAxisPosition_mm(Z_MIN_POS + BED_TRAMMING_Z_HOP, ExtUI::Z);
|
||||
}
|
||||
if (BED_TRAMMING_Z_HOP)
|
||||
ExtUI::setAxisPosition_mm(ExtUI::getAxisPosition_mm(ExtUI::Z) + (BED_TRAMMING_Z_HOP), ExtUI::Z);
|
||||
ExtUI::setAxisPosition_mm(x, ExtUI::X);
|
||||
ExtUI::setAxisPosition_mm(y, ExtUI::Y);
|
||||
ExtUI::setAxisPosition_mm(Z_MIN_POS + BED_TRAMMING_HEIGHT, ExtUI::Z);
|
||||
ExtUI::setAxisPosition_mm((Z_MIN_POS) + (BED_TRAMMING_HEIGHT), ExtUI::Z);
|
||||
}
|
||||
|
||||
void DGUSRxHandler::probe(DGUS_VP &vp, void *data_ptr) {
|
||||
|
||||
@@ -73,16 +73,6 @@
|
||||
#define DGUS_DEFAULT_FILAMENT_LEN 10
|
||||
#endif
|
||||
|
||||
#ifndef BED_TRAMMING_Z_HOP
|
||||
#define BED_TRAMMING_Z_HOP 4.0
|
||||
#endif
|
||||
|
||||
#ifndef BED_TRAMMING_HEIGHT
|
||||
#define BED_TRAMMING_HEIGHT 0.0
|
||||
#endif
|
||||
|
||||
static_assert(BED_TRAMMING_Z_HOP >= 0, "BED_TRAMMING_Z_HOP must be >= 0. Please update your configuration.");
|
||||
|
||||
#ifndef DGUS_LEVEL_CENTER_X
|
||||
#define DGUS_LEVEL_CENTER_X ((X_BED_SIZE) / 2)
|
||||
#endif
|
||||
|
||||
@@ -793,7 +793,7 @@ void RTS::handleData() {
|
||||
tmp_zprobe_offset = (float(recdat.data[0]) - 65536) / 100;
|
||||
else
|
||||
tmp_zprobe_offset = float(recdat.data[0]) / 100;
|
||||
if (WITHIN((tmp_zprobe_offset), PROBE_OFFSET_ZMIN, PROBE_OFFSET_ZMAX)) {
|
||||
if (WITHIN(tmp_zprobe_offset, PROBE_OFFSET_ZMIN, PROBE_OFFSET_ZMAX)) {
|
||||
int16_t tmpSteps = mmToWholeSteps(getZOffset_mm() - tmp_zprobe_offset, axis_t(Z));
|
||||
if (tmpSteps == 0) tmpSteps = getZOffset_mm() < tmp_zprobe_offset ? 1 : -1;
|
||||
smartAdjustAxis_steps(-tmpSteps, axis_t(Z), false);
|
||||
@@ -1162,35 +1162,35 @@ void RTS::handleData() {
|
||||
|
||||
#if ENABLED(LCD_BED_TRAMMING)
|
||||
case 6: // Bed Tramming, Centre 1
|
||||
setAxisPosition_mm(BED_TRAMMING_Z_HOP, axis_t(Z));
|
||||
if (BED_TRAMMING_Z_HOP) setAxisPosition_mm(current_position.z + (BED_TRAMMING_Z_HOP), axis_t(Z));
|
||||
setAxisPosition_mm(X_CENTER, axis_t(X));
|
||||
setAxisPosition_mm(Y_CENTER, axis_t(Y));
|
||||
waitway = 6;
|
||||
break;
|
||||
|
||||
case 7: // Bed Tramming, Front Left 2
|
||||
setAxisPosition_mm(BED_TRAMMING_Z_HOP, axis_t(Z));
|
||||
if (BED_TRAMMING_Z_HOP) setAxisPosition_mm(current_position.z + (BED_TRAMMING_Z_HOP), axis_t(Z));
|
||||
setAxisPosition_mm(X_MIN_BED + lfrb[0], axis_t(X));
|
||||
setAxisPosition_mm(Y_MIN_BED + lfrb[1], axis_t(Y));
|
||||
waitway = 6;
|
||||
break;
|
||||
|
||||
case 8: // Bed Tramming, Front Right 3
|
||||
setAxisPosition_mm(BED_TRAMMING_Z_HOP, axis_t(Z));
|
||||
if (BED_TRAMMING_Z_HOP) setAxisPosition_mm(current_position.z + (BED_TRAMMING_Z_HOP), axis_t(Z));
|
||||
setAxisPosition_mm(X_MAX_BED - lfrb[2], axis_t(X));
|
||||
setAxisPosition_mm(Y_MIN_BED + lfrb[1], axis_t(Y));
|
||||
waitway = 6;
|
||||
break;
|
||||
|
||||
case 9: // Bed Tramming, Back Right 4
|
||||
setAxisPosition_mm(BED_TRAMMING_Z_HOP, axis_t(Z));
|
||||
if (BED_TRAMMING_Z_HOP) setAxisPosition_mm(current_position.z + (BED_TRAMMING_Z_HOP), axis_t(Z));
|
||||
setAxisPosition_mm(X_MAX_BED - lfrb[2], axis_t(X));
|
||||
setAxisPosition_mm(Y_MAX_BED - lfrb[3], axis_t(Y));
|
||||
waitway = 6;
|
||||
break;
|
||||
|
||||
case 10: // Bed Tramming, Back Left 5
|
||||
setAxisPosition_mm(BED_TRAMMING_Z_HOP, axis_t(Z));
|
||||
if (BED_TRAMMING_Z_HOP) setAxisPosition_mm(current_position.z + (BED_TRAMMING_Z_HOP), axis_t(Z));
|
||||
setAxisPosition_mm(X_MIN_BED + lfrb[0], axis_t(X));
|
||||
setAxisPosition_mm(Y_MAX_BED - lfrb[3], axis_t(Y));
|
||||
waitway = 6;
|
||||
|
||||
@@ -216,7 +216,6 @@ void tft_lvgl_init() {
|
||||
|
||||
tft_style_init();
|
||||
filament_pin_setup();
|
||||
lv_encoder_pin_init();
|
||||
|
||||
#if ENABLED(MKS_WIFI_MODULE)
|
||||
mks_esp_wifi_init();
|
||||
@@ -331,12 +330,12 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
|
||||
}
|
||||
|
||||
int16_t enc_diff = 0;
|
||||
lv_indev_state_t state = LV_INDEV_STATE_REL;
|
||||
lv_indev_state_t indev_enc_state = LV_INDEV_STATE_REL; // ENC button is pressed or released
|
||||
|
||||
bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {
|
||||
(void) indev_drv; // Unused
|
||||
UNUSED(indev_drv);
|
||||
|
||||
data->state = state;
|
||||
data->state = indev_enc_state;
|
||||
data->enc_diff = enc_diff;
|
||||
enc_diff = 0;
|
||||
|
||||
@@ -446,102 +445,50 @@ lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) {
|
||||
return LV_FS_RES_OK;
|
||||
}
|
||||
|
||||
void lv_encoder_pin_init() {
|
||||
#if BUTTON_EXISTS(EN1)
|
||||
SET_INPUT_PULLUP(BTN_EN1);
|
||||
void lv_update_encoder() {
|
||||
|
||||
#if ANY_BUTTON(EN1, EN2)
|
||||
constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; // We can fill in
|
||||
static uint8_t pulse_count;
|
||||
pulse_count += ui.get_encoder_delta();
|
||||
const int8_t fullSteps = pulse_count / epps;
|
||||
pulse_count -= fullSteps * epps;
|
||||
enc_diff += fullSteps;
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN2)
|
||||
SET_INPUT_PULLUP(BTN_EN2);
|
||||
|
||||
#if ANY_BUTTON(ENC, BACK, UP, DOWN, LEFT, RIGHT)
|
||||
static millis_t last_encoder_ms;
|
||||
const millis_t now = millis(), diffTime = getTickDiff(now, last_encoder_ms);
|
||||
if (diffTime <= 50) return;
|
||||
#endif
|
||||
|
||||
#if BUTTON_EXISTS(ENC)
|
||||
SET_INPUT_PULLUP(BTN_ENC);
|
||||
static uint8_t old_button_enc = LV_INDEV_STATE_REL;
|
||||
const uint8_t enc_c = BUTTON_PRESSED(ENC) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
if (enc_c != old_button_enc) {
|
||||
indev_enc_state = enc_c ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
old_button_enc = enc_c;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if BUTTON_EXISTS(BACK)
|
||||
SET_INPUT_PULLUP(BTN_BACK);
|
||||
if (BUTTON_PRESSED(BACK)) {}
|
||||
#endif
|
||||
|
||||
#if BUTTON_EXISTS(UP)
|
||||
SET_INPUT(BTN_UP);
|
||||
if (BUTTON_PRESSED(UP)) {}
|
||||
#endif
|
||||
#if BUTTON_EXISTS(DOWN)
|
||||
SET_INPUT(BTN_DOWN);
|
||||
if (BUTTON_PRESSED(DOWN)) {}
|
||||
#endif
|
||||
#if BUTTON_EXISTS(LEFT)
|
||||
SET_INPUT(BTN_LEFT);
|
||||
if (BUTTON_PRESSED(LEFT)) {}
|
||||
#endif
|
||||
#if BUTTON_EXISTS(RIGHT)
|
||||
SET_INPUT(BTN_RIGHT);
|
||||
if (BUTTON_PRESSED(RIGHT)) {}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if 1 // HAS_ENCODER_ACTION
|
||||
|
||||
void lv_update_encoder() {
|
||||
static uint32_t encoder_time1;
|
||||
uint32_t tmpTime, diffTime = 0;
|
||||
tmpTime = millis();
|
||||
diffTime = getTickDiff(tmpTime, encoder_time1);
|
||||
if (diffTime > 50) {
|
||||
|
||||
#if HAS_ENCODER_WHEEL
|
||||
|
||||
#if ANY_BUTTON(EN1, EN2, ENC, BACK)
|
||||
|
||||
uint8_t newbutton = 0;
|
||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
||||
if (BUTTON_PRESSED(ENC)) newbutton |= EN_C;
|
||||
if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
|
||||
|
||||
#else
|
||||
|
||||
constexpr uint8_t newbutton = 0;
|
||||
|
||||
#endif
|
||||
|
||||
static uint8_t buttons = 0;
|
||||
buttons = newbutton;
|
||||
static uint8_t lastEncoderBits;
|
||||
|
||||
#define encrot0 0
|
||||
#define encrot1 1
|
||||
#define encrot2 2
|
||||
|
||||
uint8_t enc = 0;
|
||||
if (buttons & EN_A) enc |= B01;
|
||||
if (buttons & EN_B) enc |= B10;
|
||||
if (enc != lastEncoderBits) {
|
||||
switch (enc) {
|
||||
case encrot1:
|
||||
if (lastEncoderBits == encrot0) {
|
||||
enc_diff--;
|
||||
encoder_time1 = tmpTime;
|
||||
}
|
||||
break;
|
||||
case encrot2:
|
||||
if (lastEncoderBits == encrot0) {
|
||||
enc_diff++;
|
||||
encoder_time1 = tmpTime;
|
||||
}
|
||||
break;
|
||||
}
|
||||
lastEncoderBits = enc;
|
||||
}
|
||||
static uint8_t last_button_state = LV_INDEV_STATE_REL;
|
||||
const uint8_t enc_c = (buttons & EN_C) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
if (enc_c != last_button_state) {
|
||||
state = enc_c ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||
last_button_state = enc_c;
|
||||
}
|
||||
|
||||
#endif // HAS_ENCODER_WHEEL
|
||||
|
||||
} // encoder_time1
|
||||
}
|
||||
|
||||
#endif // HAS_ENCODER_ACTION
|
||||
|
||||
#ifdef __PLAT_NATIVE_SIM__
|
||||
#include <lv_misc/lv_log.h>
|
||||
typedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char *, uint32_t, const char *);
|
||||
|
||||
@@ -41,7 +41,6 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data);
|
||||
bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||
|
||||
void lcdClear(uint16_t color);
|
||||
void lv_encoder_pin_init();
|
||||
void lv_update_encoder();
|
||||
|
||||
lv_fs_res_t spi_flash_open_cb(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
|
||||
|
||||
@@ -61,7 +61,7 @@ namespace ExtUI {
|
||||
UNUSED(icon); UNUSED(fBtn);
|
||||
}
|
||||
void onUserConfirmRequired(const int icon, FSTR_P const fstr, FSTR_P const fBtn) {
|
||||
onUserConfirmRequired(cstr);
|
||||
onUserConfirmRequired(fstr);
|
||||
UNUSED(icon); UNUSED(fBtn);
|
||||
}
|
||||
|
||||
|
||||
+210
-196
@@ -227,34 +227,32 @@ void MarlinUI::init() {
|
||||
|
||||
init_lcd();
|
||||
|
||||
#if HAS_DIGITAL_BUTTONS
|
||||
#if BUTTON_EXISTS(EN1)
|
||||
SET_INPUT_PULLUP(BTN_EN1);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN2)
|
||||
SET_INPUT_PULLUP(BTN_EN2);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC)
|
||||
SET_INPUT_PULLUP(BTN_ENC);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC_EN)
|
||||
SET_INPUT_PULLUP(BTN_ENC_EN);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(BACK)
|
||||
SET_INPUT_PULLUP(BTN_BACK);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(UP)
|
||||
SET_INPUT(BTN_UP);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(DOWN)
|
||||
SET_INPUT(BTN_DOWN);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(LFT)
|
||||
SET_INPUT(BTN_LEFT);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(RT)
|
||||
SET_INPUT(BTN_RIGHT);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN1)
|
||||
SET_INPUT_PULLUP(BTN_EN1);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(EN2)
|
||||
SET_INPUT_PULLUP(BTN_EN2);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC)
|
||||
SET_INPUT_PULLUP(BTN_ENC);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(ENC_EN)
|
||||
SET_INPUT_PULLUP(BTN_ENC_EN);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(BACK)
|
||||
SET_INPUT_PULLUP(BTN_BACK);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(UP)
|
||||
SET_INPUT(BTN_UP);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(DOWN)
|
||||
SET_INPUT(BTN_DOWN);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(LFT)
|
||||
SET_INPUT(BTN_LEFT);
|
||||
#endif
|
||||
#if BUTTON_EXISTS(RT)
|
||||
SET_INPUT(BTN_RIGHT);
|
||||
#endif
|
||||
|
||||
#if HAS_SHIFT_ENCODER
|
||||
@@ -739,7 +737,7 @@ void MarlinUI::init() {
|
||||
|
||||
void MarlinUI::kill_screen(FSTR_P const lcd_error, FSTR_P const lcd_component) {
|
||||
init();
|
||||
status_printf(1, F(S_FMT ": " S_FMT), FTOP(lcd_error), FTOP(lcd_component));
|
||||
status_printf(1, F(S_FMT ": " S_FMT), lcd_error, lcd_component);
|
||||
TERN_(HAS_MARLINUI_MENU, return_to_status());
|
||||
|
||||
// RED ALERT. RED ALERT.
|
||||
@@ -1026,72 +1024,56 @@ void MarlinUI::init() {
|
||||
if (TERN0(IS_RRW_KEYPAD, handle_keypad()))
|
||||
reset_status_timeout(ms);
|
||||
|
||||
uint8_t abs_diff = ABS(encoderDiff);
|
||||
|
||||
#if ENCODER_PULSES_PER_STEP > 1
|
||||
// When reversing the encoder direction, a movement step can be missed because
|
||||
// encoderDiff has a non-zero residual value, making the controller unresponsive.
|
||||
// The fix clears the residual value when the encoder is idle.
|
||||
// Also check if past half the threshold to compensate for missed single steps.
|
||||
static int8_t lastEncoderDiff;
|
||||
|
||||
// Timeout? No decoder change since last check. 10 or 20 times per second.
|
||||
if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step?
|
||||
encoderDiff = 0; // Clear residual pulses.
|
||||
else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold?
|
||||
abs_diff = epps; // Treat as a full step size
|
||||
encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction.
|
||||
}
|
||||
if (lastEncoderDiff != encoderDiff) wake_display();
|
||||
lastEncoderDiff = encoderDiff;
|
||||
#endif
|
||||
static int8_t lastEncoderDiff;
|
||||
if (lastEncoderDiff != encoderDiff) wake_display();
|
||||
lastEncoderDiff = encoderDiff;
|
||||
|
||||
const uint8_t abs_diff = ABS(encoderDiff);
|
||||
const bool encoderPastThreshold = (abs_diff >= epps);
|
||||
if (encoderPastThreshold || lcd_clicked) {
|
||||
if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) {
|
||||
if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) {
|
||||
|
||||
#if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER)
|
||||
int32_t encoder_multiplier = 1;
|
||||
|
||||
int32_t encoder_multiplier = 1;
|
||||
#if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER)
|
||||
|
||||
if (encoder_multiplier_enabled) {
|
||||
// Note that the rate is always calculated between two passes through the
|
||||
// loop and that the abs of the encoderDiff value is tracked.
|
||||
static millis_t encoder_mult_prev_ms = 0;
|
||||
const float encoderStepRate = ((float(abs_diff) / float(epps)) * 1000.0f) / float(ms - encoder_mult_prev_ms);
|
||||
encoder_mult_prev_ms = ms;
|
||||
if (encoder_multiplier_enabled) {
|
||||
// Note that the rate is always calculated between two passes through the
|
||||
// loop and that the abs of the encoderDiff value is tracked.
|
||||
static millis_t encoder_mult_prev_ms = 0;
|
||||
const float encoderStepRate = ((float(abs_diff) / float(epps)) * 1000.0f) / float(ms - encoder_mult_prev_ms);
|
||||
encoder_mult_prev_ms = ms;
|
||||
|
||||
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 100;
|
||||
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 10;
|
||||
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 5;
|
||||
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 100;
|
||||
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 10;
|
||||
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
||||
encoder_multiplier = 5;
|
||||
|
||||
// Enable to output the encoder steps per second value
|
||||
//#define ENCODER_RATE_MULTIPLIER_DEBUG
|
||||
#if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG)
|
||||
SERIAL_ECHO_MSG(
|
||||
"Enc Step Rate: ", encoderStepRate,
|
||||
" Mult: ", encoder_multiplier,
|
||||
" 5X Steps: ", ENCODER_5X_STEPS_PER_SEC,
|
||||
" 10X Steps: ", ENCODER_10X_STEPS_PER_SEC,
|
||||
" 100X Steps: ", ENCODER_100X_STEPS_PER_SEC
|
||||
);
|
||||
#endif
|
||||
}
|
||||
// Enable to output the encoder steps per second value
|
||||
//#define ENCODER_RATE_MULTIPLIER_DEBUG
|
||||
#if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG)
|
||||
SERIAL_ECHO_MSG(
|
||||
"Enc Step Rate: ", encoderStepRate,
|
||||
" Mult: ", encoder_multiplier,
|
||||
" 5X Steps: ", ENCODER_5X_STEPS_PER_SEC,
|
||||
" 10X Steps: ", ENCODER_10X_STEPS_PER_SEC,
|
||||
" 100X Steps: ", ENCODER_100X_STEPS_PER_SEC
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
#endif // ENCODER_RATE_MULTIPLIER
|
||||
|
||||
constexpr int32_t encoder_multiplier = 1;
|
||||
|
||||
#endif // ENCODER_RATE_MULTIPLIER
|
||||
|
||||
if (can_encode()) encoderPosition += (encoderDiff * encoder_multiplier) / epps;
|
||||
|
||||
encoderDiff = 0;
|
||||
const int8_t fullSteps = encoderDiff / epps;
|
||||
if (fullSteps != 0) {
|
||||
encoderDiff -= fullSteps * epps;
|
||||
if (can_encode() && !lcd_clicked)
|
||||
encoderPosition += (fullSteps * encoder_multiplier);
|
||||
}
|
||||
}
|
||||
|
||||
if (encoderPastThreshold || lcd_clicked) {
|
||||
reset_status_timeout(ms);
|
||||
|
||||
#if HAS_BACKLIGHT_TIMEOUT
|
||||
@@ -1312,124 +1294,156 @@ void MarlinUI::init() {
|
||||
*/
|
||||
void MarlinUI::update_buttons() {
|
||||
const millis_t now = millis();
|
||||
if (ELAPSED(now, next_button_update_ms)) {
|
||||
|
||||
#if HAS_DIGITAL_BUTTONS
|
||||
#if HAS_MARLINUI_ENCODER
|
||||
|
||||
#if ANY_BUTTON(EN1, EN2, ENC, BACK)
|
||||
|
||||
uint8_t newbutton = 0;
|
||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
||||
if (can_encode() && BUTTON_PRESSED(ENC)) newbutton |= EN_C;
|
||||
if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
|
||||
|
||||
#else
|
||||
|
||||
constexpr uint8_t newbutton = 0;
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// Directional buttons
|
||||
//
|
||||
#if ANY_BUTTON(UP, DOWN, LEFT, RIGHT)
|
||||
|
||||
const int8_t pulses = epps * encoderDirection;
|
||||
|
||||
if (BUTTON_PRESSED(UP)) {
|
||||
encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
else if (BUTTON_PRESSED(DOWN)) {
|
||||
encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
else if (BUTTON_PRESSED(LEFT)) {
|
||||
encoderDiff = -pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
else if (BUTTON_PRESSED(RIGHT)) {
|
||||
encoderDiff = pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
|
||||
#endif // UP || DOWN || LEFT || RIGHT
|
||||
|
||||
buttons = (newbutton | TERN0(HAS_SLOW_BUTTONS, slow_buttons)
|
||||
#if ALL(HAS_TOUCH_BUTTONS, HAS_ENCODER_ACTION)
|
||||
| (touch_buttons & TERN(HAS_ENCODER_WHEEL, ~(EN_A | EN_B), 0xFF))
|
||||
#endif
|
||||
);
|
||||
|
||||
#elif HAS_ADC_BUTTONS
|
||||
|
||||
buttons = 0;
|
||||
|
||||
#endif
|
||||
|
||||
#if HAS_ADC_BUTTONS
|
||||
if (keypad_buttons == 0) {
|
||||
const uint8_t b = get_ADC_keyValue();
|
||||
if (WITHIN(b, 1, 8)) keypad_buttons = _BV(b - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_SHIFT_ENCODER
|
||||
/**
|
||||
* Set up Rotary Encoder bit values (for two pin encoders to indicate movement).
|
||||
* These values are independent of which pins are used for EN_A / EN_B indications.
|
||||
* The rotary encoder part is also independent of the LCD chipset.
|
||||
*/
|
||||
uint8_t val = 0;
|
||||
WRITE(SHIFT_LD_PIN, LOW);
|
||||
WRITE(SHIFT_LD_PIN, HIGH);
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
val >>= 1;
|
||||
if (READ(SHIFT_OUT_PIN)) SBI(val, 7);
|
||||
WRITE(SHIFT_CLK_PIN, HIGH);
|
||||
WRITE(SHIFT_CLK_PIN, LOW);
|
||||
}
|
||||
TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val;
|
||||
#endif
|
||||
|
||||
#if IS_TFTGLCD_PANEL
|
||||
next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2);
|
||||
buttons = slow_buttons;
|
||||
TERN_(AUTO_BED_LEVELING_UBL, external_encoder());
|
||||
#endif
|
||||
|
||||
} // next_button_update_ms
|
||||
|
||||
#if HAS_ENCODER_WHEEL
|
||||
static uint8_t lastEncoderBits;
|
||||
|
||||
// Manage encoder rotation
|
||||
#define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; }
|
||||
|
||||
uint8_t enc = 0;
|
||||
if (buttons & EN_A) enc |= B01;
|
||||
if (buttons & EN_B) enc |= B10;
|
||||
if (enc != lastEncoderBits) {
|
||||
switch (enc) {
|
||||
case 0: ENCODER_SPIN(1, 2); break;
|
||||
case 2: ENCODER_SPIN(0, 3); break;
|
||||
case 3: ENCODER_SPIN(2, 1); break;
|
||||
case 1: ENCODER_SPIN(3, 0); break;
|
||||
}
|
||||
const int8_t delta = get_encoder_delta(now);
|
||||
if (delta) {
|
||||
encoderDiff += delta * encoderDirection;
|
||||
#if ALL(HAS_MARLINUI_MENU, AUTO_BED_LEVELING_UBL)
|
||||
external_encoder();
|
||||
#endif
|
||||
lastEncoderBits = enc;
|
||||
}
|
||||
|
||||
#endif // HAS_ENCODER_WHEEL
|
||||
}
|
||||
#endif
|
||||
|
||||
if (PENDING(now, next_button_update_ms)) return;
|
||||
|
||||
#if HAS_DIGITAL_BUTTONS
|
||||
|
||||
uint8_t newbuttons = 0;
|
||||
#if ANY_BUTTON(ENC, BACK)
|
||||
if (can_encode() && BUTTON_PRESSED(ENC)) newbuttons |= EN_C;
|
||||
if (BUTTON_PRESSED(BACK)) newbuttons |= EN_D;
|
||||
#endif
|
||||
|
||||
//
|
||||
// Directional buttons
|
||||
//
|
||||
#if ANY_BUTTON(UP, DOWN, LEFT, RIGHT)
|
||||
|
||||
const int8_t pulses = epps * encoderDirection;
|
||||
|
||||
if (BUTTON_PRESSED(UP)) {
|
||||
encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
else if (BUTTON_PRESSED(DOWN)) {
|
||||
encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
else if (BUTTON_PRESSED(LEFT)) {
|
||||
encoderDiff = -pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
else if (BUTTON_PRESSED(RIGHT)) {
|
||||
encoderDiff = pulses;
|
||||
next_button_update_ms = now + 300;
|
||||
}
|
||||
|
||||
#endif // UP || DOWN || LEFT || RIGHT
|
||||
|
||||
buttons = (newbuttons | TERN0(HAS_SLOW_BUTTONS, slow_buttons)
|
||||
#if ALL(HAS_TOUCH_BUTTONS, HAS_ENCODER_ACTION)
|
||||
| (touch_buttons & TERN(HAS_MARLINUI_ENCODER, ~(EN_A | EN_B), 0xFF))
|
||||
#endif
|
||||
);
|
||||
|
||||
#elif HAS_ADC_BUTTONS
|
||||
|
||||
buttons = 0;
|
||||
|
||||
#endif
|
||||
|
||||
#if HAS_ADC_BUTTONS
|
||||
if (keypad_buttons == 0) {
|
||||
const uint8_t b = get_ADC_keyValue();
|
||||
if (WITHIN(b, 1, 8)) keypad_buttons = _BV(b - 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_SHIFT_ENCODER
|
||||
/**
|
||||
* Set up Rotary Encoder bit values (for two pin encoders to indicate movement).
|
||||
* These values are independent of which pins are used for EN_A / EN_B indications.
|
||||
* The rotary encoder part is also independent of the LCD chipset.
|
||||
*/
|
||||
uint8_t val = 0;
|
||||
WRITE(SHIFT_LD_PIN, LOW);
|
||||
WRITE(SHIFT_LD_PIN, HIGH);
|
||||
for (uint8_t i = 0; i < 8; ++i) {
|
||||
val >>= 1;
|
||||
if (READ(SHIFT_OUT_PIN)) SBI(val, 7);
|
||||
WRITE(SHIFT_CLK_PIN, HIGH);
|
||||
WRITE(SHIFT_CLK_PIN, LOW);
|
||||
}
|
||||
TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val;
|
||||
#endif
|
||||
|
||||
#if IS_TFTGLCD_PANEL
|
||||
next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2);
|
||||
buttons = slow_buttons;
|
||||
TERN_(AUTO_BED_LEVELING_UBL, external_encoder());
|
||||
#endif
|
||||
|
||||
} // update_buttons
|
||||
|
||||
#endif // HAS_ENCODER_ACTION
|
||||
|
||||
#endif // HAS_WIRED_LCD
|
||||
|
||||
#if MARLINUI_ENCODER_DELTA
|
||||
|
||||
#define ENCODER_DEBOUNCE_MS 2
|
||||
|
||||
/**
|
||||
* Get the encoder delta (-2 -1 0 +1 +2) since the last call, reading the live encoder state.
|
||||
* Pins may be debounced to filter noise.
|
||||
*/
|
||||
int8_t MarlinUI::get_encoder_delta(const millis_t &now/*=millis()*/) {
|
||||
|
||||
typedef struct { bool a:1, b:1; } enc_t;
|
||||
|
||||
const enc_t live_enc = { BUTTON_PRESSED(EN1), BUTTON_PRESSED(EN2) };
|
||||
|
||||
#if ENCODER_DEBOUNCE_MS
|
||||
|
||||
static enc_t enc;
|
||||
static enc_t old_live;
|
||||
|
||||
static millis_t en_A_bounce_ms;
|
||||
if (old_live.a != live_enc.a) en_A_bounce_ms = now + (ENCODER_DEBOUNCE_MS);
|
||||
else if (ELAPSED(now, en_A_bounce_ms)) enc.a = live_enc.a;
|
||||
|
||||
static millis_t en_B_bounce_ms;
|
||||
if (old_live.b != live_enc.b) en_B_bounce_ms = now + (ENCODER_DEBOUNCE_MS);
|
||||
else if (ELAPSED(now, en_B_bounce_ms)) enc.b = live_enc.b;
|
||||
|
||||
old_live = live_enc;
|
||||
|
||||
#else
|
||||
|
||||
const enc_t &enc = live_enc;
|
||||
|
||||
#endif
|
||||
|
||||
static uint8_t old_pos;
|
||||
const uint8_t pos = (enc.a ^ enc.b) | (enc.a << 1); // 0:00 1:10 2:11 3:01
|
||||
int8_t delta = 0;
|
||||
if (pos != old_pos) {
|
||||
delta = (pos - old_pos + 4 + 1) % 4 - 1;
|
||||
old_pos = pos;
|
||||
|
||||
static int8_t last_dir;
|
||||
if (delta == 2) delta = last_dir * 2;
|
||||
else last_dir = delta;
|
||||
}
|
||||
return delta;
|
||||
|
||||
} // get_encoder_delta
|
||||
|
||||
#endif // MARLINUI_ENCODER_DELTA
|
||||
|
||||
void MarlinUI::completion_feedback(const bool good/*=true*/) {
|
||||
wake_display(); // Wake the screen for all audio feedback
|
||||
#if HAS_SOUND
|
||||
@@ -1563,12 +1577,12 @@ void MarlinUI::host_notify(const char * const cstr) {
|
||||
*
|
||||
* @param pfmt A constant format P-string
|
||||
*/
|
||||
void MarlinUI::status_printf_P(int8_t level, PGM_P const fmt, ...) {
|
||||
void MarlinUI::status_printf_P(int8_t level, PGM_P const pfmt, ...) {
|
||||
if (set_alert_level(level)) return;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, fmt, args);
|
||||
va_start(args, pfmt);
|
||||
vsnprintf_P(status_message, MAX_MESSAGE_LENGTH, pfmt, args);
|
||||
va_end(args);
|
||||
|
||||
host_notify(status_message);
|
||||
@@ -1642,12 +1656,12 @@ void MarlinUI::host_notify(const char * const cstr) {
|
||||
void MarlinUI::_set_status_and_level(const char * const ustr, const int8_t=0, const bool pgm) {
|
||||
pgm ? host_notify_P(ustr) : host_notify(ustr);
|
||||
}
|
||||
void MarlinUI::status_printf_P(int8_t level, PGM_P const fmt, ...) {
|
||||
void MarlinUI::status_printf_P(int8_t level, PGM_P const pfmt, ...) {
|
||||
MString<30> msg;
|
||||
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
vsnprintf_P(&msg, 30, fmt, args);
|
||||
va_start(args, pfmt);
|
||||
vsnprintf_P(&msg, 30, pfmt, args);
|
||||
va_end(args);
|
||||
|
||||
host_notify(msg);
|
||||
|
||||
@@ -254,6 +254,11 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (HAS_WIRED_LCD && HAS_ENCODER_ACTION && HAS_MARLINUI_ENCODER) || HAS_DWIN_E3V2 || HAS_TFT_LVGL_UI
|
||||
#define MARLINUI_ENCODER_DELTA 1
|
||||
static int8_t get_encoder_delta(const millis_t &now=millis());
|
||||
#endif
|
||||
|
||||
#if HAS_MEDIA
|
||||
#define MEDIA_MENU_GATEWAY TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media)
|
||||
static void media_changed(const uint8_t old_stat, const uint8_t stat);
|
||||
|
||||
@@ -91,7 +91,7 @@ void menu_backlash();
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
EDIT_CURRENT_PWM(STR_C, 1);
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
EDIT_CURRENT_PWM(STR_E, 2);
|
||||
#endif
|
||||
END_MENU();
|
||||
|
||||
@@ -36,13 +36,6 @@
|
||||
#include "../../feature/bedlevel/bedlevel.h"
|
||||
#endif
|
||||
|
||||
#ifndef BED_TRAMMING_Z_HOP
|
||||
#define BED_TRAMMING_Z_HOP 4.0
|
||||
#endif
|
||||
#ifndef BED_TRAMMING_HEIGHT
|
||||
#define BED_TRAMMING_HEIGHT 0.0
|
||||
#endif
|
||||
|
||||
#if ALL(HAS_STOWABLE_PROBE, BED_TRAMMING_USE_PROBE) && DISABLED(BLTOUCH)
|
||||
#define NEEDS_PROBE_DEPLOY 1
|
||||
#endif
|
||||
@@ -151,7 +144,7 @@ static void _lcd_goto_next_corner() {
|
||||
}
|
||||
}
|
||||
|
||||
float z = BED_TRAMMING_Z_HOP;
|
||||
float z = current_position.z + (BED_TRAMMING_Z_HOP);
|
||||
#if ALL(BED_TRAMMING_USE_PROBE, BLTOUCH)
|
||||
z += bltouch.z_extra_clearance();
|
||||
#endif
|
||||
@@ -235,7 +228,7 @@ static void _lcd_goto_next_corner() {
|
||||
}
|
||||
|
||||
bool _lcd_bed_tramming_probe(const bool verify=false) {
|
||||
if (verify) line_to_z(BED_TRAMMING_Z_HOP); // do clearance if needed
|
||||
if (verify) line_to_z(current_position.z + (BED_TRAMMING_Z_HOP)); // do clearance if needed
|
||||
TERN_(BLTOUCH, if (!bltouch.high_speed_mode) bltouch.deploy()); // Deploy in LOW SPEED MODE on every probe action
|
||||
do_blocking_move_to_z(last_z - BED_TRAMMING_PROBE_TOLERANCE, MMM_TO_MMS(Z_PROBE_FEEDRATE_SLOW)); // Move down to lower tolerance
|
||||
if (TEST(endstops.trigger_state(), Z_MIN_PROBE)) { // check if probe triggered
|
||||
@@ -253,7 +246,7 @@ static void _lcd_goto_next_corner() {
|
||||
|
||||
// Raise the probe after the last point to give clearance for stow
|
||||
if (TERN0(NEEDS_PROBE_DEPLOY, good_points == nr_edge_points - 1))
|
||||
line_to_z(BED_TRAMMING_Z_HOP);
|
||||
do_z_clearance(BED_TRAMMING_Z_HOP);
|
||||
|
||||
return true; // probe triggered
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ void menu_main() {
|
||||
START_MENU();
|
||||
BACK_ITEM(MSG_INFO_SCREEN);
|
||||
|
||||
#if HAS_MEDIA && !defined(MEDIA_MENU_AT_TOP) && !HAS_ENCODER_WHEEL
|
||||
#if HAS_MEDIA && !defined(MEDIA_MENU_AT_TOP) && !HAS_MARLINUI_ENCODER
|
||||
#define MEDIA_MENU_AT_TOP
|
||||
#endif
|
||||
|
||||
|
||||
@@ -144,7 +144,7 @@ void _lcd_ubl_custom_mesh() {
|
||||
* UBL Adjust Mesh Height Command
|
||||
*/
|
||||
void _lcd_ubl_adjust_height_cmd() {
|
||||
char ubl_lcd_gcode[13];
|
||||
char ubl_lcd_gcode[14];
|
||||
const int ind = ubl_height_amount > 0 ? 6 : 7;
|
||||
strcpy_P(ubl_lcd_gcode, PSTR("G29P6C-"));
|
||||
sprintf_P(&ubl_lcd_gcode[ind], PSTR(".%i"), ABS(ubl_height_amount));
|
||||
|
||||
@@ -71,12 +71,16 @@ void moveAxis(const AxisEnum axis, const int8_t direction) {
|
||||
}
|
||||
#endif
|
||||
|
||||
const float diff = motionAxisState.currentStepSize * direction;
|
||||
float diff = motionAxisState.currentStepSize * direction;
|
||||
|
||||
#if HAS_BED_PROBE
|
||||
|
||||
if (axis == Z_AXIS && motionAxisState.z_selection == Z_SELECTION_Z_PROBE) {
|
||||
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
|
||||
diff = 0;
|
||||
|
||||
const int16_t babystep_increment = direction * BABYSTEP_SIZE_Z;
|
||||
const bool do_probe = DISABLED(BABYSTEP_HOTEND_Z_OFFSET) || active_extruder == 0;
|
||||
const float bsDiff = planner.mm_per_step[Z_AXIS] * babystep_increment,
|
||||
@@ -92,12 +96,12 @@ void moveAxis(const AxisEnum axis, const int8_t direction) {
|
||||
else
|
||||
TERN(BABYSTEP_HOTEND_Z_OFFSET, hotend_offset[active_extruder].z = new_offs, NOOP);
|
||||
drawMessage_P(NUL_STR); // Clear the error
|
||||
drawAxisValue(axis);
|
||||
}
|
||||
else
|
||||
drawMessage(GET_TEXT_F(MSG_LCD_SOFT_ENDSTOPS));
|
||||
|
||||
#else
|
||||
#else // !BABYSTEP_ZPROBE_OFFSET
|
||||
|
||||
// Only change probe.offset.z
|
||||
probe.offset.z += diff;
|
||||
if (direction < 0 && current_position.z < PROBE_OFFSET_ZMIN) {
|
||||
@@ -111,13 +115,12 @@ void moveAxis(const AxisEnum axis, const int8_t direction) {
|
||||
else
|
||||
drawMessage_P(NUL_STR); // Clear the error
|
||||
|
||||
drawAxisValue(axis);
|
||||
#endif
|
||||
#endif // !BABYSTEP_ZPROBE_OFFSET
|
||||
}
|
||||
|
||||
#endif // HAS_BED_PROBE
|
||||
|
||||
if (!ui.manual_move.processing) {
|
||||
if (diff && !ui.manual_move.processing) {
|
||||
// Get motion limit from software endstops, if any
|
||||
float min, max;
|
||||
soft_endstop.get_manual_axis_limits(axis, min, max);
|
||||
|
||||
@@ -50,6 +50,10 @@
|
||||
#include "../feature/joystick.h"
|
||||
#endif
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
#include "ft_motion.h"
|
||||
#endif
|
||||
|
||||
#if HAS_BED_PROBE
|
||||
#include "probe.h"
|
||||
#endif
|
||||
@@ -351,7 +355,7 @@ void Endstops::event_handler() {
|
||||
TERN_(HAS_STATUS_MESSAGE,
|
||||
ui.status_printf(0,
|
||||
F(S_FMT GANG_N_1(NUM_AXES, " %c") " %c"),
|
||||
GET_TEXT(MSG_LCD_ENDSTOPS),
|
||||
GET_TEXT_F(MSG_LCD_ENDSTOPS),
|
||||
NUM_AXIS_LIST_(chrX, chrY, chrZ, chrI, chrJ, chrK, chrU, chrV, chrW) chrP
|
||||
)
|
||||
);
|
||||
@@ -782,6 +786,7 @@ void Endstops::update() {
|
||||
#define PROCESS_ENDSTOP_Z(MINMAX) PROCESS_DUAL_ENDSTOP(Z, MINMAX)
|
||||
#endif
|
||||
|
||||
|
||||
#if ENABLED(G38_PROBE_TARGET)
|
||||
// For G38 moves check the probe's pin for ALL movement
|
||||
if (G38_move && TEST_ENDSTOP(Z_MIN_PROBE) == TERN1(G38_PROBE_AWAY, (G38_move < 4))) {
|
||||
@@ -796,8 +801,17 @@ void Endstops::update() {
|
||||
// Signal, after validation, if an endstop limit is pressed or not
|
||||
|
||||
#if HAS_X_AXIS
|
||||
if (stepper.axis_is_moving(X_AXIS)) {
|
||||
if (!stepper.motor_direction(X_AXIS_HEAD)) { // -direction
|
||||
#if ENABLED(FT_MOTION)
|
||||
const bool x_moving_pos = ftMotion.axis_moving_pos(X_AXIS_HEAD),
|
||||
x_moving_neg = ftMotion.axis_moving_neg(X_AXIS_HEAD);
|
||||
#define X_MOVE_TEST x_moving_pos || x_moving_neg
|
||||
#define X_NEG_DIR_TEST x_moving_neg
|
||||
#else
|
||||
#define X_MOVE_TEST stepper.axis_is_moving(X_AXIS)
|
||||
#define X_NEG_DIR_TEST !stepper.motor_direction(X_AXIS_HEAD)
|
||||
#endif
|
||||
if (X_MOVE_TEST) {
|
||||
if (X_NEG_DIR_TEST) { // -direction
|
||||
#if HAS_X_MIN_STATE
|
||||
PROCESS_ENDSTOP_X(MIN);
|
||||
#if CORE_DIAG(XY, Y, MIN)
|
||||
@@ -829,8 +843,17 @@ void Endstops::update() {
|
||||
#endif // HAS_X_AXIS
|
||||
|
||||
#if HAS_Y_AXIS
|
||||
if (stepper.axis_is_moving(Y_AXIS)) {
|
||||
if (!stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
|
||||
#if ENABLED(FT_MOTION)
|
||||
const bool y_moving_pos = ftMotion.axis_moving_pos(Y_AXIS_HEAD),
|
||||
y_moving_neg = ftMotion.axis_moving_neg(Y_AXIS_HEAD);
|
||||
#define Y_MOVE_TEST y_moving_pos || y_moving_neg
|
||||
#define Y_NEG_DIR_TEST y_moving_neg
|
||||
#else
|
||||
#define Y_MOVE_TEST stepper.axis_is_moving(Y_AXIS)
|
||||
#define Y_NEG_DIR_TEST !stepper.motor_direction(Y_AXIS_HEAD)
|
||||
#endif
|
||||
if (Y_MOVE_TEST) {
|
||||
if (Y_NEG_DIR_TEST) { // -direction
|
||||
#if HAS_Y_MIN_STATE
|
||||
PROCESS_ENDSTOP_Y(MIN);
|
||||
#if CORE_DIAG(XY, X, MIN)
|
||||
@@ -862,8 +885,17 @@ void Endstops::update() {
|
||||
#endif // HAS_Y_AXIS
|
||||
|
||||
#if HAS_Z_AXIS
|
||||
if (stepper.axis_is_moving(Z_AXIS)) {
|
||||
if (!stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
|
||||
#if ENABLED(FT_MOTION)
|
||||
const bool z_moving_pos = ftMotion.axis_moving_pos(Z_AXIS_HEAD),
|
||||
z_moving_neg = ftMotion.axis_moving_neg(Z_AXIS_HEAD);
|
||||
#define Z_MOVE_TEST z_moving_pos || z_moving_neg
|
||||
#define Z_NEG_DIR_TEST z_moving_neg
|
||||
#else
|
||||
#define Z_MOVE_TEST stepper.axis_is_moving(Z_AXIS)
|
||||
#define Z_NEG_DIR_TEST !stepper.motor_direction(Z_AXIS_HEAD)
|
||||
#endif
|
||||
if (Z_MOVE_TEST) {
|
||||
if (Z_NEG_DIR_TEST) { // Z -direction. Gantry down, bed up.
|
||||
#if HAS_Z_MIN_STATE
|
||||
// If the Z_MIN_PIN is being used for the probe there's no
|
||||
// separate Z_MIN endstop. But a Z endstop could be wired
|
||||
@@ -907,6 +939,7 @@ void Endstops::update() {
|
||||
#endif // HAS_Z_AXIS
|
||||
|
||||
#if HAS_I_AXIS
|
||||
// TODO: FT_Motion logic.
|
||||
if (stepper.axis_is_moving(I_AXIS)) {
|
||||
if (!stepper.motor_direction(I_AXIS_HEAD)) { // -direction
|
||||
#if HAS_I_MIN_STATE
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include "ft_motion.h"
|
||||
#include "stepper.h" // Access stepper block queue function and abort status.
|
||||
#include "endstops.h"
|
||||
|
||||
FTMotion ftMotion;
|
||||
|
||||
@@ -59,6 +60,9 @@ int32_t FTMotion::stepperCmdBuff_produceIdx = 0, // Index of next stepper comman
|
||||
FTMotion::stepperCmdBuff_consumeIdx = 0; // Index of next stepper command read from the buffer.
|
||||
|
||||
bool FTMotion::sts_stepperBusy = false; // The stepper buffer has items and is in use.
|
||||
millis_t FTMotion::axis_pos_move_end_ti[NUM_AXIS_ENUMS] = {0},
|
||||
FTMotion::axis_neg_move_end_ti[NUM_AXIS_ENUMS] = {0};
|
||||
|
||||
|
||||
// Private variables.
|
||||
|
||||
@@ -110,9 +114,9 @@ uint32_t FTMotion::interpIdx = 0, // Index of current data point b
|
||||
#if HAS_X_AXIS
|
||||
FTMotion::shaping_t FTMotion::shaping = {
|
||||
0, 0,
|
||||
x:{ { 0.0f }, { 0.0f }, { 0 } }, // d_zi, Ai, Ni
|
||||
x:{ false, { 0.0f }, { 0.0f }, { 0 } }, // d_zi, Ai, Ni
|
||||
#if HAS_Y_AXIS
|
||||
y:{ { 0.0f }, { 0.0f }, { 0 } } // d_zi, Ai, Ni
|
||||
y:{ false, { 0.0f }, { 0.0f }, { 0 } } // d_zi, Ai, Ni
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
@@ -131,7 +135,10 @@ constexpr uint32_t last_batchIdx = (FTM_WINDOW_SIZE) - (FTM_BATCH_SIZE);
|
||||
|
||||
// Public functions.
|
||||
|
||||
static bool markBlockStart = false;
|
||||
|
||||
// Sets controller states to begin processing a block.
|
||||
// Called by Stepper::ftMotion_blockQueueUpdate, invoked from the main loop.
|
||||
void FTMotion::startBlockProc() {
|
||||
blockProcRdy = true;
|
||||
blockProcDn = false;
|
||||
@@ -166,11 +173,13 @@ void FTMotion::loop() {
|
||||
|
||||
if (!cfg.mode) return;
|
||||
|
||||
// Handle block abort with the following sequence:
|
||||
// 1. Zero out commands in stepper ISR.
|
||||
// 2. Drain the motion buffer, stop processing until they are emptied.
|
||||
// 3. Reset all the states / memory.
|
||||
// 4. Signal ready for new block.
|
||||
/**
|
||||
* Handle block abort with the following sequence:
|
||||
* 1. Zero out commands in stepper ISR.
|
||||
* 2. Drain the motion buffer, stop processing until they are emptied.
|
||||
* 3. Reset all the states / memory.
|
||||
* 4. Signal ready for new block.
|
||||
*/
|
||||
if (stepper.abort_current_block) {
|
||||
if (sts_stepperBusy) return; // Wait until motion buffers are emptied
|
||||
reset();
|
||||
@@ -183,7 +192,10 @@ void FTMotion::loop() {
|
||||
|
||||
if (blockProcRdy) {
|
||||
if (!blockProcRdy_z1) { // One-shot.
|
||||
if (!blockDataIsRunout) loadBlockData(stepper.current_block);
|
||||
if (!blockDataIsRunout) {
|
||||
loadBlockData(stepper.current_block);
|
||||
markBlockStart = true;
|
||||
}
|
||||
else blockDataIsRunout = false;
|
||||
}
|
||||
while (!blockProcDn && !batchRdy && (makeVector_idx - makeVector_idx_z1 < (FTM_POINTS_PER_LOOP)))
|
||||
@@ -199,22 +211,12 @@ void FTMotion::loop() {
|
||||
trajMod = traj; // Move the window to traj
|
||||
#else
|
||||
// Copy the uncompensated vectors.
|
||||
#define TCOPY(A) memcpy(trajMod.A, traj.A, sizeof(trajMod.A))
|
||||
LOGICAL_AXIS_CODE(
|
||||
TCOPY(e),
|
||||
TCOPY(x), TCOPY(y), TCOPY(z),
|
||||
TCOPY(i), TCOPY(j), TCOPY(k),
|
||||
TCOPY(u), TCOPY(v), TCOPY(w)
|
||||
);
|
||||
#define TCOPY(A) memcpy(trajMod.A, traj.A, sizeof(trajMod.A));
|
||||
LOGICAL_AXIS_MAP_LC(TCOPY);
|
||||
|
||||
// Shift the time series back in the window
|
||||
#define TSHIFT(A) memcpy(traj.A, &traj.A[FTM_BATCH_SIZE], last_batchIdx * sizeof(traj.A[0]))
|
||||
LOGICAL_AXIS_CODE(
|
||||
TSHIFT(e),
|
||||
TSHIFT(x), TSHIFT(y), TSHIFT(z),
|
||||
TSHIFT(i), TSHIFT(j), TSHIFT(k),
|
||||
TSHIFT(u), TSHIFT(v), TSHIFT(w)
|
||||
);
|
||||
#define TSHIFT(A) memcpy(traj.A, &traj.A[FTM_BATCH_SIZE], last_batchIdx * sizeof(traj.A[0]));
|
||||
LOGICAL_AXIS_MAP_LC(TSHIFT);
|
||||
#endif
|
||||
|
||||
// ... data is ready in trajMod.
|
||||
@@ -471,6 +473,9 @@ void FTMotion::reset() {
|
||||
#endif
|
||||
|
||||
TERN_(HAS_EXTRUDERS, e_raw_z1 = e_advanced_z1 = 0.0f);
|
||||
|
||||
ZERO(axis_pos_move_end_ti);
|
||||
ZERO(axis_neg_move_end_ti);
|
||||
}
|
||||
|
||||
// Private functions.
|
||||
@@ -490,14 +495,14 @@ void FTMotion::init() {
|
||||
reset(); // Precautionary.
|
||||
}
|
||||
|
||||
// Loads / converts block data from planner to fixed-time control variables.
|
||||
// Load / convert block data from planner to fixed-time control variables.
|
||||
void FTMotion::loadBlockData(block_t * const current_block) {
|
||||
|
||||
const float totalLength = current_block->millimeters,
|
||||
oneOverLength = 1.0f / totalLength;
|
||||
|
||||
startPosn = endPosn_prevBlock;
|
||||
xyze_pos_t moveDist = LOGICAL_AXIS_ARRAY(
|
||||
const xyze_pos_t moveDist = LOGICAL_AXIS_ARRAY(
|
||||
current_block->steps.e * planner.mm_per_step[E_AXIS_N(current_block->extruder)] * (current_block->direction_bits.e ? 1 : -1),
|
||||
current_block->steps.x * planner.mm_per_step[X_AXIS] * (current_block->direction_bits.x ? 1 : -1),
|
||||
current_block->steps.y * planner.mm_per_step[Y_AXIS] * (current_block->direction_bits.y ? 1 : -1),
|
||||
@@ -574,7 +579,8 @@ void FTMotion::loadBlockData(block_t * const current_block) {
|
||||
* f_s * T1_P : (mm) Distance traveled during the accel phase
|
||||
* f_e * T3_P : (mm) Distance traveled during the decel phase
|
||||
*/
|
||||
F_P = (2.0f * totalLength - f_s * T1_P - f_e * T3_P) / (T1_P + 2.0f * T2_P + T3_P); // (mm/s) Feedrate at the end of the accel phase
|
||||
const float adist = f_s * T1_P;
|
||||
F_P = (2.0f * totalLength - adist - f_e * T3_P) / (T1_P + 2.0f * T2_P + T3_P); // (mm/s) Feedrate at the end of the accel phase
|
||||
|
||||
// Calculate the acceleration and deceleration rates
|
||||
accel_P = N1 ? ((F_P - f_s) / T1_P) : 0.0f;
|
||||
@@ -582,7 +588,7 @@ void FTMotion::loadBlockData(block_t * const current_block) {
|
||||
decel_P = (f_e - F_P) / T3_P;
|
||||
|
||||
// Calculate the distance traveled during the accel phase
|
||||
s_1e = f_s * T1_P + 0.5f * accel_P * sq(T1_P);
|
||||
s_1e = adist + 0.5f * accel_P * sq(T1_P);
|
||||
|
||||
// Calculate the distance traveled during the decel phase
|
||||
s_2e = s_1e + F_P * T2_P;
|
||||
@@ -591,6 +597,43 @@ void FTMotion::loadBlockData(block_t * const current_block) {
|
||||
max_intervals = N1 + N2 + N3;
|
||||
|
||||
endPosn_prevBlock += moveDist;
|
||||
|
||||
millis_t move_end_ti = millis() + SEC_TO_MS(FTM_TS*(float)(max_intervals + num_samples_cmpnstr_settle() + (PROP_BATCHES+1)*FTM_BATCH_SIZE) + ((float)FTM_STEPPERCMD_BUFF_SIZE/(float)FTM_STEPPER_FS));
|
||||
|
||||
#if CORE_IS_XY
|
||||
if (moveDist.x > 0.f) axis_pos_move_end_ti[A_AXIS] = move_end_ti;
|
||||
if (moveDist.y > 0.f) axis_pos_move_end_ti[B_AXIS] = move_end_ti;
|
||||
if (moveDist.x + moveDist.y > 0.f) axis_pos_move_end_ti[X_HEAD] = move_end_ti;
|
||||
if (moveDist.x - moveDist.y > 0.f) axis_pos_move_end_ti[Y_HEAD] = move_end_ti;
|
||||
if (moveDist.x < 0.f) axis_neg_move_end_ti[A_AXIS] = move_end_ti;
|
||||
if (moveDist.y < 0.f) axis_neg_move_end_ti[B_AXIS] = move_end_ti;
|
||||
if (moveDist.x + moveDist.y < 0.f) axis_neg_move_end_ti[X_HEAD] = move_end_ti;
|
||||
if (moveDist.x - moveDist.y < 0.f) axis_neg_move_end_ti[Y_HEAD] = move_end_ti;
|
||||
#else
|
||||
if (moveDist.x > 0.f) axis_pos_move_end_ti[X_AXIS] = move_end_ti;
|
||||
if (moveDist.y > 0.f) axis_pos_move_end_ti[Y_AXIS] = move_end_ti;
|
||||
if (moveDist.x < 0.f) axis_neg_move_end_ti[X_AXIS] = move_end_ti;
|
||||
if (moveDist.y < 0.f) axis_neg_move_end_ti[Y_AXIS] = move_end_ti;
|
||||
#endif
|
||||
if (moveDist.z > 0.f) axis_pos_move_end_ti[Z_AXIS] = move_end_ti;
|
||||
if (moveDist.z < 0.f) axis_neg_move_end_ti[Z_AXIS] = move_end_ti;
|
||||
// if (moveDist.i > 0.f) axis_pos_move_end_ti[I_AXIS] = move_end_ti;
|
||||
// if (moveDist.i < 0.f) axis_neg_move_end_ti[I_AXIS] = move_end_ti;
|
||||
// if (moveDist.j > 0.f) axis_pos_move_end_ti[J_AXIS] = move_end_ti;
|
||||
// if (moveDist.j < 0.f) axis_neg_move_end_ti[J_AXIS] = move_end_ti;
|
||||
// if (moveDist.k > 0.f) axis_pos_move_end_ti[K_AXIS] = move_end_ti;
|
||||
// if (moveDist.k < 0.f) axis_neg_move_end_ti[K_AXIS] = move_end_ti;
|
||||
// if (moveDist.u > 0.f) axis_pos_move_end_ti[U_AXIS] = move_end_ti;
|
||||
// if (moveDist.u < 0.f) axis_neg_move_end_ti[U_AXIS] = move_end_ti;
|
||||
// .
|
||||
// .
|
||||
// .
|
||||
|
||||
// If the endstop is already pressed, endstop interrupts won't invoke
|
||||
// endstop_triggered and the move will grind. So check here for a
|
||||
// triggered endstop, which shortly marks the block for discard.
|
||||
endstops.update();
|
||||
|
||||
}
|
||||
|
||||
// Generate data points of the trajectory.
|
||||
@@ -607,7 +650,6 @@ void FTMotion::makeVector() {
|
||||
else if (makeVector_idx < (N1 + N2)) {
|
||||
// Coasting phase
|
||||
dist = s_1e + F_P * (tau - N1 * (FTM_TS)); // (mm) Distance traveled for coasting phase since start of block
|
||||
//accel_k = 0.0f;
|
||||
}
|
||||
else {
|
||||
// Deceleration phase
|
||||
@@ -616,18 +658,8 @@ void FTMotion::makeVector() {
|
||||
accel_k = decel_P; // (mm/s^2) Acceleration K factor from Decel phase
|
||||
}
|
||||
|
||||
LOGICAL_AXIS_CODE(
|
||||
traj.e[makeVector_batchIdx] = startPosn.e + ratio.e * dist,
|
||||
traj.x[makeVector_batchIdx] = startPosn.x + ratio.x * dist,
|
||||
traj.y[makeVector_batchIdx] = startPosn.y + ratio.y * dist,
|
||||
traj.z[makeVector_batchIdx] = startPosn.z + ratio.z * dist,
|
||||
traj.i[makeVector_batchIdx] = startPosn.i + ratio.i * dist,
|
||||
traj.j[makeVector_batchIdx] = startPosn.j + ratio.j * dist,
|
||||
traj.k[makeVector_batchIdx] = startPosn.k + ratio.k * dist,
|
||||
traj.u[makeVector_batchIdx] = startPosn.u + ratio.u * dist,
|
||||
traj.v[makeVector_batchIdx] = startPosn.v + ratio.v * dist,
|
||||
traj.w[makeVector_batchIdx] = startPosn.w + ratio.w * dist
|
||||
);
|
||||
#define _FTM_TRAJ(A) traj.A[makeVector_batchIdx] = startPosn.A + ratio.A * dist;
|
||||
LOGICAL_AXIS_MAP_LC(_FTM_TRAJ);
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
if (cfg.linearAdvEna) {
|
||||
@@ -706,7 +738,7 @@ void FTMotion::makeVector() {
|
||||
* - Tests for delta are moved outside the loop.
|
||||
* - Two functions are used for command computation with an array of function pointers.
|
||||
*/
|
||||
static void (*command_set[NUM_AXES TERN0(HAS_EXTRUDERS, +1)])(int32_t&, int32_t&, ft_command_t&, int32_t, int32_t);
|
||||
static void (*command_set[SUM_TERN(HAS_EXTRUDERS, NUM_AXES, 1)])(int32_t&, int32_t&, ft_command_t&, int32_t, int32_t);
|
||||
|
||||
static void command_set_pos(int32_t &e, int32_t &s, ft_command_t &b, int32_t bd, int32_t bs) {
|
||||
if (e < FTM_CTS_COMPARE_VAL) return;
|
||||
@@ -746,40 +778,30 @@ void FTMotion::convertToSteps(const uint32_t idx) {
|
||||
);
|
||||
#endif
|
||||
|
||||
LOGICAL_AXIS_CODE(
|
||||
command_set[E_AXIS_N(current_block->extruder)] = delta.e >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[X_AXIS] = delta.x >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[Y_AXIS] = delta.y >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[Z_AXIS] = delta.z >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[I_AXIS] = delta.i >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[J_AXIS] = delta.j >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[K_AXIS] = delta.k >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[U_AXIS] = delta.u >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[V_AXIS] = delta.v >= 0 ? command_set_pos : command_set_neg,
|
||||
command_set[W_AXIS] = delta.w >= 0 ? command_set_pos : command_set_neg
|
||||
);
|
||||
#define _COMMAND_SET(AXIS) command_set[_AXIS(AXIS)] = delta[_AXIS(AXIS)] >= 0 ? command_set_pos : command_set_neg;
|
||||
LOGICAL_AXIS_MAP(_COMMAND_SET);
|
||||
|
||||
for (uint32_t i = 0U; i < (FTM_STEPS_PER_UNIT_TIME); i++) {
|
||||
|
||||
// Init all step/dir bits to 0 (defaulting to reverse/negative motion)
|
||||
stepperCmdBuff[stepperCmdBuff_produceIdx] = 0;
|
||||
ft_command_t &cmd = stepperCmdBuff[stepperCmdBuff_produceIdx];
|
||||
|
||||
// Init all step/dir bits to 0 (defaulting to reverse/negative motion)
|
||||
cmd = 0;
|
||||
|
||||
// Mark the start of a new block
|
||||
if (markBlockStart) {
|
||||
cmd = _BV(FT_BIT_START);
|
||||
markBlockStart = false;
|
||||
}
|
||||
|
||||
// Accumulate the errors for all axes
|
||||
err_P += delta;
|
||||
|
||||
// Set up step/dir bits for all axes
|
||||
LOGICAL_AXIS_CODE(
|
||||
command_set[E_AXIS_N(current_block->extruder)](err_P.e, steps.e, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_E), _BV(FT_BIT_STEP_E)),
|
||||
command_set[X_AXIS](err_P.x, steps.x, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_X), _BV(FT_BIT_STEP_X)),
|
||||
command_set[Y_AXIS](err_P.y, steps.y, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_Y), _BV(FT_BIT_STEP_Y)),
|
||||
command_set[Z_AXIS](err_P.z, steps.z, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_Z), _BV(FT_BIT_STEP_Z)),
|
||||
command_set[I_AXIS](err_P.i, steps.i, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_I), _BV(FT_BIT_STEP_I)),
|
||||
command_set[J_AXIS](err_P.j, steps.j, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_J), _BV(FT_BIT_STEP_J)),
|
||||
command_set[K_AXIS](err_P.k, steps.k, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_K), _BV(FT_BIT_STEP_K)),
|
||||
command_set[U_AXIS](err_P.u, steps.u, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_U), _BV(FT_BIT_STEP_U)),
|
||||
command_set[V_AXIS](err_P.v, steps.v, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_V), _BV(FT_BIT_STEP_V)),
|
||||
command_set[W_AXIS](err_P.w, steps.w, stepperCmdBuff[stepperCmdBuff_produceIdx], _BV(FT_BIT_DIR_W), _BV(FT_BIT_STEP_W)),
|
||||
);
|
||||
#define _COMMAND_RUN(AXIS) command_set[_AXIS(AXIS)](err_P[_AXIS(AXIS)], steps[_AXIS(AXIS)], cmd, _BV(FT_BIT_DIR_##AXIS), _BV(FT_BIT_STEP_##AXIS));
|
||||
LOGICAL_AXIS_MAP(_COMMAND_RUN);
|
||||
|
||||
// Next circular buffer index
|
||||
if (++stepperCmdBuff_produceIdx == (FTM_STEPPERCMD_BUFF_SIZE))
|
||||
stepperCmdBuff_produceIdx = 0;
|
||||
|
||||
|
||||
@@ -107,6 +107,9 @@ class FTMotion {
|
||||
|
||||
static bool sts_stepperBusy; // The stepper buffer has items and is in use.
|
||||
|
||||
static millis_t axis_pos_move_end_ti[NUM_AXIS_ENUMS],
|
||||
axis_neg_move_end_ti[NUM_AXIS_ENUMS];
|
||||
|
||||
// Public methods
|
||||
static void init();
|
||||
static void startBlockProc(); // Set controller states to begin processing a block.
|
||||
@@ -129,6 +132,9 @@ class FTMotion {
|
||||
|
||||
static void reset(); // Reset all states of the fixed time conversion to defaults.
|
||||
|
||||
static bool axis_moving_pos(const AxisEnum axis) { return !ELAPSED(millis(), axis_pos_move_end_ti[axis]); }
|
||||
static bool axis_moving_neg(const AxisEnum axis) { return !ELAPSED(millis(), axis_neg_move_end_ti[axis]); }
|
||||
|
||||
private:
|
||||
|
||||
static xyze_trajectory_t traj;
|
||||
@@ -152,6 +158,8 @@ class FTMotion {
|
||||
static uint32_t N1, N2, N3;
|
||||
static uint32_t max_intervals;
|
||||
|
||||
static constexpr uint32_t PROP_BATCHES = CEIL(FTM_WINDOW_SIZE/FTM_BATCH_SIZE) - 1; // Number of batches needed to propagate the current trajectory to the stepper.
|
||||
|
||||
#define _DIVCEIL(A,B) (((A) + (B) - 1) / (B))
|
||||
static constexpr uint32_t _ftm_ratio = TERN(FTM_UNIFIED_BWS, 2, _DIVCEIL(FTM_WINDOW_SIZE, FTM_BATCH_SIZE)),
|
||||
shaper_intervals = (FTM_BATCH_SIZE) * _DIVCEIL(FTM_ZMAX, FTM_BATCH_SIZE),
|
||||
@@ -172,6 +180,7 @@ class FTMotion {
|
||||
#if HAS_X_AXIS
|
||||
|
||||
typedef struct AxisShaping {
|
||||
bool ena = false; // Enabled indication.
|
||||
float d_zi[FTM_ZMAX] = { 0.0f }; // Data point delay vector.
|
||||
float Ai[5]; // Shaping gain vector.
|
||||
uint32_t Ni[5]; // Shaping time index vector.
|
||||
@@ -207,6 +216,9 @@ class FTMotion {
|
||||
static void makeVector();
|
||||
static void convertToSteps(const uint32_t idx);
|
||||
|
||||
FORCE_INLINE static int32_t num_samples_cmpnstr_settle() { return ( shaping.x.ena || shaping.y.ena ) ? FTM_ZMAX : 0; }
|
||||
|
||||
|
||||
}; // class FTMotion
|
||||
|
||||
extern FTMotion ftMotion;
|
||||
|
||||
@@ -47,7 +47,9 @@ enum dynFreqMode_t : uint8_t {
|
||||
typedef struct XYZEarray<float, FTM_WINDOW_SIZE> xyze_trajectory_t;
|
||||
typedef struct XYZEarray<float, FTM_BATCH_SIZE> xyze_trajectoryMod_t;
|
||||
|
||||
// TODO: Convert ft_command_t to a struct with bitfields instead of using a primitive type
|
||||
enum {
|
||||
FT_BIT_START,
|
||||
LIST_N(DOUBLE(LOGICAL_AXES),
|
||||
FT_BIT_DIR_E, FT_BIT_STEP_E,
|
||||
FT_BIT_DIR_X, FT_BIT_STEP_X, FT_BIT_DIR_Y, FT_BIT_STEP_Y, FT_BIT_DIR_Z, FT_BIT_STEP_Z,
|
||||
|
||||
@@ -714,6 +714,14 @@ void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*
|
||||
fr_mm_s
|
||||
);
|
||||
}
|
||||
/**
|
||||
* Move Z to a particular height so the nozzle or deployed probe clears the bed.
|
||||
* (Use do_z_clearance_by for clearance over the current position.)
|
||||
* - For a probe, add clearance for the probe distance
|
||||
* - Constrain to the Z max physical position
|
||||
* - If lowering is not allowed then skip a downward move
|
||||
* - Execute the move at the probing (or homing) feedrate
|
||||
*/
|
||||
void do_z_clearance(const_float_t zclear, const bool with_probe/*=true*/, const bool lower_allowed/*=false*/) {
|
||||
UNUSED(with_probe);
|
||||
float zdest = zclear;
|
||||
@@ -727,9 +735,13 @@ void do_blocking_move_to(const xyze_pos_t &raw, const_feedRate_t fr_mm_s/*=0.0f*
|
||||
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("do_z_clearance_by(", zclear, ")");
|
||||
do_z_clearance(current_position.z + zclear, false);
|
||||
}
|
||||
/**
|
||||
* Move Z to Z_POST_CLEARANCE,
|
||||
* The axis is allowed to move down.
|
||||
*/
|
||||
void do_move_after_z_homing() {
|
||||
DEBUG_SECTION(mzah, "do_move_after_z_homing", DEBUGGING(LEVELING));
|
||||
#if defined(Z_AFTER_HOMING) || ALL(DWIN_LCD_PROUI, INDIVIDUAL_AXIS_HOMING_SUBMENU, MESH_BED_LEVELING)
|
||||
#ifdef Z_POST_CLEARANCE
|
||||
do_z_clearance(Z_POST_CLEARANCE, true, true);
|
||||
#elif ENABLED(USE_PROBE_FOR_Z_HOMING)
|
||||
probe.move_z_after_probing();
|
||||
|
||||
@@ -1858,32 +1858,35 @@ bool Planner::_populate_block(
|
||||
|
||||
// Compute direction bit-mask for this block
|
||||
AxisBits dm;
|
||||
#if ANY(CORE_IS_XY, MARKFORGED_XY, MARKFORGED_YX)
|
||||
dm.hx = (dist.a > 0); // Save the toolhead's true direction in X
|
||||
dm.hy = (dist.b > 0); // ...and Y
|
||||
TERN_(HAS_Z_AXIS, dm.z = (dist.c > 0));
|
||||
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX)
|
||||
dm.hx = (dist.a > 0); // True direction in X
|
||||
#endif
|
||||
#if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX)
|
||||
dm.hy = (dist.b > 0); // True direction in Y
|
||||
#endif
|
||||
#if ANY(CORE_IS_XZ, CORE_IS_YZ)
|
||||
dm.hz = (dist.c > 0); // True direction in Z
|
||||
#endif
|
||||
#if CORE_IS_XY
|
||||
dm.a = (dist.a + dist.b > 0); // Motor A direction
|
||||
dm.b = (CORESIGN(dist.a - dist.b) > 0); // Motor B direction
|
||||
dm.a = (dist.a + dist.b > 0); // Motor A direction
|
||||
dm.b = (CORESIGN(dist.a - dist.b) > 0); // Motor B direction
|
||||
TERN_(HAS_Z_AXIS, dm.z = (dist.c > 0)); // Axis Z direction
|
||||
#elif CORE_IS_XZ
|
||||
dm.hx = (dist.a > 0); // Save the toolhead's true direction in X
|
||||
dm.y = (dist.b > 0);
|
||||
dm.hz = (dist.c > 0); // ...and Z
|
||||
dm.a = (dist.a + dist.c > 0); // Motor A direction
|
||||
dm.y = (dist.b > 0); // Axis Y direction
|
||||
dm.c = (CORESIGN(dist.a - dist.c) > 0); // Motor C direction
|
||||
#elif CORE_IS_YZ
|
||||
dm.x = (dist.a > 0);
|
||||
dm.hy = (dist.b > 0); // Save the toolhead's true direction in Y
|
||||
dm.hz = (dist.c > 0); // ...and Z
|
||||
dm.x = (dist.a > 0); // Axis X direction
|
||||
dm.b = (dist.b + dist.c > 0); // Motor B direction
|
||||
dm.c = (CORESIGN(dist.b - dist.c) > 0); // Motor C direction
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
dm.a = (dist.a TERN(MARKFORGED_INVERSE, -, +) dist.b > 0); // Motor A direction
|
||||
dm.b = (dist.b > 0); // Motor B direction
|
||||
TERN_(HAS_Z_AXIS, dm.z = (dist.c > 0)); // Axis Z direction
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
dm.a = (dist.a > 0); // Motor A direction
|
||||
dm.b = (dist.b TERN(MARKFORGED_INVERSE, -, +) dist.a > 0); // Motor B direction
|
||||
TERN_(HAS_Z_AXIS, dm.z = (dist.c > 0)); // Axis Z direction
|
||||
#else
|
||||
XYZ_CODE(
|
||||
dm.x = (dist.a > 0),
|
||||
@@ -2274,14 +2277,12 @@ bool Planner::_populate_block(
|
||||
#endif
|
||||
|
||||
const feedRate_t cs = ABS(current_speed.e),
|
||||
max_fr = settings.max_feedrate_mm_s[E_AXIS_N(extruder)]
|
||||
* TERN(HAS_MIXER_SYNC_CHANNEL, MIXING_STEPPERS, 1);
|
||||
max_fr = MUL_TERN(HAS_MIXER_SYNC_CHANNEL, settings.max_feedrate_mm_s[E_AXIS_N(extruder)], MIXING_STEPPERS);
|
||||
|
||||
if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); //respect max feedrate on any movement (doesn't matter if E axes only or not)
|
||||
if (cs > max_fr) NOMORE(speed_factor, max_fr / cs); // Respect max feedrate on any move (travel and print)
|
||||
|
||||
#if ENABLED(VOLUMETRIC_EXTRUDER_LIMIT)
|
||||
const feedRate_t max_vfr = volumetric_extruder_feedrate_limit[extruder]
|
||||
* TERN(HAS_MIXER_SYNC_CHANNEL, MIXING_STEPPERS, 1);
|
||||
const feedRate_t max_vfr = MUL_TERN(HAS_MIXER_SYNC_CHANNEL, volumetric_extruder_feedrate_limit[extruder], MIXING_STEPPERS);
|
||||
|
||||
// TODO: Doesn't work properly for joined segments. Set MIN_STEPS_PER_SEGMENT 1 as workaround.
|
||||
|
||||
@@ -2453,7 +2454,7 @@ bool Planner::_populate_block(
|
||||
// Formula for the average speed over a 1 step worth of distance if starting from zero and
|
||||
// accelerating at the current limit. Since we can only change the speed every step this is a
|
||||
// good lower limit for the entry and exit speeds. Note that for calculate_trapezoid_for_block()
|
||||
// to work correctly this must be accurately set and propagated.
|
||||
// to work correctly, this must be accurately set and propagated.
|
||||
minimum_planner_speed_sqr = 0.5f * block->acceleration / steps_per_mm;
|
||||
// Go straight to/from nominal speed if block->acceleration is too high for it.
|
||||
NOMORE(minimum_planner_speed_sqr, sq(block->nominal_speed));
|
||||
@@ -2727,7 +2728,7 @@ bool Planner::_populate_block(
|
||||
#endif // CLASSIC_JERK
|
||||
|
||||
// High acceleration limits override low jerk/junction deviation limits (as fixing trapezoids
|
||||
// or reducing acceleration introduces too much complexity and/or too much compute).
|
||||
// or reducing acceleration introduces too much complexity and/or too much compute)
|
||||
NOLESS(vmax_junction_sqr, minimum_planner_speed_sqr);
|
||||
|
||||
// Max entry speed of this block equals the max exit speed of the previous block.
|
||||
@@ -2776,10 +2777,12 @@ void Planner::buffer_sync_block(const BlockFlagBit sync_flag/*=BLOCK_BIT_SYNC_PO
|
||||
block->flag.apply(sync_flag);
|
||||
|
||||
block->position = position;
|
||||
|
||||
#if ENABLED(BACKLASH_COMPENSATION)
|
||||
LOOP_NUM_AXES(axis) block->position[axis] += backlash.get_applied_steps((AxisEnum)axis);
|
||||
#endif
|
||||
#if ALL(HAS_FAN, LASER_SYNCHRONOUS_M106_M107)
|
||||
|
||||
#if ENABLED(LASER_SYNCHRONOUS_M106_M107)
|
||||
FANS_LOOP(i) block->fan_speed[i] = thermalManager.fan_speed[i];
|
||||
#endif
|
||||
|
||||
@@ -3108,6 +3111,10 @@ bool Planner::buffer_line(const xyze_pos_t &cart, const_feedRate_t fr_mm_s
|
||||
* The provided ABCE position is in machine units.
|
||||
*/
|
||||
void Planner::set_machine_position_mm(const abce_pos_t &abce) {
|
||||
|
||||
// When FT Motion is enabled, call synchronize() here instead of generating a sync block
|
||||
if (TERN0(FT_MOTION, ftMotion.cfg.mode)) synchronize();
|
||||
|
||||
TERN_(DISTINCT_E_FACTORS, last_extruder = active_extruder);
|
||||
TERN_(HAS_POSITION_FLOAT, position_float = abce);
|
||||
position.set(
|
||||
|
||||
@@ -206,9 +206,10 @@ typedef struct PlannerBlock {
|
||||
|
||||
volatile block_flags_t flag; // Block flags
|
||||
|
||||
bool is_fan_sync() { return TERN0(LASER_SYNCHRONOUS_M106_M107, flag.sync_fans); }
|
||||
bool is_pwr_sync() { return TERN0(LASER_POWER_SYNC, flag.sync_laser_pwr); }
|
||||
bool is_sync() { return flag.sync_position || is_fan_sync() || is_pwr_sync(); }
|
||||
bool is_sync_pos() { return flag.sync_position; }
|
||||
bool is_sync_fan() { return TERN0(LASER_SYNCHRONOUS_M106_M107, flag.sync_fans); }
|
||||
bool is_sync_pwr() { return TERN0(LASER_POWER_SYNC, flag.sync_laser_pwr); }
|
||||
bool is_sync() { return is_sync_pos() || is_sync_fan() || is_sync_pwr(); }
|
||||
bool is_page() { return TERN0(DIRECT_STEPPING, flag.page); }
|
||||
bool is_move() { return !(is_sync() || is_page()); }
|
||||
|
||||
@@ -625,7 +626,7 @@ class Planner {
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
FORCE_INLINE static void refresh_e_factor(const uint8_t e) {
|
||||
e_factor[e] = flow_percentage[e] * 0.01f * TERN(NO_VOLUMETRICS, 1.0f, volumetric_multiplier[e]);
|
||||
e_factor[e] = flow_percentage[e] * 0.01f IF_DISABLED(NO_VOLUMETRICS, * volumetric_multiplier[e]);
|
||||
}
|
||||
|
||||
static void set_flow(const uint8_t e, const int16_t flow) {
|
||||
|
||||
@@ -999,7 +999,7 @@ float Probe::probe_at_point(const_float_t rx, const_float_t ry, const ProbePtRai
|
||||
default: break;
|
||||
case PROBE_PT_RAISE:
|
||||
if (raise_after_is_relative)
|
||||
do_z_clearance(current_position.z + z_clearance, false);
|
||||
do_z_clearance_by(z_clearance);
|
||||
else
|
||||
do_z_clearance(z_clearance);
|
||||
break;
|
||||
|
||||
+235
-141
@@ -648,6 +648,11 @@ void Stepper::disable_all_steppers() {
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onSteppersDisabled());
|
||||
}
|
||||
|
||||
#if ENABLED(FTM_OPTIMIZE_DIR_STATES)
|
||||
// We'll compare the updated DIR bits to the last set state
|
||||
static AxisBits last_set_direction;
|
||||
#endif
|
||||
|
||||
// Set a single axis direction based on the last set flags.
|
||||
// A direction bit of "1" indicates forward or positive motion.
|
||||
#define SET_STEP_DIR(A) do{ \
|
||||
@@ -673,6 +678,8 @@ void Stepper::apply_directions() {
|
||||
SET_STEP_DIR(U), SET_STEP_DIR(V), SET_STEP_DIR(W)
|
||||
);
|
||||
|
||||
TERN_(FTM_OPTIMIZE_DIR_STATES, last_set_direction = last_direction_bits);
|
||||
|
||||
DIR_WAIT_AFTER();
|
||||
}
|
||||
|
||||
@@ -1543,8 +1550,20 @@ void Stepper::isr() {
|
||||
nextMainISR = FTM_MIN_TICKS; // Set to minimum interval (a limit on the top speed)
|
||||
ftMotion_stepper(); // Run FTM Stepping
|
||||
}
|
||||
interval = nextMainISR; // Interval is either some old nextMainISR or FTM_MIN_TICKS
|
||||
nextMainISR = 0; // For FT Motion fire again ASAP
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
if (nextBabystepISR == 0) { // Avoid ANY stepping too soon after baby-stepping
|
||||
nextBabystepISR = babystepping_isr();
|
||||
NOLESS(nextMainISR, (BABYSTEP_TICKS) / 8); // FULL STOP for 125µs after a baby-step
|
||||
}
|
||||
if (nextBabystepISR != BABYSTEP_NEVER) // Avoid baby-stepping too close to axis Stepping
|
||||
NOLESS(nextBabystepISR, nextMainISR / 2); // TODO: Only look at axes enabled for baby-stepping
|
||||
#endif
|
||||
|
||||
interval = nextMainISR; // Interval is either some old nextMainISR or FTM_MIN_TICKS
|
||||
TERN_(BABYSTEPPING, NOMORE(interval, nextBabystepISR)); // Come back early for Babystepping?
|
||||
|
||||
nextMainISR = 0; // For FT Motion fire again ASAP
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1802,6 +1821,7 @@ void Stepper::pulse_phase_isr() {
|
||||
last_direction_bits.toggle(_AXIS(AXIS)); \
|
||||
DIR_WAIT_BEFORE(); \
|
||||
SET_STEP_DIR(AXIS); \
|
||||
TERN_(FTM_OPTIMIZE_DIR_STATES, last_set_direction = last_direction_bits); \
|
||||
DIR_WAIT_AFTER(); \
|
||||
} \
|
||||
} \
|
||||
@@ -2249,6 +2269,90 @@ hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) {
|
||||
return calc_timer_interval(step_rate);
|
||||
}
|
||||
|
||||
// Method to get all moving axes (for proper endstop handling)
|
||||
void Stepper::set_axis_moved_for_current_block() {
|
||||
|
||||
#if IS_CORE
|
||||
// Define conditions for checking endstops
|
||||
#define S_(N) current_block->steps[CORE_AXIS_##N]
|
||||
#define D_(N) current_block->direction_bits[CORE_AXIS_##N]
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_XZ
|
||||
/**
|
||||
* Head direction in -X axis for CoreXY and CoreXZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving.
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below)
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X)
|
||||
*/
|
||||
#if ANY(COREXY, COREXZ)
|
||||
#define X_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define X_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
#define X_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define X_MOVE_TEST !!current_block->steps.a
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_YZ
|
||||
/**
|
||||
* Head direction in -Y axis for CoreXY / CoreYZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y)
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z)
|
||||
*/
|
||||
#if ANY(COREYX, COREYZ)
|
||||
#define Y_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define Y_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
#define Y_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define Y_MOVE_TEST !!current_block->steps.b
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XZ || CORE_IS_YZ
|
||||
/**
|
||||
* Head direction in -Z axis for CoreXZ or CoreYZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above)
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z)
|
||||
*/
|
||||
#if ANY(COREZX, COREZY)
|
||||
#define Z_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define Z_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Z_CMP(D_(1),D_(2))) )
|
||||
#else
|
||||
#define Z_MOVE_TEST !!current_block->steps.c
|
||||
#endif
|
||||
|
||||
// Set flags for all axes that move in this block
|
||||
// These are set per-axis, not per-stepper
|
||||
AxisBits didmove;
|
||||
NUM_AXIS_CODE(
|
||||
if (X_MOVE_TEST) didmove.a = true, // Cartesian X or Kinematic A
|
||||
if (Y_MOVE_TEST) didmove.b = true, // Cartesian Y or Kinematic B
|
||||
if (Z_MOVE_TEST) didmove.c = true, // Cartesian Z or Kinematic C
|
||||
if (!!current_block->steps.i) didmove.i = true,
|
||||
if (!!current_block->steps.j) didmove.j = true,
|
||||
if (!!current_block->steps.k) didmove.k = true,
|
||||
if (!!current_block->steps.u) didmove.u = true,
|
||||
if (!!current_block->steps.v) didmove.v = true,
|
||||
if (!!current_block->steps.w) didmove.w = true
|
||||
);
|
||||
axis_did_move = didmove;
|
||||
}
|
||||
|
||||
/**
|
||||
* This last phase of the stepper interrupt processes and properly
|
||||
* schedules planner blocks. This is executed after the step pulses
|
||||
@@ -2406,6 +2510,8 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
|
||||
E_APPLY_DIR(forward_e, false);
|
||||
|
||||
TERN_(FTM_OPTIMIZE_DIR_STATES, last_set_direction = last_direction_bits);
|
||||
|
||||
DIR_WAIT_AFTER();
|
||||
}
|
||||
}
|
||||
@@ -2507,25 +2613,31 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
// Anything in the buffer?
|
||||
if ((current_block = planner.get_current_block())) {
|
||||
|
||||
// Sync block? Sync the stepper counts or fan speeds and return
|
||||
// Run through all sync blocks
|
||||
while (current_block->is_sync()) {
|
||||
|
||||
// Set laser power
|
||||
#if ENABLED(LASER_POWER_SYNC)
|
||||
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
|
||||
if (current_block->is_pwr_sync()) {
|
||||
if (current_block->is_sync_pwr()) {
|
||||
planner.laser_inline.status.isSyncPower = true;
|
||||
cutter.apply_power(current_block->laser.power);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
TERN_(LASER_SYNCHRONOUS_M106_M107, if (current_block->is_fan_sync()) planner.sync_fan_speeds(current_block->fan_speed));
|
||||
// Set "fan speeds" for a laser module
|
||||
#if ENABLED(LASER_SYNCHRONOUS_M106_M107)
|
||||
if (current_block->is_sync_fan()) planner.sync_fan_speeds(current_block->fan_speed);
|
||||
#endif
|
||||
|
||||
if (!(current_block->is_fan_sync() || current_block->is_pwr_sync())) _set_position(current_block->position);
|
||||
// Set position
|
||||
if (current_block->is_sync_pos()) _set_position(current_block->position);
|
||||
|
||||
// Done with this block
|
||||
discard_current_block();
|
||||
|
||||
// Try to get a new block
|
||||
// Try to get a new block. Exit if there are no more.
|
||||
if (!(current_block = planner.get_current_block()))
|
||||
return interval; // No more queued movements!
|
||||
}
|
||||
@@ -2559,85 +2671,8 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Flag all moving axes for proper endstop handling
|
||||
|
||||
#if IS_CORE
|
||||
// Define conditions for checking endstops
|
||||
#define S_(N) current_block->steps[CORE_AXIS_##N]
|
||||
#define D_(N) current_block->direction_bits[CORE_AXIS_##N]
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_XZ
|
||||
/**
|
||||
* Head direction in -X axis for CoreXY and CoreXZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving.
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below)
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X)
|
||||
*/
|
||||
#if ANY(COREXY, COREXZ)
|
||||
#define X_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define X_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
#define X_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define X_MOVE_TEST !!current_block->steps.a
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_YZ
|
||||
/**
|
||||
* Head direction in -Y axis for CoreXY / CoreYZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y)
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z)
|
||||
*/
|
||||
#if ANY(COREYX, COREYZ)
|
||||
#define Y_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define Y_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
#define Y_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define Y_MOVE_TEST !!current_block->steps.b
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XZ || CORE_IS_YZ
|
||||
/**
|
||||
* Head direction in -Z axis for CoreXZ or CoreYZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above)
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z)
|
||||
*/
|
||||
#if ANY(COREZX, COREZY)
|
||||
#define Z_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define Z_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Z_CMP(D_(1),D_(2))) )
|
||||
#else
|
||||
#define Z_MOVE_TEST !!current_block->steps.c
|
||||
#endif
|
||||
|
||||
AxisBits didmove;
|
||||
NUM_AXIS_CODE(
|
||||
if (X_MOVE_TEST) didmove.a = true,
|
||||
if (Y_MOVE_TEST) didmove.b = true,
|
||||
if (Z_MOVE_TEST) didmove.c = true,
|
||||
if (!!current_block->steps.i) didmove.i = true,
|
||||
if (!!current_block->steps.j) didmove.j = true,
|
||||
if (!!current_block->steps.k) didmove.k = true,
|
||||
if (!!current_block->steps.u) didmove.u = true,
|
||||
if (!!current_block->steps.v) didmove.v = true,
|
||||
if (!!current_block->steps.w) didmove.w = true
|
||||
);
|
||||
axis_did_move = didmove;
|
||||
// Set flags for all moving axes, accounting for kinematics
|
||||
set_axis_moved_for_current_block();
|
||||
|
||||
#if ENABLED(ADAPTIVE_STEP_SMOOTHING)
|
||||
// Nonlinear Extrusion needs at least 2x oversampling to permit increase of E step rate
|
||||
@@ -3255,15 +3290,12 @@ void Stepper::_set_position(const abce_long_t &spos) {
|
||||
#endif
|
||||
|
||||
#if ANY(IS_CORE, MARKFORGED_XY, MARKFORGED_YX)
|
||||
// Core equations follow the form of the dA and dB equations at https://www.corexy.com/theory.html
|
||||
#if CORE_IS_XY
|
||||
// corexy positioning
|
||||
// these equations follow the form of the dA and dB equations on https://www.corexy.com/theory.html
|
||||
count_position.set(spos.a + spos.b, CORESIGN(spos.a - spos.b) OPTARG(HAS_Z_AXIS, spos.c));
|
||||
#elif CORE_IS_XZ
|
||||
// corexz planning
|
||||
count_position.set(spos.a + spos.c, spos.b, CORESIGN(spos.a - spos.c));
|
||||
#elif CORE_IS_YZ
|
||||
// coreyz planning
|
||||
count_position.set(spos.a, spos.b + spos.c, CORESIGN(spos.b - spos.c));
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
count_position.set(spos.a TERN(MARKFORGED_INVERSE, +, -) spos.b, spos.b, spos.c);
|
||||
@@ -3459,16 +3491,24 @@ void Stepper::report_positions() {
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
|
||||
// Set stepper I/O for fixed time controller.
|
||||
/**
|
||||
* Run stepping from the Stepper ISR at regular short intervals.
|
||||
*
|
||||
* - Set ftMotion.sts_stepperBusy state to reflect whether there are any commands in the circular buffer.
|
||||
* - If there are no commands in the buffer, return.
|
||||
* - Get the next command from the circular buffer ftMotion.stepperCmdBuff[].
|
||||
* - If the block is being aborted, return without processing the command.
|
||||
* - Apply STEP/DIR along with any delays required. A command may be empty, with no STEP/DIR.
|
||||
*/
|
||||
void Stepper::ftMotion_stepper() {
|
||||
|
||||
static AxisBits direction_bits{0};
|
||||
|
||||
// Check if the buffer is empty.
|
||||
ftMotion.sts_stepperBusy = (ftMotion.stepperCmdBuff_produceIdx != ftMotion.stepperCmdBuff_consumeIdx);
|
||||
if (!ftMotion.sts_stepperBusy) return;
|
||||
|
||||
// "Pop" one command from current motion buffer
|
||||
// Use one byte to restore one stepper command in the format:
|
||||
// |X_step|X_direction|Y_step|Y_direction|Z_step|Z_direction|E_step|E_direction|
|
||||
const ft_command_t command = ftMotion.stepperCmdBuff[ftMotion.stepperCmdBuff_consumeIdx];
|
||||
if (++ftMotion.stepperCmdBuff_consumeIdx == (FTM_STEPPERCMD_BUFF_SIZE))
|
||||
ftMotion.stepperCmdBuff_consumeIdx = 0;
|
||||
@@ -3477,58 +3517,80 @@ void Stepper::report_positions() {
|
||||
|
||||
USING_TIMED_PULSE();
|
||||
|
||||
axis_did_move = LOGICAL_AXIS_ARRAY(
|
||||
// Get FT Motion command flags for axis STEP / DIR
|
||||
#define _FTM_STEP(AXIS) TEST(command, FT_BIT_STEP_##AXIS)
|
||||
#define _FTM_DIR(AXIS) TEST(command, FT_BIT_DIR_##AXIS)
|
||||
|
||||
AxisBits axis_step;
|
||||
axis_step = LOGICAL_AXIS_ARRAY(
|
||||
TEST(command, FT_BIT_STEP_E),
|
||||
TEST(command, FT_BIT_STEP_X), TEST(command, FT_BIT_STEP_Y), TEST(command, FT_BIT_STEP_Z),
|
||||
TEST(command, FT_BIT_STEP_I), TEST(command, FT_BIT_STEP_J), TEST(command, FT_BIT_STEP_K),
|
||||
TEST(command, FT_BIT_STEP_U), TEST(command, FT_BIT_STEP_V), TEST(command, FT_BIT_STEP_W)
|
||||
);
|
||||
|
||||
last_direction_bits = LOGICAL_AXIS_ARRAY(
|
||||
axis_did_move.e ? TEST(command, FT_BIT_DIR_E) : last_direction_bits.e,
|
||||
axis_did_move.x ? TEST(command, FT_BIT_DIR_X) : last_direction_bits.x,
|
||||
axis_did_move.y ? TEST(command, FT_BIT_DIR_Y) : last_direction_bits.y,
|
||||
axis_did_move.z ? TEST(command, FT_BIT_DIR_Z) : last_direction_bits.z,
|
||||
axis_did_move.i ? TEST(command, FT_BIT_DIR_I) : last_direction_bits.i,
|
||||
axis_did_move.j ? TEST(command, FT_BIT_DIR_J) : last_direction_bits.j,
|
||||
axis_did_move.k ? TEST(command, FT_BIT_DIR_K) : last_direction_bits.k,
|
||||
axis_did_move.u ? TEST(command, FT_BIT_DIR_U) : last_direction_bits.u,
|
||||
axis_did_move.v ? TEST(command, FT_BIT_DIR_V) : last_direction_bits.v,
|
||||
axis_did_move.w ? TEST(command, FT_BIT_DIR_W) : last_direction_bits.w
|
||||
direction_bits = LOGICAL_AXIS_ARRAY(
|
||||
axis_step.e ? TEST(command, FT_BIT_DIR_E) : direction_bits.e,
|
||||
axis_step.x ? TEST(command, FT_BIT_DIR_X) : direction_bits.x,
|
||||
axis_step.y ? TEST(command, FT_BIT_DIR_Y) : direction_bits.y,
|
||||
axis_step.z ? TEST(command, FT_BIT_DIR_Z) : direction_bits.z,
|
||||
axis_step.i ? TEST(command, FT_BIT_DIR_I) : direction_bits.i,
|
||||
axis_step.j ? TEST(command, FT_BIT_DIR_J) : direction_bits.j,
|
||||
axis_step.k ? TEST(command, FT_BIT_DIR_K) : direction_bits.k,
|
||||
axis_step.u ? TEST(command, FT_BIT_DIR_U) : direction_bits.u,
|
||||
axis_step.v ? TEST(command, FT_BIT_DIR_V) : direction_bits.v,
|
||||
axis_step.w ? TEST(command, FT_BIT_DIR_W) : direction_bits.w
|
||||
);
|
||||
|
||||
// Apply directions (which will apply to the entire linear move)
|
||||
LOGICAL_AXIS_CODE(
|
||||
E_APPLY_DIR(last_direction_bits.e, false),
|
||||
X_APPLY_DIR(last_direction_bits.x, false), Y_APPLY_DIR(last_direction_bits.y, false), Z_APPLY_DIR(last_direction_bits.z, false),
|
||||
I_APPLY_DIR(last_direction_bits.i, false), J_APPLY_DIR(last_direction_bits.j, false), K_APPLY_DIR(last_direction_bits.k, false),
|
||||
U_APPLY_DIR(last_direction_bits.u, false), V_APPLY_DIR(last_direction_bits.v, false), W_APPLY_DIR(last_direction_bits.w, false)
|
||||
E_APPLY_DIR(direction_bits.e, false),
|
||||
X_APPLY_DIR(direction_bits.x, false), Y_APPLY_DIR(direction_bits.y, false), Z_APPLY_DIR(direction_bits.z, false),
|
||||
I_APPLY_DIR(direction_bits.i, false), J_APPLY_DIR(direction_bits.j, false), K_APPLY_DIR(direction_bits.k, false),
|
||||
U_APPLY_DIR(direction_bits.u, false), V_APPLY_DIR(direction_bits.v, false), W_APPLY_DIR(direction_bits.w, false)
|
||||
);
|
||||
|
||||
DIR_WAIT_AFTER();
|
||||
/**
|
||||
* Update direction bits for steppers that were stepped by this command.
|
||||
* HX, HY, HZ direction bits were set for Core kinematics
|
||||
* when the block was fetched and are not overwritten here.
|
||||
*/
|
||||
|
||||
// Start a step pulse
|
||||
LOGICAL_AXIS_CODE(
|
||||
E_APPLY_STEP(axis_did_move.e, false),
|
||||
X_APPLY_STEP(axis_did_move.x, false), Y_APPLY_STEP(axis_did_move.y, false), Z_APPLY_STEP(axis_did_move.z, false),
|
||||
I_APPLY_STEP(axis_did_move.i, false), J_APPLY_STEP(axis_did_move.j, false), K_APPLY_STEP(axis_did_move.k, false),
|
||||
U_APPLY_STEP(axis_did_move.u, false), V_APPLY_STEP(axis_did_move.v, false), W_APPLY_STEP(axis_did_move.w, false)
|
||||
E_APPLY_STEP(axis_step.e, false),
|
||||
X_APPLY_STEP(axis_step.x, false), Y_APPLY_STEP(axis_step.y, false), Z_APPLY_STEP(axis_step.z, false),
|
||||
I_APPLY_STEP(axis_step.i, false), J_APPLY_STEP(axis_step.j, false), K_APPLY_STEP(axis_step.k, false),
|
||||
U_APPLY_STEP(axis_step.u, false), V_APPLY_STEP(axis_step.v, false), W_APPLY_STEP(axis_step.w, false)
|
||||
);
|
||||
|
||||
if (TERN1(FTM_OPTIMIZE_DIR_STATES, last_set_direction != last_direction_bits)) {
|
||||
// Apply directions (generally applying to the entire linear move)
|
||||
#define _FTM_APPLY_DIR(AXIS) if (TERN1(FTM_OPTIMIZE_DIR_STATES, last_direction_bits[_AXIS(A)] != last_set_direction[_AXIS(AXIS)])) \
|
||||
SET_STEP_DIR(AXIS);
|
||||
LOGICAL_AXIS_MAP(_FTM_APPLY_DIR);
|
||||
|
||||
TERN_(FTM_OPTIMIZE_DIR_STATES, last_set_direction = last_direction_bits);
|
||||
|
||||
// Any DIR change requires a wait period
|
||||
DIR_WAIT_AFTER();
|
||||
}
|
||||
|
||||
// Start step pulses. Edge stepping will toggle the STEP pin.
|
||||
#define _FTM_STEP_START(AXIS) AXIS##_APPLY_STEP(_FTM_STEP(AXIS), false);
|
||||
LOGICAL_AXIS_MAP(_FTM_STEP_START);
|
||||
|
||||
// Apply steps via I2S
|
||||
TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
|
||||
|
||||
// Begin waiting for the minimum pulse duration
|
||||
START_TIMED_PULSE();
|
||||
|
||||
// Update step counts
|
||||
LOGICAL_AXIS_CODE(
|
||||
if (axis_did_move.e) count_position.e += last_direction_bits.e ? 1 : -1, if (axis_did_move.x) count_position.x += last_direction_bits.x ? 1 : -1,
|
||||
if (axis_did_move.y) count_position.y += last_direction_bits.y ? 1 : -1, if (axis_did_move.z) count_position.z += last_direction_bits.z ? 1 : -1,
|
||||
if (axis_did_move.i) count_position.i += last_direction_bits.i ? 1 : -1, if (axis_did_move.j) count_position.j += last_direction_bits.j ? 1 : -1,
|
||||
if (axis_did_move.k) count_position.k += last_direction_bits.k ? 1 : -1, if (axis_did_move.u) count_position.u += last_direction_bits.u ? 1 : -1,
|
||||
if (axis_did_move.v) count_position.v += last_direction_bits.v ? 1 : -1, if (axis_did_move.w) count_position.w += last_direction_bits.w ? 1 : -1
|
||||
);
|
||||
#define _FTM_STEP_COUNT(AXIS) if (axis_step[_AXIS(AXIS)]) count_position[_AXIS(AXIS)] += direction_bits[_AXIS(AXIS)] ? 1 : -1;
|
||||
LOGICAL_AXIS_MAP(_FTM_STEP_COUNT);
|
||||
|
||||
// Provide EDGE flags for E stepper(s)
|
||||
#if HAS_EXTRUDERS
|
||||
#if ENABLED(E_DUAL_STEPPER_DRIVERS)
|
||||
constexpr bool e_axis_has_dedge = AXIS_HAS_DEDGE(E0) && AXIS_HAS_DEDGE(E1);
|
||||
@@ -3541,38 +3603,32 @@ void Stepper::report_positions() {
|
||||
|
||||
// Only wait for axes without edge stepping
|
||||
const bool any_wait = false LOGICAL_AXIS_GANG(
|
||||
|| (!e_axis_has_dedge && axis_did_move.e),
|
||||
|| (!AXIS_HAS_DEDGE(X) && axis_did_move.x), || (!AXIS_HAS_DEDGE(Y) && axis_did_move.y), || (!AXIS_HAS_DEDGE(Z) && axis_did_move.z),
|
||||
|| (!AXIS_HAS_DEDGE(I) && axis_did_move.i), || (!AXIS_HAS_DEDGE(J) && axis_did_move.j), || (!AXIS_HAS_DEDGE(K) && axis_did_move.k),
|
||||
|| (!AXIS_HAS_DEDGE(U) && axis_did_move.u), || (!AXIS_HAS_DEDGE(V) && axis_did_move.v), || (!AXIS_HAS_DEDGE(W) && axis_did_move.w)
|
||||
|| (!e_axis_has_dedge && axis_step.e),
|
||||
|| (!AXIS_HAS_DEDGE(X) && axis_step.x), || (!AXIS_HAS_DEDGE(Y) && axis_step.y), || (!AXIS_HAS_DEDGE(Z) && axis_step.z),
|
||||
|| (!AXIS_HAS_DEDGE(I) && axis_step.i), || (!AXIS_HAS_DEDGE(J) && axis_step.j), || (!AXIS_HAS_DEDGE(K) && axis_step.k),
|
||||
|| (!AXIS_HAS_DEDGE(U) && axis_step.u), || (!AXIS_HAS_DEDGE(V) && axis_step.v), || (!AXIS_HAS_DEDGE(W) && axis_step.w)
|
||||
);
|
||||
|
||||
// Allow pulses to be registered by stepper drivers
|
||||
if (any_wait) AWAIT_HIGH_PULSE();
|
||||
|
||||
// Stop pulses. Axes with DEDGE will do nothing, assuming STEP_STATE_* is HIGH
|
||||
LOGICAL_AXIS_CODE(
|
||||
E_APPLY_STEP(!STEP_STATE_E, false),
|
||||
X_APPLY_STEP(!STEP_STATE_X, false), Y_APPLY_STEP(!STEP_STATE_Y, false), Z_APPLY_STEP(!STEP_STATE_Z, false),
|
||||
I_APPLY_STEP(!STEP_STATE_I, false), J_APPLY_STEP(!STEP_STATE_J, false), K_APPLY_STEP(!STEP_STATE_K, false),
|
||||
U_APPLY_STEP(!STEP_STATE_U, false), V_APPLY_STEP(!STEP_STATE_V, false), W_APPLY_STEP(!STEP_STATE_W, false)
|
||||
);
|
||||
|
||||
// Check endstops on every step
|
||||
IF_DISABLED(ENDSTOP_INTERRUPTS_FEATURE, endstops.update());
|
||||
#define _FTM_STEP_STOP(AXIS) AXIS##_APPLY_STEP(!STEP_STATE_##AXIS, false);
|
||||
LOGICAL_AXIS_MAP(_FTM_STEP_STOP);
|
||||
|
||||
// Also handle babystepping here
|
||||
TERN_(BABYSTEPPING, if (babystep.has_steps()) babystepping_isr());
|
||||
|
||||
} // Stepper::ftMotion_stepper
|
||||
|
||||
// Called from FTMotion::loop (when !blockProcRdy) which is called from Marlin idle()
|
||||
void Stepper::ftMotion_blockQueueUpdate() {
|
||||
|
||||
if (current_block) {
|
||||
// If the current block is not done processing, return right away
|
||||
// If the current block is not done processing, return right away.
|
||||
// A block is done processing when the command buffer has been
|
||||
// filled, not necessarily when it's done running.
|
||||
if (!ftMotion.getBlockProcDn()) return;
|
||||
|
||||
axis_did_move.reset();
|
||||
planner.release_current_block();
|
||||
}
|
||||
|
||||
@@ -3580,10 +3636,37 @@ void Stepper::report_positions() {
|
||||
current_block = planner.get_current_block();
|
||||
|
||||
if (current_block) {
|
||||
// Sync block? Sync the stepper counts and return
|
||||
while (current_block->is_sync()) {
|
||||
TERN_(LASER_FEATURE, if (!(current_block->is_fan_sync() || current_block->is_pwr_sync()))) _set_position(current_block->position);
|
||||
|
||||
// Sync position, fan power, laser power?
|
||||
while (current_block->is_sync()) {
|
||||
|
||||
#if 0
|
||||
|
||||
// TODO: Implement compatible sync blocks with FT Motion commands,
|
||||
// perhaps by setting a FT_BIT_SYNC flag that holds the current block
|
||||
// until it is processed by ftMotion_stepper
|
||||
|
||||
// Set laser power
|
||||
#if ENABLED(LASER_POWER_SYNC)
|
||||
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
|
||||
if (current_block->is_sync_pwr()) {
|
||||
planner.laser_inline.status.isSyncPower = true;
|
||||
cutter.apply_power(current_block->laser.power);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set "fan speeds" for a laser module
|
||||
#if ENABLED(LASER_SYNCHRONOUS_M106_M107)
|
||||
if (current_block->is_sync_fan()) planner.sync_fan_speeds(current_block->fan_speed);
|
||||
#endif
|
||||
|
||||
// Set position
|
||||
if (current_block->is_sync_pos()) _set_position(current_block->position);
|
||||
|
||||
#endif
|
||||
|
||||
// Done with this block
|
||||
planner.release_current_block();
|
||||
|
||||
// Try to get a new block
|
||||
@@ -3591,6 +3674,17 @@ void Stepper::report_positions() {
|
||||
return; // No queued blocks.
|
||||
}
|
||||
|
||||
// Some kinematics track axis motion in HX, HY, HZ
|
||||
#if ANY(CORE_IS_XY, CORE_IS_XZ, MARKFORGED_XY, MARKFORGED_YX)
|
||||
last_direction_bits.hx = current_block->direction_bits.hx;
|
||||
#endif
|
||||
#if ANY(CORE_IS_XY, CORE_IS_YZ, MARKFORGED_XY, MARKFORGED_YX)
|
||||
last_direction_bits.hy = current_block->direction_bits.hy;
|
||||
#endif
|
||||
#if ANY(CORE_IS_XZ, CORE_IS_YZ)
|
||||
last_direction_bits.hz = current_block->direction_bits.hz;
|
||||
#endif
|
||||
|
||||
ftMotion.startBlockProc();
|
||||
return;
|
||||
}
|
||||
@@ -3809,7 +3903,7 @@ void Stepper::report_positions() {
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
case 1:
|
||||
#endif
|
||||
#if ANY_PIN(MOTOR_CURRENT_PWM_E, MOTOR_CURRENT_PWM_E0, MOTOR_CURRENT_PWM_E1)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
case 2:
|
||||
#endif
|
||||
set_digipot_current(i, motor_current_setting[i]);
|
||||
|
||||
@@ -684,6 +684,9 @@ class Stepper {
|
||||
// Calculate timing interval and steps-per-ISR for the given step rate
|
||||
static hal_timer_t calc_multistep_timer_interval(uint32_t step_rate);
|
||||
|
||||
// Evaluate axis motions and set bits in axis_did_move
|
||||
static void set_axis_moved_for_current_block();
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
static void calc_nonlinear_e(uint32_t step_rate);
|
||||
#endif
|
||||
|
||||
@@ -806,7 +806,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
}
|
||||
}
|
||||
SHV((bias + d) >> 1);
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PID_CYCLE), cycles, ncycles));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PID_CYCLE), cycles, ncycles));
|
||||
cycles++;
|
||||
minT = target;
|
||||
}
|
||||
@@ -1195,7 +1195,7 @@ volatile bool Temperature::raw_temps_ready = false;
|
||||
|
||||
// Determine ambient temperature.
|
||||
SERIAL_ECHOLNPGM(STR_MPC_COOLING_TO_AMBIENT);
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onMPCTuning(ExtUI::mpcresult_t::MPCTEMP_START));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onMPCTuning(ExtUI::mpcresult_t::MPC_STARTED));
|
||||
TERN(DWIN_LCD_PROUI, LCD_ALERTMESSAGE(MSG_MPC_COOLING_TO_AMBIENT), LCD_MESSAGE(MSG_COOLING));
|
||||
|
||||
if (tuner.measure_ambient_temp() != MPC_autotuner::MeasurementState::SUCCESS) return;
|
||||
@@ -2019,7 +2019,7 @@ void Temperature::mintemp_error(const heater_id_t heater_id OPTARG(ERR_INCLUDE_T
|
||||
if (watch_cooler.elapsed(ms)) { // Time to check the cooler?
|
||||
const auto deg = degCooler();
|
||||
if (deg > watch_cooler.target) // Failed to decrease enough?
|
||||
_TEMP_ERROR(H_COOLER, GET_EN_TEXT_F(MSG_ERR_COOLING_FAILED), MSG_ERR_COOLING_FAILED, deg);
|
||||
_TEMP_ERROR(H_COOLER, GET_TEXT_F(MSG_ERR_COOLING_FAILED), MSG_ERR_COOLING_FAILED, deg);
|
||||
else
|
||||
start_watching_cooler(); // Start again if the target is still far off
|
||||
}
|
||||
@@ -4419,6 +4419,7 @@ void Temperature::isr() {
|
||||
#if ENABLED(AUTO_REPORT_TEMPERATURES)
|
||||
AutoReporter<Temperature::AutoReportTemp> Temperature::auto_reporter;
|
||||
void Temperature::AutoReportTemp::report() {
|
||||
if (wait_for_heatup) return;
|
||||
print_heater_states(active_extruder OPTARG(HAS_TEMP_REDUNDANT, ENABLED(AUTO_REPORT_REDUNDANT)));
|
||||
SERIAL_EOL();
|
||||
}
|
||||
@@ -4433,7 +4434,7 @@ void Temperature::isr() {
|
||||
#else
|
||||
F("E1 " S_FMT)
|
||||
#endif
|
||||
, heating ? GET_TEXT(MSG_HEATING) : GET_TEXT(MSG_COOLING)
|
||||
, heating ? GET_TEXT_F(MSG_HEATING) : GET_TEXT_F(MSG_COOLING)
|
||||
);
|
||||
|
||||
if (isM104) {
|
||||
|
||||
@@ -204,31 +204,35 @@ typedef struct { float p, i, d, c, f; } raw_pidcf_t;
|
||||
|
||||
float get_pid_output(const float target, const float current) {
|
||||
const float pid_error = target - current;
|
||||
float output_pow;
|
||||
if (!target || pid_error < -(PID_FUNCTIONAL_RANGE)) {
|
||||
pid_reset = true;
|
||||
return 0;
|
||||
output_pow = 0;
|
||||
}
|
||||
else if (pid_error > PID_FUNCTIONAL_RANGE) {
|
||||
pid_reset = true;
|
||||
return MAX_POW;
|
||||
output_pow = MAX_POW;
|
||||
}
|
||||
else {
|
||||
if (pid_reset) {
|
||||
pid_reset = false;
|
||||
temp_iState = 0.0;
|
||||
work_d = 0.0;
|
||||
}
|
||||
|
||||
if (pid_reset) {
|
||||
pid_reset = false;
|
||||
temp_iState = 0.0;
|
||||
work_d = 0.0;
|
||||
const float max_power_over_i_gain = float(MAX_POW) / Ki - float(MIN_POW);
|
||||
temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain);
|
||||
|
||||
work_p = Kp * pid_error;
|
||||
work_i = Ki * temp_iState;
|
||||
work_d = work_d + PID_K2 * (Kd * (temp_dState - current) - work_d);
|
||||
|
||||
output_pow = constrain(work_p + work_i + work_d + float(MIN_POW), 0, MAX_POW);
|
||||
}
|
||||
|
||||
const float max_power_over_i_gain = float(MAX_POW) / Ki - float(MIN_POW);
|
||||
temp_iState = constrain(temp_iState + pid_error, 0, max_power_over_i_gain);
|
||||
|
||||
work_p = Kp * pid_error;
|
||||
work_i = Ki * temp_iState;
|
||||
work_d = work_d + PID_K2 * (Kd * (temp_dState - current) - work_d);
|
||||
|
||||
temp_dState = current;
|
||||
|
||||
return constrain(work_p + work_i + work_d + float(MIN_POW), 0, MAX_POW);
|
||||
return output_pow;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -62,6 +62,24 @@
|
||||
#define E0_SERIAL_TX_PIN PC14
|
||||
#define E0_SERIAL_RX_PIN PC14
|
||||
|
||||
// Default TMC slave addresses
|
||||
#ifndef X_SLAVE_ADDRESS
|
||||
#define X_SLAVE_ADDRESS 3
|
||||
#endif
|
||||
#ifndef Y_SLAVE_ADDRESS
|
||||
#define Y_SLAVE_ADDRESS 3
|
||||
#endif
|
||||
#ifndef Z_SLAVE_ADDRESS
|
||||
#define Z_SLAVE_ADDRESS 3
|
||||
#endif
|
||||
#ifndef E0_SLAVE_ADDRESS
|
||||
#define E0_SLAVE_ADDRESS 3
|
||||
#endif
|
||||
static_assert(X_SLAVE_ADDRESS == 3, "X_SLAVE_ADDRESS must be 3 for BOARD_SOVOL_V131.");
|
||||
static_assert(Y_SLAVE_ADDRESS == 3, "Y_SLAVE_ADDRESS must be 3 for BOARD_SOVOL_V131.");
|
||||
static_assert(Z_SLAVE_ADDRESS == 3, "Z_SLAVE_ADDRESS must be 3 for BOARD_SOVOL_V131.");
|
||||
static_assert(E0_SLAVE_ADDRESS == 3, "E0_SLAVE_ADDRESS must be 3 for BOARD_SOVOL_V131.");
|
||||
|
||||
// Reduce baud rate to improve software serial reliability
|
||||
#ifndef TMC_BAUD_RATE
|
||||
#define TMC_BAUD_RATE 19200
|
||||
|
||||
@@ -45,10 +45,13 @@
|
||||
#endif
|
||||
|
||||
//
|
||||
// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role
|
||||
// Release JTAG pins but keep SWD enabled
|
||||
// - PA15 (JTDI / USART2 RX)
|
||||
// - PB3 (JTDO / E0_DIR)
|
||||
// - PB4 (NJTRST / E0_STEP)
|
||||
//
|
||||
//#define DISABLE_DEBUG
|
||||
//#define DISABLE_JTAG
|
||||
#define DISABLE_JTAG
|
||||
|
||||
//
|
||||
// EEPROM
|
||||
|
||||
@@ -46,10 +46,13 @@
|
||||
#endif
|
||||
|
||||
//
|
||||
// Release PB4 (Y_ENABLE_PIN) from JTAG NRST role
|
||||
// Release JTAG pins but keep SWD enabled
|
||||
// - PA15 (JTDI / E0_DIR_PIN)
|
||||
// - PB3 (JTDO / E0_STEP_PIN)
|
||||
// - PB4 (NJTRST / E0_ENABLE_PIN)
|
||||
//
|
||||
//#define DISABLE_DEBUG
|
||||
//#define DISABLE_JTAG
|
||||
#define DISABLE_JTAG
|
||||
|
||||
//
|
||||
// EEPROM
|
||||
|
||||
@@ -232,9 +232,7 @@
|
||||
|
||||
#elif ENABLED(ANET_FULL_GRAPHICS_LCD)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! ANET_FULL_GRAPHICS_LCD requires wiring modifications. See 'pins_BTT_SKR_V1_3.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_V1_3", "ANET_FULL_GRAPHICS_LCD")
|
||||
|
||||
/**
|
||||
* 1. Cut the tab off the LCD connector so it can be plugged into the "EXP1" connector the other way.
|
||||
@@ -268,9 +266,7 @@
|
||||
|
||||
#elif ENABLED(WYH_L12864)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! WYH_L12864 requires wiring modifications. See 'pins_BTT_SKR_V1_3.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_V1_3", "WYH_L12864")
|
||||
|
||||
/**
|
||||
* 1. Cut the tab off the LCD connector so it can be plugged into the "EXP1" connector the other way.
|
||||
@@ -366,9 +362,7 @@
|
||||
|
||||
#elif ENABLED(MKS_TS35_V2_0)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! MKS_TS35_V2_0 requires wiring modifications. The SKR 1.3 EXP ports are rotated 180° from what the MKS_TS35_V2_0 expects. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this error.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_V1_3", "MKS_TS35_V2_0", " The SKR 1.3 EXP ports are rotated 180°.")
|
||||
|
||||
/** ------ ------
|
||||
* BEEPER | 1 2 | BTN_ENC SPI1_MISO | 1 2 | SPI1_SCK
|
||||
|
||||
@@ -296,9 +296,7 @@
|
||||
#elif HAS_WIRED_LCD
|
||||
|
||||
#if ENABLED(CTC_A10S_A13)
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! CTC_A10S_A13 requires wiring modifications. See 'pins_BTT_SKR_V1_4.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_V1_4", "CTC_A10S_A13")
|
||||
|
||||
/**
|
||||
* 1. Cut the tab off the LCD connector so it can be plugged into the "EXP1" connector the other way.
|
||||
@@ -330,9 +328,7 @@
|
||||
#define BEEPER_PIN EXP1_08_PIN
|
||||
|
||||
#elif ENABLED(ANET_FULL_GRAPHICS_LCD)
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! ANET_FULL_GRAPHICS_LCD requires wiring modifications. See 'pins_BTT_SKR_V1_4.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_V1_4", "ANET_FULL_GRAPHICS_LCD")
|
||||
|
||||
/**
|
||||
* 1. Cut the tab off the LCD connector so it can be plugged into the "EXP1" connector the other way.
|
||||
@@ -450,9 +446,7 @@
|
||||
|
||||
#elif ENABLED(MKS_TS35_V2_0)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! MKS_TS35_V2_0 requires wiring modifications. The SKR 1.4 EXP ports are rotated 180° from what the MKS_TS35_V2_0 expects. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this error.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_V1_4", "MKS_TS35_V2_0", " The SKR 1.4 EXP ports are rotated 180°.")
|
||||
|
||||
/** ------ ------
|
||||
* BEEPER | 1 2 | BTN_ENC SPI1_MISO | 1 2 | SPI1_SCK
|
||||
|
||||
@@ -211,19 +211,19 @@
|
||||
* ------ ------
|
||||
* EXP1 EXP2
|
||||
*/
|
||||
#define EXP1_01_PIN P1_31
|
||||
#define EXP1_02_PIN P1_30
|
||||
#define EXP1_03_PIN P0_18
|
||||
#define EXP1_04_PIN P0_16
|
||||
#define EXP1_05_PIN P0_15
|
||||
#define EXP1_01_PIN P1_31
|
||||
#define EXP1_02_PIN P1_30
|
||||
#define EXP1_03_PIN P0_18
|
||||
#define EXP1_04_PIN P0_16
|
||||
#define EXP1_05_PIN P0_15
|
||||
|
||||
#define EXP2_01_PIN P0_08
|
||||
#define EXP2_02_PIN P0_07
|
||||
#define EXP2_03_PIN P3_25
|
||||
#define EXP2_04_PIN P0_28
|
||||
#define EXP2_05_PIN P3_26
|
||||
#define EXP2_06_PIN P0_09
|
||||
#define EXP2_07_PIN P0_27
|
||||
#define EXP2_01_PIN P0_08
|
||||
#define EXP2_02_PIN P0_07
|
||||
#define EXP2_03_PIN P3_25
|
||||
#define EXP2_04_PIN P0_28
|
||||
#define EXP2_05_PIN P3_26
|
||||
#define EXP2_06_PIN P0_09
|
||||
#define EXP2_07_PIN P0_27
|
||||
|
||||
//
|
||||
// LCD / Controller
|
||||
|
||||
@@ -307,9 +307,7 @@
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! ZONESTAR_LCD on REARM requires wiring modifications. NB. ADCs are not 5V tolerant. See 'pins_RAMPS_RE_ARM.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("RAMPS_RE_ARM", "ZONESTAR_LCD", " ADCs are not 5V tolerant.")
|
||||
|
||||
#elif IS_TFTGLCD_PANEL
|
||||
|
||||
|
||||
@@ -218,9 +218,8 @@
|
||||
#define EXP1_08_PIN P0_18
|
||||
|
||||
#if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! Ender-3 V2 display requires a custom cable with TX = P0_15, RX = P0_16. See 'pins_BTT_SKR_E3_TURBO.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
|
||||
CONTROLLER_WARNING("BTT_SKR_E3_TURBO", "Ender-3 V2 display", " Requires a custom cable with TX = P0_15, RX = P0_16.")
|
||||
|
||||
/**
|
||||
* Ender-3 V2 display SKR E3 Turbo (EXP1) Ender-3 V2 display --> SKR E3 Turbo
|
||||
@@ -254,9 +253,7 @@
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD) // ANET A8 LCD Controller - Must convert to 3.3V - CONNECTING TO 5V WILL DAMAGE THE BOARD!
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! ZONESTAR_LCD requires wiring modifications. See 'pins_BTT_SKR_E3_TURBO.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("BTT_SKR_E3_TURBO", "ZONESTAR_LCD")
|
||||
|
||||
#define LCD_PINS_RS EXP1_06_PIN
|
||||
#define LCD_PINS_EN EXP1_02_PIN
|
||||
|
||||
@@ -123,6 +123,12 @@
|
||||
#define NOT_TARGET NONE
|
||||
#endif
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#define CONTROLLER_WARNING(PF,CN,V...) static_assert(false, "\n\nWARNING! " CN " requires wiring modification! See pins_" PF ".h for details." V "\n (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)\n\n");
|
||||
#else
|
||||
#define CONTROLLER_WARNING(...)
|
||||
#endif
|
||||
|
||||
//
|
||||
// RAMPS 1.3 / 1.4 / 1.6+ - ATmega1280, ATmega2560
|
||||
//
|
||||
@@ -1071,3 +1077,6 @@
|
||||
// Post-process pins according to configured settings
|
||||
//
|
||||
#include "pins_postprocess.h"
|
||||
|
||||
// Cleanup
|
||||
#undef CONTROLLER_WARNING
|
||||
|
||||
@@ -1247,7 +1247,7 @@
|
||||
#define J_STEP_PIN _EPIN(J_E_INDEX, STEP)
|
||||
#define J_DIR_PIN _EPIN(J_E_INDEX, DIR)
|
||||
#define J_ENABLE_PIN _EPIN(J_E_INDEX, ENABLE)
|
||||
#if I_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(J_STEP)
|
||||
#if J_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(J_STEP)
|
||||
#error "No E stepper plug left for J!"
|
||||
#else
|
||||
#define AUTO_ASSIGNED_J_STEPPER 1
|
||||
@@ -1417,7 +1417,7 @@
|
||||
#define U_STEP_PIN _EPIN(U_E_INDEX, STEP)
|
||||
#define U_DIR_PIN _EPIN(U_E_INDEX, DIR)
|
||||
#define U_ENABLE_PIN _EPIN(U_E_INDEX, ENABLE)
|
||||
#if M_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(U_STEP)
|
||||
#if U_E_INDEX >= MAX_E_STEPPERS || !PIN_EXISTS(U_STEP)
|
||||
#error "No E stepper plug left for U!"
|
||||
#else
|
||||
#define AUTO_ASSIGNED_U_STEPPER 1
|
||||
@@ -1736,3 +1736,43 @@
|
||||
#define NEOPIXEL_PIN BOARD_NEOPIXEL_PIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Undefine motor PWM pins for nonexistent axes since the existence of a MOTOR_CURRENT_PWM_*_PIN implies its standard use.
|
||||
// TODO: Allow remapping (e.g., E => Z2). Spec G-codes to use logical axis with index (e.g., to set Z2: Mxxx Z P1 Snnn).
|
||||
#if !HAS_X_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_X_PIN
|
||||
#endif
|
||||
#if !HAS_Y_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_Y_PIN
|
||||
#endif
|
||||
#if !HAS_X_AXIS && !HAS_Y_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_XY_PIN
|
||||
#endif
|
||||
#if !HAS_Z_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_Z_PIN
|
||||
#endif
|
||||
#if !HAS_I_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_I_PIN
|
||||
#endif
|
||||
#if !HAS_J_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_J_PIN
|
||||
#endif
|
||||
#if !HAS_K_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_K_PIN
|
||||
#endif
|
||||
#if !HAS_U_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_U_PIN
|
||||
#endif
|
||||
#if !HAS_V_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_V_PIN
|
||||
#endif
|
||||
#if !HAS_W_AXIS
|
||||
#undef MOTOR_CURRENT_PWM_W_PIN
|
||||
#endif
|
||||
#if !HAS_EXTRUDERS
|
||||
#undef MOTOR_CURRENT_PWM_E_PIN
|
||||
#undef MOTOR_CURRENT_PWM_E0_PIN // Archim 1.0
|
||||
#undef MOTOR_CURRENT_PWM_E1_PIN // Kept in sync with E0
|
||||
#elif !HAS_MULTI_EXTRUDER
|
||||
#undef MOTOR_CURRENT_PWM_E1_PIN
|
||||
#endif
|
||||
|
||||
@@ -320,17 +320,29 @@
|
||||
#endif
|
||||
|
||||
//
|
||||
// TMC software SPI
|
||||
// TMC SPI
|
||||
//
|
||||
#if HAS_TMC_SPI
|
||||
#ifndef TMC_SPI_MOSI
|
||||
#define TMC_SPI_MOSI AUX2_09
|
||||
#endif
|
||||
#ifndef TMC_SPI_MISO
|
||||
#define TMC_SPI_MISO AUX2_07
|
||||
#endif
|
||||
#ifndef TMC_SPI_SCK
|
||||
#define TMC_SPI_SCK AUX2_05
|
||||
#if ENABLED(TMC_USE_SW_SPI)
|
||||
#ifndef TMC_SPI_MOSI
|
||||
#define TMC_SPI_MOSI AUX2_09
|
||||
#endif
|
||||
#ifndef TMC_SPI_MISO
|
||||
#define TMC_SPI_MISO AUX2_07
|
||||
#endif
|
||||
#ifndef TMC_SPI_SCK
|
||||
#define TMC_SPI_SCK AUX2_05
|
||||
#endif
|
||||
#else
|
||||
#ifndef TMC_SPI_MOSI
|
||||
#define TMC_SPI_MOSI AUX3_04
|
||||
#endif
|
||||
#ifndef TMC_SPI_MISO
|
||||
#define TMC_SPI_MISO AUX3_03
|
||||
#endif
|
||||
#ifndef TMC_SPI_SCK
|
||||
#define TMC_SPI_SCK AUX3_05
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -633,9 +645,7 @@
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! ZONESTAR_LCD on RAMPS requires wiring modifications. It plugs into AUX2 but GND and 5V need to be swapped. See 'pins_RAMPS.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("RAMPS", "ZONESTAR_LCD", " Plugs into AUX2 but GND and 5V must be swapped.")
|
||||
|
||||
#define LCD_PINS_RS AUX2_05
|
||||
#define LCD_PINS_EN AUX2_07
|
||||
@@ -924,9 +934,7 @@
|
||||
|
||||
#if ALL(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! LCD_FYSETC_TFT81050 requires wiring modifications. See 'pins_RAMPS.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("RAMPS", "LCD_FYSETC_TFT81050")
|
||||
|
||||
/**
|
||||
* FYSETC TFT-81050 display pinout
|
||||
|
||||
@@ -569,9 +569,15 @@
|
||||
|
||||
#if HAS_TMC_UART
|
||||
/**
|
||||
* Address for the UART Configuration of the TMC2209. Override in Configuration files.
|
||||
* To test TMC2209 Steppers enable TMC_DEBUG in Configuration_adv.h and test the M122 command with voltage on the steppers.
|
||||
* TMC2208/TMC2209 stepper drivers
|
||||
* It seems to work perfectly fine on Software Serial, if an advanced user wants to test, you could use the SAMD51 Serial1 and Serial 2. Be careful with the Sercom configurations.
|
||||
*/
|
||||
//#define X_HARDWARE_SERIAL Serial1
|
||||
//#define Y_HARDWARE_SERIAL Serial1
|
||||
//#define Z_HARDWARE_SERIAL Serial1
|
||||
//#define E0_HARDWARE_SERIAL Serial1
|
||||
|
||||
// Default TMC slave addresses
|
||||
#ifndef X_SLAVE_ADDRESS
|
||||
#define X_SLAVE_ADDRESS 0b00
|
||||
#endif
|
||||
@@ -584,18 +590,15 @@
|
||||
#ifndef E0_SLAVE_ADDRESS
|
||||
#define E0_SLAVE_ADDRESS 0b11
|
||||
#endif
|
||||
static_assert(X_SLAVE_ADDRESS == 0b00, "X_SLAVE_ADDRESS must be 0b00 for BOARD_BRICOLEMON_LITE_V1_0.");
|
||||
static_assert(Y_SLAVE_ADDRESS == 0b01, "Y_SLAVE_ADDRESS must be 0b01 for BOARD_BRICOLEMON_LITE_V1_0.");
|
||||
static_assert(Z_SLAVE_ADDRESS == 0b10, "Z_SLAVE_ADDRESS must be 0b10 for BOARD_BRICOLEMON_LITE_V1_0.");
|
||||
static_assert(E0_SLAVE_ADDRESS == 0b11, "E0_SLAVE_ADDRESS must be 0b11 for BOARD_BRICOLEMON_LITE_V1_0.");
|
||||
|
||||
/**
|
||||
* TMC2208/TMC2209 stepper drivers
|
||||
* It seems to work perfectly fine on Software Serial, if an advanced user wants to test, you could use the SAMD51 Serial1 and Serial 2. Be careful with the Sercom configurations.
|
||||
*/
|
||||
//#define X_HARDWARE_SERIAL Serial1
|
||||
//#define Y_HARDWARE_SERIAL Serial1
|
||||
//#define Z_HARDWARE_SERIAL Serial1
|
||||
//#define E0_HARDWARE_SERIAL Serial1
|
||||
|
||||
// This is the stable default value after testing, but, higher UART rates could be configured, remeber to test the Steppers with the M122 command to check if everything works.
|
||||
#define TMC_BAUD_RATE 250000
|
||||
// Reduce baud rate to improve software serial reliability
|
||||
#ifndef TMC_BAUD_RATE
|
||||
#define TMC_BAUD_RATE 19200 // 250000
|
||||
#endif
|
||||
|
||||
//
|
||||
// Software serial
|
||||
|
||||
@@ -620,11 +620,19 @@
|
||||
#endif
|
||||
|
||||
#if HAS_TMC_UART
|
||||
|
||||
/**
|
||||
* Address for the UART Configuration of the TMC2209. Override in Configuration files.
|
||||
* To test TMC2209 Steppers enable TMC_DEBUG in Configuration_adv.h and test the M122 command with voltage on the steppers.
|
||||
* TMC2208/TMC2209 stepper drivers
|
||||
* It seems to work perfectly fine on Software Serial, if an advanced user wants to test, you could use the SAMD51 Serial1 and Serial 2. Be careful with the Sercom configurations.
|
||||
* Steppers 1,2,3,4 (X,Y,Z,E0) are on the Serial1, Sercom (RX = 0, TX = 1), extra stepper 5 (E1 or any axis you want) is on Serial2, Sercom (RX = 17, TX = 16)
|
||||
*/
|
||||
|
||||
//#define X_HARDWARE_SERIAL Serial1
|
||||
//#define Y_HARDWARE_SERIAL Serial1
|
||||
//#define Z_HARDWARE_SERIAL Serial1
|
||||
//#define E0_HARDWARE_SERIAL Serial1
|
||||
//#define E1_HARDWARE_SERIAL Serial2
|
||||
|
||||
// Default TMC slave addresses
|
||||
#ifndef X_SLAVE_ADDRESS
|
||||
#define X_SLAVE_ADDRESS 0b00
|
||||
#endif
|
||||
@@ -640,20 +648,16 @@
|
||||
#ifndef E1_SLAVE_ADDRESS
|
||||
#define E1_SLAVE_ADDRESS 0b00
|
||||
#endif
|
||||
static_assert(X_SLAVE_ADDRESS == 0b00, "X_SLAVE_ADDRESS must be 0b00 for BOARD_BRICOLEMON_V1_0.");
|
||||
static_assert(Y_SLAVE_ADDRESS == 0b01, "Y_SLAVE_ADDRESS must be 0b01 for BOARD_BRICOLEMON_V1_0.");
|
||||
static_assert(Z_SLAVE_ADDRESS == 0b10, "Z_SLAVE_ADDRESS must be 0b10 for BOARD_BRICOLEMON_V1_0.");
|
||||
static_assert(E0_SLAVE_ADDRESS == 0b11, "E0_SLAVE_ADDRESS must be 0b11 for BOARD_BRICOLEMON_V1_0.");
|
||||
static_assert(E1_SLAVE_ADDRESS == 0b00, "E1_SLAVE_ADDRESS must be 0b00 for BOARD_BRICOLEMON_V1_0.");
|
||||
|
||||
/**
|
||||
* TMC2208/TMC2209 stepper drivers
|
||||
* It seems to work perfectly fine on Software Serial, if an advanced user wants to test, you could use the SAMD51 Serial1 and Serial 2. Be careful with the Sercom configurations.
|
||||
* Steppers 1,2,3,4 (X,Y,Z,E0) are on the Serial1, Sercom (RX = 0, TX = 1), extra stepper 5 (E1 or any axis you want) is on Serial2, Sercom (RX = 17, TX = 16)
|
||||
*/
|
||||
|
||||
//#define X_HARDWARE_SERIAL Serial1
|
||||
//#define Y_HARDWARE_SERIAL Serial1
|
||||
//#define Z_HARDWARE_SERIAL Serial1
|
||||
//#define E0_HARDWARE_SERIAL Serial1
|
||||
//#define E1_HARDWARE_SERIAL Serial2
|
||||
|
||||
#define TMC_BAUD_RATE 250000
|
||||
// Reduce baud rate to improve software serial reliability
|
||||
#ifndef TMC_BAUD_RATE
|
||||
#define TMC_BAUD_RATE 19200 // 250000
|
||||
#endif
|
||||
|
||||
//
|
||||
// Software serial
|
||||
|
||||
@@ -497,11 +497,19 @@
|
||||
#define SD_DETECT_PIN 22
|
||||
|
||||
#if HAS_TMC_UART
|
||||
|
||||
/**
|
||||
* TMC2209 UART Address. Override in Configuration files.
|
||||
* To test TMC2209 Steppers enable TMC_DEBUG and test M122 with voltage on the steppers.
|
||||
* TMC2208/TMC2209 stepper drivers
|
||||
* Seems to work fine with Software Serial. If you want to test, use SAMD51 Serial1 and Serial2. Be careful with the Sercom configurations.
|
||||
* Steppers 1,2,3,4 (X,Y,Z,E0) are on Serial1, Sercom (RX=0, TX=1), extra stepper 5 (E1 or any axis you want) is on Serial2, Sercom (RX=17, TX=16)
|
||||
*/
|
||||
|
||||
//#define X_HARDWARE_SERIAL Serial1
|
||||
//#define Y_HARDWARE_SERIAL Serial1
|
||||
//#define Z_HARDWARE_SERIAL Serial1
|
||||
//#define E0_HARDWARE_SERIAL Serial1
|
||||
//#define E1_HARDWARE_SERIAL Serial2
|
||||
|
||||
// Default TMC slave addresses
|
||||
#ifndef X_SLAVE_ADDRESS
|
||||
#define X_SLAVE_ADDRESS 0b00
|
||||
#endif
|
||||
@@ -517,20 +525,16 @@
|
||||
#ifndef E1_SLAVE_ADDRESS
|
||||
#define E1_SLAVE_ADDRESS 0b00
|
||||
#endif
|
||||
static_assert(X_SLAVE_ADDRESS == 0b00, "X_SLAVE_ADDRESS must be 0b00 for BOARD_MINITRONICS20.");
|
||||
static_assert(Y_SLAVE_ADDRESS == 0b01, "Y_SLAVE_ADDRESS must be 0b01 for BOARD_MINITRONICS20.");
|
||||
static_assert(Z_SLAVE_ADDRESS == 0b10, "Z_SLAVE_ADDRESS must be 0b10 for BOARD_MINITRONICS20.");
|
||||
static_assert(E0_SLAVE_ADDRESS == 0b11, "E0_SLAVE_ADDRESS must be 0b11 for BOARD_MINITRONICS20.");
|
||||
static_assert(E1_SLAVE_ADDRESS == 0b00, "E1_SLAVE_ADDRESS must be 0b00 for BOARD_MINITRONICS20.");
|
||||
|
||||
/**
|
||||
* TMC2208/TMC2209 stepper drivers
|
||||
* Seems to work fine with Software Serial. If you want to test, use SAMD51 Serial1 and Serial2. Be careful with the Sercom configurations.
|
||||
* Steppers 1,2,3,4 (X,Y,Z,E0) are on Serial1, Sercom (RX=0, TX=1), extra stepper 5 (E1 or any axis you want) is on Serial2, Sercom (RX=17, TX=16)
|
||||
*/
|
||||
|
||||
//#define X_HARDWARE_SERIAL Serial1
|
||||
//#define Y_HARDWARE_SERIAL Serial1
|
||||
//#define Z_HARDWARE_SERIAL Serial1
|
||||
//#define E0_HARDWARE_SERIAL Serial1
|
||||
//#define E1_HARDWARE_SERIAL Serial2
|
||||
|
||||
#define TMC_BAUD_RATE 250000
|
||||
// Reduce baud rate to improve software serial reliability
|
||||
#ifndef TMC_BAUD_RATE
|
||||
#define TMC_BAUD_RATE 19200 // 250000
|
||||
#endif
|
||||
|
||||
//
|
||||
// Software serial
|
||||
|
||||
@@ -465,9 +465,7 @@
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! ZONESTAR_LCD on RAMPS requires wiring modifications. It plugs into AUX2 but GND and 5V need to be swapped. See 'pins_RAMPS.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("RAMPS_144", "ZONESTAR_LCD", " Plugs into AUX2 but GND and 5V must be swapped.")
|
||||
|
||||
#define LCD_PINS_RS AUX2_05
|
||||
#define LCD_PINS_EN AUX2_07
|
||||
@@ -749,9 +747,7 @@
|
||||
|
||||
#if ALL(TOUCH_UI_FTDI_EVE, LCD_FYSETC_TFT81050)
|
||||
|
||||
#ifndef NO_CONTROLLER_CUSTOM_WIRING_WARNING
|
||||
#error "CAUTION! LCD_FYSETC_TFT81050 requires wiring modifications. See 'pins_RAMPS.h' for details. (Define NO_CONTROLLER_CUSTOM_WIRING_WARNING to suppress this warning.)"
|
||||
#endif
|
||||
CONTROLLER_WARNING("RAMPS_144", "LCD_FYSETC_TFT81050")
|
||||
|
||||
/**
|
||||
* FYSETC TFT-81050 display pinout
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
#endif
|
||||
#if PIN_EXISTS(BEEPER) && (SERVO0_PIN == BEEPER_PIN || FIL_RUNOUT_PIN == BEEPER_PIN)
|
||||
#undef BEEPER_PIN
|
||||
#define BEEPER_PIN -1
|
||||
#define BEEPER_PIN -1
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user