Merge branch 'bugfix-2.1.x' into bugfix-2.1.x-April5

This commit is contained in:
Andrew 2025-09-10 00:02:10 -04:00 committed by GitHub
commit 925c6feb2e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
256 changed files with 3073 additions and 2184 deletions

View file

@ -38,7 +38,7 @@
"platformio.platformio-ide",
"marlinfirmware.auto-build",
"editorconfig.editorconfig"
],
]
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],

View file

@ -21,6 +21,7 @@ on:
branches:
- bugfix-2.1.x
- 2.1.x
- release-*
paths-ignore:
- config/**
- data/**
@ -208,13 +209,6 @@ jobs:
sudo apt-get install libsdl2-net-dev
sudo apt-get install libglm-dev
- name: Checkout Configurations
uses: actions/checkout@v4
with:
repository: MarlinFirmware/Configurations
ref: ${{ env.CONFIG_BRANCH }}
path: ConfigurationsRepo
- name: Run ${{ matrix.test-platform }} Tests
run: |
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}

View file

@ -9,14 +9,14 @@ name: CI - Validate boards.h
on:
pull_request:
branches:
- bugfix-2.1.x
- bugfix-2.1.x
paths:
- 'Marlin/src/core/boards.h'
- "Marlin/src/core/boards.h"
push:
branches:
- bugfix-2.1.x
- bugfix-2.1.x
paths:
- 'Marlin/src/core/boards.h'
- "Marlin/src/core/boards.h"
jobs:
validate_pins_files:
@ -26,23 +26,23 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out the PR
uses: actions/checkout@v4
- name: Check out the PR
uses: actions/checkout@v4
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-boards-v1
restore-keys: |
${{ runner.os }}-pip-boards-
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-validation-v1
restore-keys: |
${{ runner.os }}-pip-validation-
- name: Select Python 3.9
uses: actions/setup-python@v5
with:
python-version: '3.9'
architecture: 'x64'
- name: Select Python 3.9
uses: actions/setup-python@v5
with:
python-version: "3.9"
architecture: "x64"
- name: Validate core/boards.h
run: |
make validate-boards -j
- name: Validate core/boards.h
run: |
make validate-boards -j

40
.github/workflows/ci-validate-lines.yml vendored Normal file
View file

@ -0,0 +1,40 @@
#
# ci-validate-lines.yml
# Validate that all text files are unchanged by linesformat.py
#
name: CI - Validate Source Files
on:
pull_request:
branches:
- bugfix-2.1.x
- 2.1.x
push:
branches:
- bugfix-2.1.x
- 2.1.x
jobs:
validate_source_files:
name: Validate Source Files
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
steps:
- name: Check out the PR
uses: actions/checkout@v4
- name: Cache node_modules
uses: actions/cache@v4
with:
path: node_modules
key: ${{ runner.os }}-npm-lines-v1
restore-keys: |
${{ runner.os }}-npm-lines-
- name: Validate text file formatting
run: |
npm install --save-dev prettier
make validate-lines -j

View file

@ -8,18 +8,18 @@ name: CI - Validate Pins Files
on:
pull_request:
branches:
- bugfix-2.1.x
- 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/*/**'
- "Marlin/src/pins/*/**"
push:
branches:
- bugfix-2.1.x
- 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/*/**'
- "Marlin/src/pins/*/**"
jobs:
validate_pins_files:
@ -29,23 +29,23 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Check out the PR
uses: actions/checkout@v4
- name: Check out the PR
uses: actions/checkout@v4
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-pins-v1
restore-keys: |
${{ runner.os }}-pip-pins-
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-validation-v1
restore-keys: |
${{ runner.os }}-pip-validation-
- name: Select Python 3.9
uses: actions/setup-python@v5
with:
python-version: '3.9'
architecture: 'x64'
- 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
- name: Validate all pins files
run: |
make validate-pins -j

5
.gitignore vendored
View file

@ -31,6 +31,11 @@ out-language/
*.gen
*.sublime-workspace
# npm
node_modules/
package.json
package-lock.json
# OS
applet/
.DS_Store

10
.prettierignore Normal file
View file

@ -0,0 +1,10 @@
# Prettier Ignore file
*.min.js
web-ui/
buildroot/share/PlatformIO/boards
buildroot/share/PlatformIO/variants
*.sublime-project
*.sublime-syntax
.github
.vscode
launch.json

View file

@ -8,6 +8,7 @@ help:
@echo "Tasks for local development:"
@echo "make marlin : Build Marlin for the configured board"
@echo "make format-pins -j : Reformat all pins files (-j for parallel execution)"
@echo "make validate-lines -j : Validate line endings, fails on trailing whitespace, etc."
@echo "make validate-pins -j : Validate all pins files, fails if any require reformatting"
@echo "make validate-boards -j : Validate boards.h and pins.h for standards compliance"
@echo "make tests-single-ci : Run a single test from inside the CI"
@ -95,7 +96,7 @@ PINS := $(shell find Marlin/src/pins -mindepth 2 -name '*.h')
.PHONY: $(PINS) format-pins validate-pins
$(PINS): %:
@echo "Formatting $@"
@echo "Formatting pins $@"
@python $(SCRIPTS_DIR)/pinsformat.py $< $@
format-pins: $(PINS)
@ -104,6 +105,17 @@ 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)
.PHONY: format-lines validate-lines
format-lines:
@echo "Formatting all sources"
@python $(SCRIPTS_DIR)/linesformat.py buildroot
@python $(SCRIPTS_DIR)/linesformat.py Marlin
validate-lines:
@echo "Validating text formatting"
@npx prettier --check . --editorconfig --object-wrap preserve
BOARDS_FILE := Marlin/src/core/boards.h
.PHONY: validate-boards

View file

@ -148,9 +148,9 @@
* Options: A4988, A5984, DRV8825, LV8729, TB6560, TB6600, TMC2100,
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
* TMC2240, TMC2240_STANDALONE, TMC2660, TMC2660_STANDALONE,
* TMC2240, TMC2660, TMC2660_STANDALONE,
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2240', 'TMC2240_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2240', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
*/
#define X_DRIVER_TYPE A4988
#define Y_DRIVER_TYPE A4988
@ -735,7 +735,12 @@
//#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
#define MPC_MAX 255 // (0..255) Current to nozzle while MPC is active.
#define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers.
#define MPC_HEATER_POWER { 40.0f } // (W) Nominal heat cartridge powers.
//#define MPC_PTC // Hotend power changes with temperature (e.g., PTC heat cartridges).
#if ENABLED(MPC_PTC)
#define MPC_HEATER_ALPHA { 0.0028f } // Temperature coefficient of resistance of the heat cartridges.
#define MPC_HEATER_REFTEMP { 20 } // (°C) Reference temperature for MPC_HEATER_POWER and MPC_HEATER_ALPHA.
#endif
#define MPC_INCLUDE_FAN // Model the fan speed?
@ -805,8 +810,8 @@
// 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_bedKp 10.00
#define DEFAULT_bedKi .023
#define DEFAULT_bedKp 10.00
#define DEFAULT_bedKi 0.023
#define DEFAULT_bedKd 305.4
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
@ -3113,7 +3118,7 @@
//
// FYSETC variant of the MINI12864 graphic controller with SD support
// https://wiki.fysetc.com/Mini12864_Panel/
// https://wiki.fysetc.com/docs/Mini12864Panel
//
//#define FYSETC_MINI_12864_X_X // Type C/D/E/F. No tunable RGB Backlight by default
//#define FYSETC_MINI_12864_1_2 // Type C/D/E/F. Simple RGB Backlight (always on)
@ -3509,6 +3514,11 @@
//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation)
//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation)
#if ENABLED(DWIN_CREALITY_LCD)
//#define USE_STRING_HEADINGS // Use string headings for Creality UI instead of images
//#define USE_STRING_TITLES // Use string titles for Creality UI instead of images
#endif
//
// Touch Screen Settings
//

View file

@ -1081,11 +1081,26 @@
#define G34_MAX_GRADE 5 // (%) Maximum incline that G34 will handle
#define Z_STEPPER_ALIGN_ITERATIONS 5 // Number of iterations to apply during alignment
#define Z_STEPPER_ALIGN_ACC 0.02 // Stop iterating early if the accuracy is better than this
#define RESTORE_LEVELING_AFTER_G34 // Restore leveling after G34 is done?
// After G34, re-home Z (G28 Z) or just calculate it from the last probe heights?
// Re-homing might be more precise in reproducing the actual 'G28 Z' homing height, especially on an uneven bed.
#define HOME_AFTER_G34
#endif
/**
* Commands to execute at the start of G34 probing,
* after switching to the PROBING_TOOL.
*/
//#define EVENT_GCODE_BEFORE_G34 "M300 P440 S200"
/**
* Commands to execute at the end of G34 probing.
* Useful to retract or move the Z probe out of the way.
*/
//#define EVENT_GCODE_AFTER_G34 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10"
#endif // Z_STEPPER_AUTO_ALIGN
/**
* Assisted Tramming
@ -1188,7 +1203,7 @@
// ZVD, MZV : FTM_RATIO
// 2HEI : FTM_RATIO * 3 / 2
// 3HEI : FTM_RATIO * 2
#endif
#endif // FT_MOTION
/**
* Input Shaping
@ -1394,7 +1409,7 @@
* Multi-stepping sends steps in bursts to reduce MCU usage for high step-rates.
* This allows higher feedrates than the MCU could otherwise support.
*/
#define MULTISTEPPING_LIMIT 16 //: [1, 2, 4, 8, 16, 32, 64, 128]
#define MULTISTEPPING_LIMIT 16 // :[1, 2, 4, 8, 16, 32, 64, 128]
/**
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
@ -3031,12 +3046,11 @@
#define INTERPOLATE true
#if HAS_DRIVER(TMC2240)
#define TMC2240_CURRENT_RANGE 1 // RMS: { 0:'690mA', 1:'1410mA', 2:'2120mA', 3:'2110mA' }
// PEAK:{ 0:'1A', 1:'2A', 2:'3A', 3:'3A' }
// Determines max current. Lower is more internal current resolution. Higher runs cooler.
#define TMC2240_Rref 12000 // ('rref', 12000, minval=12000, maxval=60000)
#define TMC2240_SLOPE_CONTROL 0 // :{ 0:'100V/us', 1:'200V/us', 2:'400V/us', 3:'800V/us' }
// Lower is more silent. Higher runs cooler.
#define TMC2240_RREF 12000 // (Ω) 12000 .. 60000. (FLY TMC2240 = 12300)
// Max Current. Lower for more internal resolution. Raise to run cooler.
#define TMC2240_CURRENT_RANGE 1 // :{ 0:'RMS=690mA PEAK=1A', 1:'RMS=1410mA PEAK=2A', 2:'RMS=2120mA PEAK=3A', 3:'RMS=2110mA PEAK=3A' }
// Slope Control: Lower is more silent. Higher runs cooler.
#define TMC2240_SLOPE_CONTROL 0 // :{ 0:'100V/µs', 1:'200V/µs', 2:'400V/µs', 3:'800V/µs' }
#endif
#if AXIS_IS_TMC_CONFIG(X)
@ -3467,7 +3481,7 @@
* X/Y/Z_STALL_SENSITIVITY is the default stall threshold.
* Use M914 X Y Z to set the stall threshold at runtime:
*
* Sensitivity TMC2209/2240 Others
* Sensitivity TMC2209 Others
* HIGHEST 255 -64 (Too sensitive => False positive)
* LOWEST 0 63 (Too insensitive => No trigger)
*
@ -3486,7 +3500,7 @@
//#define SENSORLESS_HOMING // StallGuard capable drivers only
#if ANY(SENSORLESS_HOMING, SENSORLESS_PROBING)
// TMC2209/2240: 0...255. TMC2130: -64...63
// TMC2209: 0...255. TMC2130: -64...63
#define X_STALL_SENSITIVITY 8
#define X2_STALL_SENSITIVITY X_STALL_SENSITIVITY
#define Y_STALL_SENSITIVITY 8
@ -3503,6 +3517,7 @@
//#define W_STALL_SENSITIVITY 8
//#define SPI_ENDSTOPS // TMC2130, TMC2240, and TMC5160
//#define IMPROVE_HOMING_RELIABILITY
//#define SENSORLESS_STALLGUARD_DELAY 0 // (ms) Delay to allow drivers to settle
#endif
// @section tmc/config
@ -3990,7 +4005,7 @@
#endif
/**
* M115 - Report capabilites. Disable to save ~1150 bytes of flash.
* M115 - Report capabilities. Disable to save ~1150 bytes of flash.
* Some hosts (and serial TFT displays) rely on this feature.
*/
#define CAPABILITIES_REPORT

View file

@ -338,7 +338,8 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1164)
else ifeq ($(HARDWARE_MOTHERBOARD),1165)
# XTLW MFF V2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1166)
# E3D Rumba BigBox
else ifeq ($(HARDWARE_MOTHERBOARD),1167)
#
# RAMBo and derivatives

View file

@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2025-06-05"
//#define STRING_DISTRIBUTION_DATE "2025-09-09"
/**
* The protocol for communication to the host. Protocol indicates communication

View file

@ -229,7 +229,7 @@ usb_iface_desc_t UDC_DESC_STORAGE *udc_get_interface_desc(void);
* - USB Device Controller (UDC) provides USB chapter 9 compliance
* - USB Device Interface (UDI) provides USB Class compliance
* - USB Device Driver (UDD) provides USB Driver for each Atmel MCU
*
* Many USB Device applications can be implemented on Atmel MCU.
* Atmel provides many application notes for different applications:
* - AVR4900, provides general information about Device Stack

View file

@ -523,7 +523,7 @@ static bool udd_ep_interrupt(void);
* \internal
* \brief Function called by UOTGHS interrupt to manage USB Device interrupts
*
* USB Device interrupt events are splited in three parts:
* USB Device interrupt events are split in three parts:
* - USB line events (SOF, reset, suspend, resume, wakeup)
* - control endpoint events (setup reception, end of data transfer, underflow, overflow, stall)
* - bulk/interrupt/isochronous endpoints events (end of data transfer)
@ -1567,7 +1567,7 @@ static void udd_ctrl_out_received(void)
udd_ctrl_payload_buf_cnt))) {
// End of reception because it is a short packet
// Before send ZLP, call intermediate callback
// in case of data receiv generate a stall
// in case of data receive generate a stall
udd_g_ctrlreq.payload_size = udd_ctrl_payload_buf_cnt;
if (NULL != udd_g_ctrlreq.over_under_run) {
if (!udd_g_ctrlreq.over_under_run()) {
@ -1808,7 +1808,7 @@ static void udd_ep_trans_done(udd_ep_id_t ep)
}
if (ptr_job->buf_cnt != ptr_job->buf_size) {
// Need to send or receiv other data
// Need to send or receive other data
next_trans = ptr_job->buf_size - ptr_job->buf_cnt;
if (UDD_ENDPOINT_MAX_TRANS < next_trans) {

View file

@ -242,12 +242,13 @@ void MarlinHAL::adc_init() {
TERN_(HAS_TEMP_ADC_5, adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_6, adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_PROBE, adc1_set_attenuation(get_channel(TEMP_PROBE_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_BOARD, adc1_set_attenuation(get_channel(TEMP_BOARD_PIN), ADC_ATTEN_11db));
TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_PROBE, adc1_set_attenuation(get_channel(TEMP_PROBE_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_ADC_BOARD, adc1_set_attenuation(get_channel(TEMP_BOARD_PIN), ADC_ATTEN_11db));
TERN_(HAS_FILWIDTH_ADC, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
TERN_(HAS_FILWIDTH2_ADC, adc1_set_attenuation(get_channel(FILWIDTH2_PIN), ADC_ATTEN_11db));
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
// That's why we're not setting it up here.

View file

@ -3,6 +3,7 @@
This HAL is eventually intended to act as the generic HAL for all GD32 chips using the MFL library.
Currently it supports:
* GD32F303RET6
- GD32F303RET6
Targeting the official [MFL Arduino Core](https://github.com/bnmguy/ArduinoCore_MFL).

View file

@ -73,7 +73,7 @@ public:
// Interrupt handler
void handle_interrupts();
// Varaible stored parameters
// Variable stored parameters
auto get_scr(uint16_t rca, uint32_t* scr) -> SDIO_Error_Type;
auto store_cid() -> SDIO_Error_Type;
auto store_csd() -> SDIO_Error_Type;

View file

@ -53,7 +53,7 @@ bool PersistentStore::access_start() {
int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE);
if (bytes_read < 0) return false;
for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++)
for (; bytes_read < long(MARLIN_EEPROM_SIZE); bytes_read++)
HAL_eeprom_data[bytes_read] = 0xFF;
file.close();

View file

@ -49,7 +49,7 @@ extern Timer0 step_timer;
* See https://github.com/MarlinFirmware/Marlin/pull/27099 for more information.
*
* NOTE: If the 'constexpr' requirement is ever lifted, TIMER0_BASE_FREQUENCY could
* be used instead. Tho this would probably not make any noticable difference.
* be used instead. Tho this would probably not make any noticeable difference.
*/
#define HAL_TIMER_RATE F_PCLK1

View file

@ -45,7 +45,7 @@ bool PersistentStore::access_start() {
fseek(eeprom_file, 0L, SEEK_END);
std::size_t file_size = ftell(eeprom_file);
if (file_size < MARLIN_EEPROM_SIZE) {
if (file_size < long(MARLIN_EEPROM_SIZE)) {
memset(buffer + file_size, eeprom_erase_value, MARLIN_EEPROM_SIZE - file_size);
}
else {

View file

@ -74,7 +74,7 @@ bool PersistentStore::access_start() {
if (status == CMD_SUCCESS) {
// sector is blank so nothing stored yet
for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = EEPROM_ERASE;
for (int i = 0; i < long(MARLIN_EEPROM_SIZE); i++) ram_eeprom[i] = EEPROM_ERASE;
current_slot = EEPROM_SLOTS;
}
else {
@ -82,7 +82,7 @@ bool PersistentStore::access_start() {
current_slot = first_nblank_loc / (MARLIN_EEPROM_SIZE);
uint8_t *eeprom_data = SLOT_ADDRESS(EEPROM_SECTOR, current_slot);
// load current settings
for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i];
for (int i = 0; i < long(MARLIN_EEPROM_SIZE); i++) ram_eeprom[i] = eeprom_data[i];
}
eeprom_dirty = false;

View file

@ -112,7 +112,7 @@ void MarlinHAL::reboot() { watchdog_reboot(0, 0, 1); }
void MarlinHAL::watchdog_init() {
#if DISABLED(DISABLE_WATCHDOG_INIT)
static_assert(WDT_TIMEOUT_US > 1000, "WDT Timout is too small, aborting");
static_assert(WDT_TIMEOUT_US > 1000, "WDT Timeout is too small, aborting");
watchdog_enable(WDT_TIMEOUT_US/1000, true);
#endif
}

View file

@ -176,7 +176,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
tc->COUNT32.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
//set prescaler
//the clock normally counts at the GCLK_TC frequency, but we can set it to divide that frequency to slow it down
//you can use different prescaler divisons here like TC_CTRLA_PRESCALER_DIV1 to get a different range
//you can use different prescaler divisions here like TC_CTRLA_PRESCALER_DIV1 to get a different range
tc->COUNT32.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE; //it will divide GCLK_TC frequency by 1024
//set the compare-capture register.
//The counter will count up to this value (it's a 16bit counter so we use uint16_t)

View file

@ -61,7 +61,8 @@
#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1)
#define GET_BOARD_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1)
#define GET_SOC_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1)
#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1)
#define GET_FILAMENT_WIDTH_ADC() TERN(HAS_FILWIDTH_ADC, PIN_TO_ADC(FILWIDTH_PIN), -1)
#define GET_FILAMENT2_WIDTH_ADC() TERN(HAS_FILWIDTH2_ADC, PIN_TO_ADC(FILWIDTH2_PIN), -1)
#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1)
#define GET_JOY_ADC_X() TERN(HAS_JOY_ADC_X, PIN_TO_ADC(JOY_X_PIN), -1)
#define GET_JOY_ADC_Y() TERN(HAS_JOY_ADC_Y, PIN_TO_ADC(JOY_Y_PIN), -1)
@ -77,7 +78,7 @@
|| GET_PROBE_ADC() == n \
|| GET_COOLER_ADC() == n \
|| GET_BOARD_ADC() == n || GET_SOC_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n || GET_FILAMENT2_WIDTH_ADC() == n \
|| GET_BUTTONS_ADC() == n \
|| GET_JOY_ADC_X() == n || GET_JOY_ADC_Y() == n || GET_JOY_ADC_Z() == n \
|| GET_POWERMON_ADC_CURRENT() == n || GET_POWERMON_ADC_VOLTS() == n \
@ -146,6 +147,9 @@ enum ADCIndex {
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH,
#endif
#if GET_FILAMENT2_WIDTH_ADC() == 0
FILWIDTH2,
#endif
#if GET_BUTTONS_ADC() == 0
ADC_KEY,
#endif
@ -212,6 +216,9 @@ enum ADCIndex {
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH,
#endif
#if GET_FILAMENT2_WIDTH_ADC() == 1
FILWIDTH2,
#endif
#if GET_BUTTONS_ADC() == 1
ADC_KEY,
#endif
@ -334,6 +341,9 @@ enum ADCIndex {
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH_PIN,
#endif
#if GET_FILAMENT2_WIDTH_ADC() == 0
FILWIDTH2_PIN,
#endif
#if GET_BUTTONS_ADC() == 0
ADC_KEYPAD_PIN,
#endif
@ -400,6 +410,9 @@ enum ADCIndex {
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH_PIN,
#endif
#if GET_FILAMENT2_WIDTH_ADC() == 1
FILWIDTH2_PIN,
#endif
#if GET_BUTTONS_ADC() == 1
ADC_KEYPAD_PIN,
#endif
@ -471,6 +484,9 @@ enum ADCIndex {
#if GET_FILAMENT_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
#if GET_FILAMENT2_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH2_PIN) },
#endif
#if GET_BUTTONS_ADC() == 0
{ PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
#endif
@ -543,6 +559,9 @@ enum ADCIndex {
#if GET_FILAMENT_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
#if GET_FILAMENT2_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH2_PIN) },
#endif
#if GET_BUTTONS_ADC() == 1
{ PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
#endif

View file

@ -209,7 +209,7 @@ HAL_HardwareSerial::HAL_HardwareSerial(void *peripheral) {
}
#endif
else { // else get the pins of the first peripheral occurence in PinMap
else { // else get the pins of the first peripheral occurrence in PinMap
_serial.pin_rx = pinmap_pin(peripheral, PinMap_UART_RX);
_serial.pin_tx = pinmap_pin(peripheral, PinMap_UART_TX);
}

View file

@ -3,9 +3,10 @@
This HAL is intended to act as the generic STM32 HAL for all STM32 chips (The whole F, H and L family).
Currently it supports:
* STM32F0xx
* STM32F1xx
* STM32F4xx
* STM32F7xx
- STM32F0xx
- STM32F1xx
- STM32F4xx
- STM32F7xx
Targeting the official [Arduino STM32 Core](https://github.com/stm32duino/Arduino_Core_STM32).

View file

@ -125,13 +125,13 @@ bool PersistentStore::access_start() {
}
if (current_slot == -1) {
// We didn't find anything, so we'll just initialize to empty
for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = EMPTY_UINT8;
for (int i = 0; i < long(MARLIN_EEPROM_SIZE); i++) ram_eeprom[i] = EMPTY_UINT8;
current_slot = EEPROM_SLOTS;
}
else {
// load current settings
uint8_t *eeprom_data = (uint8_t *)SLOT_ADDRESS(current_slot);
for (int i = 0; i < MARLIN_EEPROM_SIZE; i++) ram_eeprom[i] = eeprom_data[i];
for (int i = 0; i < long(MARLIN_EEPROM_SIZE); i++) ram_eeprom[i] = eeprom_data[i];
DEBUG_ECHOLNPGM("EEPROM loaded from slot ", current_slot, ".");
}
eeprom_data_written = false;

View file

@ -54,7 +54,7 @@ bool PersistentStore::access_start() {
int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE);
if (bytes_read < 0) return false;
for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++)
for (; bytes_read < long(MARLIN_EEPROM_SIZE); bytes_read++)
HAL_eeprom_data[bytes_read] = 0xFF;
file.close();
return true;

View file

@ -150,7 +150,7 @@ const XrefInfo pin_xref[] PROGMEM = {
#ifndef M43_NEVER_TOUCH
#define _M43_NEVER_TOUCH(x) WITHIN(x, 9, 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP)
#ifdef KILL_PIN
#if PIN_EXISTS(KILL)
#define M43_NEVER_TOUCH(x) m43_never_touch(x)
bool m43_never_touch(const pin_t index) {

View file

@ -49,7 +49,11 @@
#define TOUCH_INT_PIN -1
#endif
#define XPT2046_DFR_MODE 0x00
#if PIN_EXISTS(TOUCH_INT)
#define XPT2046_DFR_MODE 0x00
#else
#define XPT2046_DFR_MODE 0x01
#endif
#define XPT2046_SER_MODE 0x04
#define XPT2046_CONTROL 0x80

View file

@ -131,30 +131,31 @@ uint16_t MarlinHAL::adc_result;
#include <STM32ADC.h>
// Init the AD in continuous capture mode
// Init the ADC in continuous capture mode
void MarlinHAL::adc_init() {
static const uint8_t adc_pins[] = {
OPTITEM(HAS_TEMP_ADC_0, TEMP_0_PIN)
OPTITEM(HAS_TEMP_ADC_1, TEMP_1_PIN)
OPTITEM(HAS_TEMP_ADC_2, TEMP_2_PIN)
OPTITEM(HAS_TEMP_ADC_3, TEMP_3_PIN)
OPTITEM(HAS_TEMP_ADC_4, TEMP_4_PIN)
OPTITEM(HAS_TEMP_ADC_5, TEMP_5_PIN)
OPTITEM(HAS_TEMP_ADC_6, TEMP_6_PIN)
OPTITEM(HAS_TEMP_ADC_7, TEMP_7_PIN)
OPTITEM(HAS_HEATED_BED, TEMP_BED_PIN)
OPTITEM(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN)
OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN)
OPTITEM(HAS_TEMP_COOLER, TEMP_COOLER_PIN)
OPTITEM(HAS_TEMP_BOARD, TEMP_BOARD_PIN)
OPTITEM(HAS_TEMP_SOC, TEMP_SOC_PIN)
OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN)
OPTITEM(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN)
OPTITEM(HAS_JOY_ADC_X, JOY_X_PIN)
OPTITEM(HAS_JOY_ADC_Y, JOY_Y_PIN)
OPTITEM(HAS_JOY_ADC_Z, JOY_Z_PIN)
OPTITEM(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN)
OPTITEM(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN)
OPTITEM(HAS_TEMP_ADC_0, TEMP_0_PIN )
OPTITEM(HAS_TEMP_ADC_1, TEMP_1_PIN )
OPTITEM(HAS_TEMP_ADC_2, TEMP_2_PIN )
OPTITEM(HAS_TEMP_ADC_3, TEMP_3_PIN )
OPTITEM(HAS_TEMP_ADC_4, TEMP_4_PIN )
OPTITEM(HAS_TEMP_ADC_5, TEMP_5_PIN )
OPTITEM(HAS_TEMP_ADC_6, TEMP_6_PIN )
OPTITEM(HAS_TEMP_ADC_7, TEMP_7_PIN )
OPTITEM(HAS_TEMP_ADC_BED, TEMP_BED_PIN )
OPTITEM(HAS_TEMP_ADC_CHAMBER, TEMP_CHAMBER_PIN )
OPTITEM(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN )
OPTITEM(HAS_TEMP_ADC_COOLER, TEMP_COOLER_PIN )
OPTITEM(HAS_TEMP_ADC_BOARD, TEMP_BOARD_PIN )
OPTITEM(HAS_TEMP_ADC_SOC, TEMP_SOC_PIN )
OPTITEM(HAS_FILWIDTH_ADC, FILWIDTH_PIN )
OPTITEM(HAS_FILWIDTH2_ADC, FILWIDTH2_PIN )
OPTITEM(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN )
OPTITEM(HAS_JOY_ADC_X, JOY_X_PIN )
OPTITEM(HAS_JOY_ADC_Y, JOY_Y_PIN )
OPTITEM(HAS_JOY_ADC_Z, JOY_Z_PIN )
OPTITEM(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN)
OPTITEM(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN)
};
static STM32ADC adc(ADC1);
// Configure the ADC
@ -175,27 +176,28 @@ void MarlinHAL::adc_start(const pin_t pin) {
ADCIndex pin_index;
switch (pin) {
default: return;
_TCASE(HAS_TEMP_ADC_0, TEMP_0_PIN, TEMP_0)
_TCASE(HAS_TEMP_ADC_1, TEMP_1_PIN, TEMP_1)
_TCASE(HAS_TEMP_ADC_2, TEMP_2_PIN, TEMP_2)
_TCASE(HAS_TEMP_ADC_3, TEMP_3_PIN, TEMP_3)
_TCASE(HAS_TEMP_ADC_4, TEMP_4_PIN, TEMP_4)
_TCASE(HAS_TEMP_ADC_5, TEMP_5_PIN, TEMP_5)
_TCASE(HAS_TEMP_ADC_6, TEMP_6_PIN, TEMP_6)
_TCASE(HAS_TEMP_ADC_7, TEMP_7_PIN, TEMP_7)
_TCASE(HAS_HEATED_BED, TEMP_BED_PIN, TEMP_BED)
_TCASE(HAS_TEMP_CHAMBER, TEMP_CHAMBER_PIN, TEMP_CHAMBER)
_TCASE(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN, TEMP_PROBE)
_TCASE(HAS_TEMP_COOLER, TEMP_COOLER_PIN, TEMP_COOLER)
_TCASE(HAS_TEMP_BOARD, TEMP_BOARD_PIN, TEMP_BOARD)
_TCASE(HAS_TEMP_SOC, TEMP_SOC_PIN, TEMP_SOC)
_TCASE(HAS_JOY_ADC_X, JOY_X_PIN, JOY_X)
_TCASE(HAS_JOY_ADC_Y, JOY_Y_PIN, JOY_Y)
_TCASE(HAS_JOY_ADC_Z, JOY_Z_PIN, JOY_Z)
_TCASE(FILAMENT_WIDTH_SENSOR, FILWIDTH_PIN, FILWIDTH)
_TCASE(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN, ADC_KEY)
_TCASE(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN, POWERMON_CURRENT)
_TCASE(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN, POWERMON_VOLTAGE)
_TCASE(HAS_TEMP_ADC_0, TEMP_0_PIN, TEMP_0 )
_TCASE(HAS_TEMP_ADC_1, TEMP_1_PIN, TEMP_1 )
_TCASE(HAS_TEMP_ADC_2, TEMP_2_PIN, TEMP_2 )
_TCASE(HAS_TEMP_ADC_3, TEMP_3_PIN, TEMP_3 )
_TCASE(HAS_TEMP_ADC_4, TEMP_4_PIN, TEMP_4 )
_TCASE(HAS_TEMP_ADC_5, TEMP_5_PIN, TEMP_5 )
_TCASE(HAS_TEMP_ADC_6, TEMP_6_PIN, TEMP_6 )
_TCASE(HAS_TEMP_ADC_7, TEMP_7_PIN, TEMP_7 )
_TCASE(HAS_TEMP_ADC_BED, TEMP_BED_PIN, TEMP_BED )
_TCASE(HAS_TEMP_ADC_CHAMBER, TEMP_CHAMBER_PIN, TEMP_CHAMBER )
_TCASE(HAS_TEMP_ADC_PROBE, TEMP_PROBE_PIN, TEMP_PROBE )
_TCASE(HAS_TEMP_ADC_COOLER, TEMP_COOLER_PIN, TEMP_COOLER )
_TCASE(HAS_TEMP_ADC_BOARD, TEMP_BOARD_PIN, TEMP_BOARD )
_TCASE(HAS_TEMP_ADC_SOC, TEMP_SOC_PIN, TEMP_SOC )
_TCASE(HAS_FILWIDTH_ADC, FILWIDTH_PIN, FILWIDTH )
_TCASE(HAS_FILWIDTH2_ADC, FILWIDTH2_PIN, FILWIDTH2 )
_TCASE(HAS_ADC_BUTTONS, ADC_KEYPAD_PIN, ADC_KEY )
_TCASE(HAS_JOY_ADC_X, JOY_X_PIN, JOY_X )
_TCASE(HAS_JOY_ADC_Y, JOY_Y_PIN, JOY_Y )
_TCASE(HAS_JOY_ADC_Z, JOY_Z_PIN, JOY_Z )
_TCASE(POWER_MONITOR_CURRENT, POWER_MONITOR_CURRENT_PIN, POWERMON_CURRENT)
_TCASE(POWER_MONITOR_VOLTAGE, POWER_MONITOR_VOLTAGE_PIN, POWERMON_VOLTAGE)
}
adc_result = (adc_results[(int)pin_index] & 0xFFF) >> (12 - HAL_ADC_RESOLUTION); // shift out unused bits
}

View file

@ -612,7 +612,7 @@ void ADC_DMA_init() {
* n32g452 - end
==============================================================================*/
#define NS_PINRT(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPAIR(V); }while(0)
#define NS_PINRT(V...) do{ SERIAL_ECHO_START(); SERIAL_ECHOLNPGM(V); }while(0)
// Init the AD in continuous capture mode
void MarlinHAL::adc_init() {
@ -622,7 +622,7 @@ void MarlinHAL::adc_init() {
// GPIO settings
reg_temp = ADC_RCC_APB2PCLKEN;
reg_temp |= 0x0f; // Make PORT mouth clock
reg_temp |= 0x0F; // Make PORT mouth clock
ADC_RCC_APB2PCLKEN = reg_temp;
//reg_temp = NS_GPIOC_PL_CFG;

View file

@ -5,6 +5,7 @@ This HAL is for STM32F103 boards used with [Arduino STM32](https://github.com/ro
Currently has been tested in Malyan M200 (103CBT6), SKRmini (103RCT6), Chitu 3d (103ZET6), and various 103VET6 boards.
### Main developers:
- Victorpv
- xC000005
- thisiskeithb

View file

@ -33,12 +33,14 @@
#include <stdint.h>
#include <wirish.h>
#include "../../core/macros.h" // for PIN_EXISTS
// Number of SPI ports
#ifdef BOARD_SPI3_SCK_PIN
#if PIN_EXISTS(BOARD_SPI3_SCK)
#define BOARD_NR_SPI 3
#elif defined(BOARD_SPI2_SCK_PIN)
#elif PIN_EXISTS(BOARD_SPI2_SCK)
#define BOARD_NR_SPI 2
#elif defined(BOARD_SPI1_SCK_PIN)
#elif PIN_EXISTS(BOARD_SPI1_SCK)
#define BOARD_NR_SPI 1
#endif

View file

@ -44,7 +44,8 @@ enum ADCIndex : uint8_t {
OPTITEM(HAS_TEMP_ADC_COOLER, TEMP_COOLER )
OPTITEM(HAS_TEMP_ADC_BOARD, TEMP_BOARD )
OPTITEM(HAS_TEMP_ADC_SOC, TEMP_SOC )
OPTITEM(FILAMENT_WIDTH_SENSOR, FILWIDTH )
OPTITEM(HAS_FILWIDTH_ADC, FILWIDTH )
OPTITEM(HAS_FILWIDTH2_ADC, FILWIDTH2 )
OPTITEM(HAS_ADC_BUTTONS, ADC_KEY )
OPTITEM(HAS_JOY_ADC_X, JOY_X )
OPTITEM(HAS_JOY_ADC_Y, JOY_Y )

View file

@ -81,7 +81,7 @@ bool PersistentStore::access_finish() {
if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
const uint16_t *source = reinterpret_cast<const uint16_t*>(ram_eeprom);
for (size_t i = 0; i < MARLIN_EEPROM_SIZE; i += 2, ++source) {
for (size_t i = 0; i < long(MARLIN_EEPROM_SIZE); i += 2, ++source) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE)
ACCESS_FINISHED(false);
}

View file

@ -53,7 +53,7 @@ bool PersistentStore::access_start() {
int bytes_read = file.read(HAL_eeprom_data, MARLIN_EEPROM_SIZE);
if (bytes_read < 0) return false;
for (; bytes_read < MARLIN_EEPROM_SIZE; bytes_read++)
for (; bytes_read < long(MARLIN_EEPROM_SIZE); bytes_read++)
HAL_eeprom_data[bytes_read] = 0xFF;
file.close();
return true;

View file

@ -15,7 +15,7 @@
#include "unwinder.h"
/** The maximum number of instructions to interpet in a function.
/** The maximum number of instructions to interpret in a function.
* Unwinding will be unconditionally stopped and UNWIND_EXHAUSTED returned
* if more than this number of instructions are interpreted in a single
* function without unwinding a stack frame. This prevents infinite loops

View file

@ -39,7 +39,7 @@
#endif
#ifndef F
class __FlashStringHelper;
#define F(str) (reinterpret_cast<const __FlashStringHelper *>(PSTR(str)))
#define F(string_literal) (reinterpret_cast<const __FlashStringHelper *>(PSTR(string_literal)))
#endif
#ifndef _SFR_BYTE
#define _SFR_BYTE(n) (n)

View file

@ -152,8 +152,8 @@
#include "feature/encoder_i2c.h"
#endif
#if (HAS_TRINAMIC_CONFIG || HAS_TMC_SPI) && DISABLED(PSU_DEFAULT_OFF)
#include "feature/tmc_util.h"
#if HAS_TRINAMIC_CONFIG
#include "module/stepper/trinamic.h"
#endif
#if HAS_CUTTER
@ -483,7 +483,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
// Check if the kill button was pressed and wait to ensure the signal is not noise
// typically caused by poor insulation and grounding on LCD cables.
// Lower numbers here will increase response time and therefore safety rating.
// It is recommended to set this as low as possibe without false triggers.
// It is recommended to set this as low as possible without false triggers.
// -------------------------------------------------------------------------------
#ifndef KILL_DELAY
#define KILL_DELAY 250

View file

@ -105,32 +105,34 @@
#define BOARD_TRIGORILLA_14_11 1138 // ... Rev 1.1 (new servo pin order)
#define BOARD_RAMPS_ENDER_4 1139 // Creality: Ender-4, CR-8
#define BOARD_RAMPS_CREALITY 1140 // Creality: CR10S, CR20, CR-X
#define BOARD_DAGOMA_F5 1141 // Dagoma F5
#define BOARD_DAGOMA_D6 1142 // Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
#define BOARD_FYSETC_F6_13 1143 // FYSETC F6 1.3
#define BOARD_FYSETC_F6_14 1144 // FYSETC F6 1.4
#define BOARD_DUPLICATOR_I3_PLUS 1145 // Wanhao Duplicator i3 Plus
#define BOARD_VORON 1146 // VORON Design
#define BOARD_TRONXY_V3_1_0 1147 // Tronxy TRONXY-V3-1.0
#define BOARD_Z_BOLT_X_SERIES 1148 // Z-Bolt X Series
#define BOARD_TT_OSCAR 1149 // TT OSCAR
#define BOARD_TANGO 1150 // BIQU Tango V1
#define BOARD_MKS_GEN_L_V2 1151 // MKS GEN L V2
#define BOARD_MKS_GEN_L_V21 1152 // MKS GEN L V2.1
#define BOARD_COPYMASTER_3D 1153 // Copymaster 3D
#define BOARD_ORTUR_4 1154 // Ortur 4
#define BOARD_TENLOG_D3_HERO 1155 // Tenlog D3 Hero IDEX printer
#define BOARD_TENLOG_MB1_V23 1156 // Tenlog D3, D5, D6 IDEX Printer
#define BOARD_RAMPS_S_12_EEFB 1157 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_RAMPS_S_12_EEEB 1158 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
#define BOARD_RAMPS_S_12_EFFB 1159 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
#define BOARD_LONGER3D_LK1_PRO 1160 // Longer LK1 PRO / Alfawise U20 Pro (PRO version)
#define BOARD_LONGER3D_LKx_PRO 1161 // Longer LKx PRO / Alfawise Uxx Pro (PRO version)
#define BOARD_PXMALION_CORE_I3 1162 // Pxmalion Core I3
#define BOARD_PANOWIN_CUTLASS 1163 // Panowin Cutlass (as found in the Panowin F1)
#define BOARD_KODAMA_BARDO 1164 // Kodama Bardo V1.x (as found in the Kodama Trinus)
#define BOARD_XTLW_MFF_V1 1165 // XTLW MFF V1.0
#define BOARD_XTLW_MFF_V2 1166 // XTLW MFF V2.0
#define BOARD_CREALITY_V252 1141 // Creality CR-10 V2, CR-10 V3
#define BOARD_DAGOMA_F5 1142 // Dagoma F5
#define BOARD_DAGOMA_D6 1143 // Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
#define BOARD_FYSETC_F6_13 1144 // FYSETC F6 1.3
#define BOARD_FYSETC_F6_14 1145 // FYSETC F6 1.4
#define BOARD_DUPLICATOR_I3_PLUS 1146 // Wanhao Duplicator i3 Plus
#define BOARD_VORON 1147 // VORON Design
#define BOARD_TRONXY_V3_1_0 1148 // Tronxy TRONXY-V3-1.0
#define BOARD_Z_BOLT_X_SERIES 1149 // Z-Bolt X Series
#define BOARD_TT_OSCAR 1150 // TT OSCAR
#define BOARD_TANGO 1151 // BIQU Tango V1
#define BOARD_MKS_GEN_L_V2 1152 // MKS GEN L V2
#define BOARD_MKS_GEN_L_V21 1153 // MKS GEN L V2.1
#define BOARD_COPYMASTER_3D 1154 // Copymaster 3D
#define BOARD_ORTUR_4 1155 // Ortur 4
#define BOARD_TENLOG_D3_HERO 1156 // Tenlog D3 Hero IDEX printer
#define BOARD_TENLOG_MB1_V23 1157 // Tenlog D3, D5, D6 IDEX Printer
#define BOARD_RAMPS_S_12_EEFB 1158 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_RAMPS_S_12_EEEB 1159 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
#define BOARD_RAMPS_S_12_EFFB 1160 // Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
#define BOARD_LONGER3D_LK1_PRO 1161 // Longer LK1 PRO / Alfawise U20 Pro (PRO version)
#define BOARD_LONGER3D_LKx_PRO 1162 // Longer LKx PRO / Alfawise Uxx Pro (PRO version)
#define BOARD_PXMALION_CORE_I3 1163 // Pxmalion Core I3
#define BOARD_PANOWIN_CUTLASS 1164 // Panowin Cutlass (as found in the Panowin F1)
#define BOARD_KODAMA_BARDO 1165 // Kodama Bardo V1.x (as found in the Kodama Trinus)
#define BOARD_XTLW_MFF_V1 1166 // XTLW MFF V1.0
#define BOARD_XTLW_MFF_V2 1167 // XTLW MFF V2.0
#define BOARD_RUMBA_E3D 1168 // E3D Rumba BigBox
//
// RAMBo and derivatives

View file

@ -42,7 +42,6 @@
#define _TMC2209 0x2209A
#define _TMC2209_STANDALONE 0x2209B
#define _TMC2240 0x2240A
#define _TMC2240_STANDALONE 0x2240B
#define _TMC2660 0x2660A
#define _TMC2660_STANDALONE 0x2660B
#define _TMC5130 0x5130A
@ -108,7 +107,7 @@
#if ( HAS_DRIVER(TMC2100) \
|| HAS_DRIVER(TMC2130_STANDALONE) || HAS_DRIVER(TMC2160_STANDALONE) \
|| HAS_DRIVER(TMC2208_STANDALONE) || HAS_DRIVER(TMC2209_STANDALONE) \
|| HAS_DRIVER(TMC2240_STANDALONE) || HAS_DRIVER(TMC2660_STANDALONE) \
|| HAS_DRIVER(TMC2660_STANDALONE) \
|| HAS_DRIVER(TMC5130_STANDALONE) || HAS_DRIVER(TMC5160_STANDALONE) )
#define HAS_TRINAMIC_STANDALONE 1
#endif

View file

@ -124,9 +124,11 @@ void print_bin(uint16_t val) {
void _print_xyz(NUM_AXIS_ARGS_(const_float_t) FSTR_P const prefix) {
if (prefix) SERIAL_ECHO(prefix);
#if NUM_AXES
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k, SP_U_STR, u, SP_V_STR, v, SP_W_STR, w)
);
SERIAL_ECHOPGM_P(NUM_AXIS_PAIRED_LIST(
SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z,
SP_I_STR, i, SP_J_STR, j, SP_K_STR, k,
SP_U_STR, u, SP_V_STR, v, SP_W_STR, w
));
#endif
}

View file

@ -185,7 +185,7 @@ void SERIAL_ECHOLN(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args
// all the odd loose string elements as PROGMEM strings.
//
// Print up to 20 pairs of values. Odd elements must be literal strings.
// Print pairs of values. Odd elements must be literal strings.
#define __SEP_N(N,V...) _SEP_##N(V)
#define _SEP_N(N,V...) __SEP_N(N,V)
#define _SEP_N_REF() _SEP_N
@ -194,7 +194,7 @@ void SERIAL_ECHOLN(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args
#define _SEP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SEP_N_REF)()(TWO_ARGS(V),V);
#define SERIAL_ECHOPGM(V...) do{ EVAL(_SEP_N(TWO_ARGS(V),V)); }while(0)
// Print up to 20 pairs of values followed by newline. Odd elements must be literal strings.
// Print pairs of values followed by newline. Odd elements must be literal strings.
#define __SELP_N(N,V...) _SELP_##N(V)
#define _SELP_N(N,V...) __SELP_N(N,V)
#define _SELP_N_REF() _SELP_N
@ -203,7 +203,7 @@ void SERIAL_ECHOLN(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args
#define _SELP_3(s,v,V...) _SEP_2(s,v); DEFER2(_SELP_N_REF)()(TWO_ARGS(V),V);
#define SERIAL_ECHOLNPGM(V...) do{ EVAL(_SELP_N(TWO_ARGS(V),V)); }while(0)
// Print up to 20 pairs of values. Odd elements must be PSTR pointers.
// Print pairs of values. Odd elements must be PSTR pointers.
#define __SEP_N_P(N,V...) _SEP_##N##_P(V)
#define _SEP_N_P(N,V...) __SEP_N_P(N,V)
#define _SEP_N_P_REF() _SEP_N_P
@ -212,7 +212,7 @@ void SERIAL_ECHOLN(T arg1, Args ... args) { SERIAL_ECHO(arg1); SERIAL_ECHO(args
#define _SEP_3_P(p,v,V...) _SEP_2_P(p,v); DEFER2(_SEP_N_P_REF)()(TWO_ARGS(V),V);
#define SERIAL_ECHOPGM_P(V...) do{ EVAL(_SEP_N_P(TWO_ARGS(V),V)); }while(0)
// Print up to 20 pairs of values followed by newline. Odd elements must be PSTR pointers.
// Print pairs of values followed by newline. Odd elements must be PSTR pointers.
#define __SELP_N_P(N,V...) _SELP_##N##_P(V)
#define _SELP_N_P(N,V...) __SELP_N_P(N,V)
#define _SELP_N_P_REF() _SELP_N_P

View file

@ -70,6 +70,9 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
#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)
#define NUM_AXIS_PAIRED_LIST(V...) LIST_N(DOUBLE(NUM_AXES), V)
#define LOGICAL_AXIS_PAIRED_LIST(EA,EB,V...) NUM_AXIS_PAIRED_LIST(V) LIST_ITEM_E(EA) LIST_ITEM_E(EB)
#if NUM_AXES
#define NUM_AXES_SEP ,
#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES)
@ -354,7 +357,7 @@ typedef float feedRate_t;
//
// celsius_t is the native unit of temperature. Signed to handle a disconnected thermistor value (-14).
// For more resolition (e.g., for a chocolate printer) this may later be changed to Celsius x 100
// For more resolution (e.g., for a chocolate printer) this may later be changed to Celsius x 100
//
typedef uint16_t raw_adc_t;
typedef int16_t celsius_t;

View file

@ -40,7 +40,7 @@ bool CaseLight::on = CASE_LIGHT_DEFAULT_ON;
#if CASE_LIGHT_IS_COLOR_LED
constexpr uint8_t init_case_light[] = CASE_LIGHT_DEFAULT_COLOR;
LEDColor CaseLight::color = { init_case_light[0], init_case_light[1], init_case_light[2] OPTARG(HAS_WHITE_LED, init_case_light[3]) };
LED1Color_t CaseLight::color = { init_case_light[0], init_case_light[1], init_case_light[2] OPTARG(HAS_WHITE_LED, init_case_light[3]) };
#endif
void CaseLight::update(const bool sflag) {
@ -67,13 +67,13 @@ void CaseLight::update(const bool sflag) {
#if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
if (on)
// Use current color of (NeoPixel) leds and new brightness level
leds.set_color(LEDColor(leds.color.r, leds.color.g, leds.color.b OPTARG(HAS_WHITE_LED, leds.color.w) OPTARG(NEOPIXEL_LED, n10ct)));
leds.set_color(LED1Color_t(leds.color.r, leds.color.g, leds.color.b OPTARG(HAS_WHITE_LED, leds.color.w) OPTARG(NEOPIXEL_LED, n10ct)));
else
// Switch off leds
leds.set_off();
#else
// Use CaseLight color (CASE_LIGHT_DEFAULT_COLOR) and new brightness level
leds.set_color(LEDColor(color.r, color.g, color.b OPTARG(HAS_WHITE_LED, color.w) OPTARG(NEOPIXEL_LED, n10ct)));
leds.set_color(LED1Color_t(color.r, color.g, color.b OPTARG(HAS_WHITE_LED, color.w) OPTARG(NEOPIXEL_LED, n10ct)));
#endif
#else // !CASE_LIGHT_IS_COLOR_LED

View file

@ -24,7 +24,7 @@
#include "../inc/MarlinConfig.h"
#if CASE_LIGHT_IS_COLOR_LED
#include "leds/leds.h" // for LEDColor
#include "leds/leds.h" // for LED1Color_t
#endif
class CaseLight {
@ -50,7 +50,7 @@ public:
#if ENABLED(CASE_LIGHT_IS_COLOR_LED)
private:
static LEDColor color;
static LED1Color_t color;
#endif
};

View file

@ -44,9 +44,30 @@ uint8_t ControllerFan::speed;
void ControllerFan::setup() {
SET_OUTPUT(CONTROLLER_FAN_PIN);
#ifdef CONTROLLER_FAN2_PIN
#if PIN_EXISTS(CONTROLLER_FAN2)
SET_OUTPUT(CONTROLLER_FAN2_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN3)
SET_OUTPUT(CONTROLLER_FAN3_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN4)
SET_OUTPUT(CONTROLLER_FAN4_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN5)
SET_OUTPUT(CONTROLLER_FAN5_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN6)
SET_OUTPUT(CONTROLLER_FAN6_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN7)
SET_OUTPUT(CONTROLLER_FAN7_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN8)
SET_OUTPUT(CONTROLLER_FAN8_PIN);
#endif
#if PIN_EXISTS(CONTROLLER_FAN9)
SET_OUTPUT(CONTROLLER_FAN9_PIN);
#endif
init();
}
@ -107,19 +128,38 @@ void ControllerFan::update() {
fan_kick_end = 0;
#endif
#define SET_CONTROLLER_FAN(N) do { \
if (PWM_PIN(CONTROLLER_FAN##N##_PIN)) hal.set_pwm_duty(pin_t(CONTROLLER_FAN##N##_PIN), speed); \
else WRITE(CONTROLLER_FAN##N##_PIN, speed > 0);\
} while (0)
#if ENABLED(FAN_SOFT_PWM)
soft_pwm_speed = speed;
#else
if (PWM_PIN(CONTROLLER_FAN_PIN))
hal.set_pwm_duty(pin_t(CONTROLLER_FAN_PIN), speed);
else
WRITE(CONTROLLER_FAN_PIN, speed > 0);
#ifdef CONTROLLER_FAN2_PIN
if (PWM_PIN(CONTROLLER_FAN2_PIN))
hal.set_pwm_duty(pin_t(CONTROLLER_FAN2_PIN), speed);
else
WRITE(CONTROLLER_FAN2_PIN, speed > 0);
SET_CONTROLLER_FAN();
#if PIN_EXISTS(CONTROLLER_FAN2)
SET_CONTROLLER_FAN(2);
#endif
#if PIN_EXISTS(CONTROLLER_FAN3)
SET_CONTROLLER_FAN(3);
#endif
#if PIN_EXISTS(CONTROLLER_FAN4)
SET_CONTROLLER_FAN(4);
#endif
#if PIN_EXISTS(CONTROLLER_FAN5)
SET_CONTROLLER_FAN(5);
#endif
#if PIN_EXISTS(CONTROLLER_FAN6)
SET_CONTROLLER_FAN(6);
#endif
#if PIN_EXISTS(CONTROLLER_FAN7)
SET_CONTROLLER_FAN(7);
#endif
#if PIN_EXISTS(CONTROLLER_FAN8)
SET_CONTROLLER_FAN(8);
#endif
#if PIN_EXISTS(CONTROLLER_FAN9)
SET_CONTROLLER_FAN(9);
#endif
#endif
}

View file

@ -87,7 +87,13 @@ void DigipotI2C::init() {
Wire.begin();
#endif
// Set up initial currents as defined in Configuration_adv.h
static const float digipot_motor_current[] PROGMEM = TERN(DIGIPOT_USE_RAW_VALUES, DIGIPOT_MOTOR_CURRENT, DIGIPOT_I2C_MOTOR_CURRENTS);
static const float digipot_motor_current[] PROGMEM =
#if ENABLED(DIGIPOT_USE_RAW_VALUES)
DIGIPOT_MOTOR_CURRENT
#else
DIGIPOT_I2C_MOTOR_CURRENTS
#endif
;
for (uint8_t i = 0; i < COUNT(digipot_motor_current); ++i)
set_current(i, pgm_read_float(&digipot_motor_current[i]));
}

View file

@ -131,7 +131,7 @@ void EasythreedUI::loadButton() {
break;
case FS_PROCEED: {
// Feed or Retract just once. Hard abort all moves and return to idle on swicth release.
// Feed or Retract just once. Hard abort all moves and return to idle on switch release.
static bool flag = false;
if (READ(BTN_RETRACT) && READ(BTN_FEED)) { // Switch in center position (stop)
flag = false; // Restore flag to false

View file

@ -32,7 +32,7 @@
#include "leds.h"
#include <Wire.h>
void blinkm_set_led_color(const LEDColor &color) {
void blinkm_set_led_color(const LED1Color_t &color) {
Wire.begin();
Wire.beginTransmission(I2C_ADDRESS(0x09));
Wire.write('o'); //to disable ongoing script, only needs to be used once

View file

@ -25,7 +25,6 @@
* blinkm.h - Control a BlinkM over i2c
*/
struct LEDColor;
typedef LEDColor LEDColor;
struct LED1Color_t;
void blinkm_set_led_color(const LEDColor &color);
void blinkm_set_led_color(const LED1Color_t &color);

View file

@ -35,15 +35,15 @@
#endif
#if ENABLED(LED_COLOR_PRESETS)
const LEDColor LEDLights::defaultLEDColor = LEDColor(
const LED1Color_t LEDLights::defaultLEDColor {
LED_USER_PRESET_RED, LED_USER_PRESET_GREEN, LED_USER_PRESET_BLUE
OPTARG(HAS_WHITE_LED, LED_USER_PRESET_WHITE)
OPTARG(NEOPIXEL_LED, LED_USER_PRESET_BRIGHTNESS)
);
};
#endif
#if ANY(LED_CONTROL_MENU, PRINTER_EVENT_LEDS, CASE_LIGHT_IS_COLOR_LED)
LEDColor LEDLights::color;
LED1Color_t LEDLights::color;
bool LEDLights::lights_on;
#endif
@ -101,7 +101,7 @@ void LEDLights::setup() {
constexpr int8_t led_pin_count = TERN(HAS_WHITE_LED, 4, 3);
// Startup animation
LEDColor curColor = LEDColorOff();
LED1Color_t curColor = LEDColorOff();
PCA9632_set_led_color(curColor); // blackout
delay(200);
@ -156,15 +156,15 @@ void LEDLights::setup() {
TERN_(LED_USER_PRESET_STARTUP, set_default());
}
void LEDLights::set_color(const LEDColor &incol
void LEDLights::set_color(const LED1Color_t &incol
OPTARG(NEOPIXEL_IS_SEQUENTIAL, bool isSequence/*=false*/)
) {
#if ENABLED(NEOPIXEL_LED)
const uint32_t neocolor = LEDColorWhite() == incol
? neo.Color(NEO_WHITE)
: neo.Color(incol.r, incol.g, incol.b OPTARG(HAS_WHITE_LED, incol.w));
? neo.White()
: neo.Color(incol.r, incol.g, incol.b OPTARG(HAS_WHITE_NEOPIXEL_1, incol.w));
#if ENABLED(NEOPIXEL_IS_SEQUENTIAL)
static uint16_t nextLed = 0;
@ -258,7 +258,7 @@ void LEDLights::set_color(const LEDColor &incol
#if ENABLED(NEOPIXEL2_SEPARATE)
#if ENABLED(NEO2_COLOR_PRESETS)
const LEDColor LEDLights2::defaultLEDColor = LEDColor(
const LED2Color_t LEDLights2::defaultLEDColor2 = LED2Color_t(
NEO2_USER_PRESET_RED, NEO2_USER_PRESET_GREEN, NEO2_USER_PRESET_BLUE
OPTARG(HAS_WHITE_LED2, NEO2_USER_PRESET_WHITE)
OPTARG(NEOPIXEL_LED, NEO2_USER_PRESET_BRIGHTNESS)
@ -266,7 +266,7 @@ void LEDLights::set_color(const LEDColor &incol
#endif
#if ENABLED(LED_CONTROL_MENU)
LEDColor LEDLights2::color;
LED2Color_t LEDLights2::color;
bool LEDLights2::lights_on;
#endif
@ -277,10 +277,10 @@ void LEDLights::set_color(const LEDColor &incol
TERN_(NEO2_USER_PRESET_STARTUP, set_default());
}
void LEDLights2::set_color(const LEDColor &incol) {
const uint32_t neocolor = LEDColorWhite() == incol
? neo2.Color(NEO2_WHITE)
: neo2.Color(incol.r, incol.g, incol.b OPTARG(HAS_WHITE_LED2, incol.w));
void LEDLights2::set_color(const LED2Color_t &incol) {
const uint32_t neocolor = LEDColorWhite2() == incol
? neo2.White()
: neo2.Color(incol.r, incol.g, incol.b OPTARG(HAS_WHITE_NEOPIXEL_2, incol.w));
neo2.set_brightness(incol.i);
neo2.set_color(neocolor);

View file

@ -29,11 +29,6 @@
#include <string.h>
// A white component can be passed
#if ANY(RGBW_LED, PCA9632_RGBW)
#define HAS_WHITE_LED 1
#endif
#if ENABLED(NEOPIXEL_LED)
#define _NEOPIXEL_INCLUDE_
#include "neopixel.h"
@ -52,75 +47,142 @@
#include "pca9632.h"
#endif
#if ANY(RGBW_LED, PCA9632_RGBW, HAS_WHITE_NEOPIXEL_1)
#define HAS_WHITE_LED 1
#endif
#if HAS_WHITE_NEOPIXEL_2
#define HAS_WHITE_LED2 1
#endif
/**
* LEDcolor type for use with leds.set_color
*/
typedef struct LEDColor {
uint8_t r, g, b
OPTARG(HAS_WHITE_LED, w)
OPTARG(NEOPIXEL_LED, i)
;
struct LED1Color_t {
// Basic RGB color components
uint8_t r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, i);
// Default constructor - white color
LED1Color_t() : r(255), g(255), b(255) OPTARG(HAS_WHITE_LED, w(255)) OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS)){}
LEDColor() : r(255), g(255), b(255)
OPTARG(HAS_WHITE_LED, w(255))
OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS))
{}
// Copy constructor
LED1Color_t(const LED1Color_t&) = default;
LEDColor(const LEDColor&) = default;
LEDColor(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w=0) OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS))
// Constructor with individual components
LED1Color_t(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w=0) OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS))
: r(r), g(g), b(b) OPTARG(HAS_WHITE_LED, w(w)) OPTARG(NEOPIXEL_LED, i(i)) {}
LEDColor(const uint8_t (&rgbw)[4]) : r(rgbw[0]), g(rgbw[1]), b(rgbw[2])
OPTARG(HAS_WHITE_LED, w(rgbw[3]))
OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS))
{}
// Constructor from array
LED1Color_t(const uint8_t (&rgbw)[4]) : r(rgbw[0]), g(rgbw[1]), b(rgbw[2])
OPTARG(HAS_WHITE_LED, w(rgbw[3])) OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS)){}
LEDColor& operator=(const uint8_t (&rgbw)[4]) {
// Array assignment operator
LED1Color_t& operator=(const uint8_t (&rgbw)[4]) {
r = rgbw[0]; g = rgbw[1]; b = rgbw[2];
TERN_(HAS_WHITE_LED, w = rgbw[3]);
return *this;
}
bool operator==(const LEDColor &right) {
if (this == &right) return true;
return 0 == memcmp(this, &right, sizeof(LEDColor));
// Comparison operators
bool operator==(const LED1Color_t &right) {
return (this == &right) || (0 == memcmp(this, &right, sizeof(LED1Color_t)));
}
bool operator!=(const LEDColor &right) { return !operator==(right); }
bool operator!=(const LED1Color_t &right) {
return !operator==(right);
}
// Check if LED is effectively off
bool is_off() const {
return 3 > r + g + b + TERN0(HAS_WHITE_LED, w);
}
} LEDColor;
};
struct LED2Color_t {
// Basic RGB color components
uint8_t r, g, b OPTARG(HAS_WHITE_LED2, w) OPTARG(NEOPIXEL_LED, i);
// Default constructor - white color
LED2Color_t() : r(255), g(255), b(255) OPTARG(HAS_WHITE_LED2, w(255)) OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS)){}
// Copy constructor
LED2Color_t(const LED2Color_t&) = default;
// Constructor with individual components
LED2Color_t(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED2, uint8_t w=0) OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS))
: r(r), g(g), b(b) OPTARG(HAS_WHITE_LED2, w(w)) OPTARG(NEOPIXEL_LED, i(i)) {}
// Constructor from array
LED2Color_t(const uint8_t (&rgbw)[4]) : r(rgbw[0]), g(rgbw[1]), b(rgbw[2])
OPTARG(HAS_WHITE_LED2, w(rgbw[3])) OPTARG(NEOPIXEL_LED, i(NEOPIXEL_BRIGHTNESS)){}
// Array assignment operator
LED2Color_t& operator=(const uint8_t (&rgbw)[4]) {
r = rgbw[0]; g = rgbw[1]; b = rgbw[2];
TERN_(HAS_WHITE_LED2, w = rgbw[3]);
return *this;
}
// Comparison operators
bool operator==(const LED2Color_t &right) {
return (this == &right) || (0 == memcmp(this, &right, sizeof(LED1Color_t)));
}
bool operator!=(const LED2Color_t &right) {
return !operator==(right);
}
// Check if LED is effectively off
bool is_off() const {
return 3 > r + g + b + TERN0(HAS_WHITE_LED2, w);
}
};
/**
* Color presets
*/
#define LEDColorOff() LEDColor( 0, 0, 0)
#define LEDColorRed() LEDColor(255, 0, 0)
#define LEDColorOff() LED1Color_t( 0, 0, 0)
#define LEDColorRed() LED1Color_t(255, 0, 0)
#if ENABLED(LED_COLORS_REDUCE_GREEN)
#define LEDColorOrange() LEDColor(255, 25, 0)
#define LEDColorYellow() LEDColor(255, 75, 0)
#define LEDColorOrange() LED1Color_t(255, 25, 0)
#define LEDColorYellow() LED1Color_t(255, 75, 0)
#else
#define LEDColorOrange() LEDColor(255, 80, 0)
#define LEDColorYellow() LEDColor(255, 255, 0)
#define LEDColorOrange() LED1Color_t(255, 80, 0)
#define LEDColorYellow() LED1Color_t(255, 255, 0)
#endif
#define LEDColorGreen() LEDColor( 0, 255, 0)
#define LEDColorBlue() LEDColor( 0, 0, 255)
#define LEDColorIndigo() LEDColor( 0, 255, 255)
#define LEDColorViolet() LEDColor(255, 0, 255)
#define LEDColorGreen() LED1Color_t( 0, 255, 0)
#define LEDColorBlue() LED1Color_t( 0, 0, 255)
#define LEDColorIndigo() LED1Color_t( 0, 255, 255)
#define LEDColorViolet() LED1Color_t(255, 0, 255)
#if HAS_WHITE_LED && DISABLED(RGB_LED)
#define LEDColorWhite() LEDColor( 0, 0, 0, 255)
#define LEDColorWhite() LED1Color_t( 0, 0, 0, 255)
#else
#define LEDColorWhite() LEDColor(255, 255, 255)
#define LEDColorWhite() LED1Color_t(255, 255, 255)
#endif
#define LEDColorOff2() LED2Color_t( 0, 0, 0)
#define LEDColorRed2() LED2Color_t(255, 0, 0)
#if ENABLED(LED_COLORS_REDUCE_GREEN)
#define LEDColorOrange2() LED2Color_t(255, 25, 0)
#define LEDColorYellow2() LED2Color_t(255, 75, 0)
#else
#define LEDColorOrange2() LED2Color_t(255, 80, 0)
#define LEDColorYellow2() LED2Color_t(255, 255, 0)
#endif
#define LEDColorGreen2() LED2Color_t( 0, 255, 0)
#define LEDColorBlue2() LED2Color_t( 0, 0, 255)
#define LEDColorIndigo2() LED2Color_t( 0, 255, 255)
#define LEDColorViolet2() LED2Color_t(255, 0, 255)
#if HAS_WHITE_LED2 && DISABLED(RGB_LED)
#define LEDColorWhite2() LED2Color_t( 0, 0, 0, 255)
#else
#define LEDColorWhite2() LED2Color_t(255, 255, 255)
#endif
class LEDLights {
public:
#if ANY(LED_CONTROL_MENU, PRINTER_EVENT_LEDS, CASE_LIGHT_IS_COLOR_LED)
static LEDColor color; // last non-off color
static LED1Color_t color; // last non-off color
static bool lights_on; // the last set color was "on"
#else
static constexpr bool lights_on = true;
@ -130,7 +192,7 @@ public:
static void setup(); // init()
static void set_color(const LEDColor &color
static void set_color(const LED1Color_t &color
OPTARG(NEOPIXEL_IS_SEQUENTIAL, bool isSequence=false)
);
@ -139,7 +201,7 @@ public:
OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS)
OPTARG(NEOPIXEL_IS_SEQUENTIAL, bool isSequence=false)
) {
set_color(LEDColor(r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, i)) OPTARG(NEOPIXEL_IS_SEQUENTIAL, isSequence));
set_color(LED1Color_t(r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, i)) OPTARG(NEOPIXEL_IS_SEQUENTIAL, isSequence));
}
static void set_off() { set_color(LEDColorOff()); }
@ -147,7 +209,7 @@ public:
static void set_white() { set_color(LEDColorWhite()); }
#if ENABLED(LED_COLOR_PRESETS)
static const LEDColor defaultLEDColor;
static const LED1Color_t defaultLEDColor;
static void set_default() { set_color(defaultLEDColor); }
static void set_red() { set_color(LEDColorRed()); }
static void set_orange() { set_color(LEDColorOrange()); }
@ -158,7 +220,7 @@ public:
#endif
#if ENABLED(PRINTER_EVENT_LEDS)
static LEDColor get_color() { return lights_on ? color : LEDColorOff(); }
static LED1Color_t get_color() { return lights_on ? color : LEDColorOff(); }
#endif
#if ENABLED(LED_CONTROL_MENU)
@ -190,35 +252,35 @@ extern LEDLights leds;
static void setup(); // init()
static void set_color(const LEDColor &color);
static void set_color(const LED2Color_t &color);
static void set_color(uint8_t r, uint8_t g, uint8_t b
OPTARG(HAS_WHITE_LED, uint8_t w=0)
OPTARG(HAS_WHITE_LED2, uint8_t w=0)
OPTARG(NEOPIXEL_LED, uint8_t i=NEOPIXEL_BRIGHTNESS)
) {
set_color(LEDColor(r, g, b
OPTARG(HAS_WHITE_LED, w)
set_color(LED2Color_t(r, g, b
OPTARG(HAS_WHITE_LED2, w)
OPTARG(NEOPIXEL_LED, i)
));
}
static void set_off() { set_color(LEDColorOff()); }
static void set_green() { set_color(LEDColorGreen()); }
static void set_white() { set_color(LEDColorWhite()); }
static void set_off() { set_color(LEDColorOff2()); }
static void set_green() { set_color(LEDColorGreen2()); }
static void set_white() { set_color(LEDColorWhite2()); }
#if ENABLED(NEO2_COLOR_PRESETS)
static const LEDColor defaultLEDColor;
static void set_default() { set_color(defaultLEDColor); }
static void set_red() { set_color(LEDColorRed()); }
static void set_orange() { set_color(LEDColorOrange()); }
static void set_yellow() { set_color(LEDColorYellow()); }
static void set_blue() { set_color(LEDColorBlue()); }
static void set_indigo() { set_color(LEDColorIndigo()); }
static void set_violet() { set_color(LEDColorViolet()); }
static const LED2Color_t defaultLEDColor2;
static void set_default() { set_color(defaultLEDColor2); }
static void set_red() { set_color(LEDColorRed2()); }
static void set_orange() { set_color(LEDColorOrange2()); }
static void set_yellow() { set_color(LEDColorYellow2()); }
static void set_blue() { set_color(LEDColorBlue2()); }
static void set_indigo() { set_color(LEDColorIndigo2()); }
static void set_violet() { set_color(LEDColorViolet2()); }
#endif
#if ENABLED(NEOPIXEL2_SEPARATE)
static LEDColor color; // last non-off color
static LED2Color_t color; // last non-off color
static bool lights_on; // the last set color was "on"
static void toggle(); // swap "off" with color
static void update() { set_color(color); }

View file

@ -103,7 +103,7 @@ void Marlin_NeoPixel::init() {
safe_delay(500);
set_color_startup(adaneo1.Color(0, 0, 255, 0)); // blue
safe_delay(500);
#if HAS_WHITE_LED
#if HAS_WHITE_NEOPIXEL_1
set_color_startup(adaneo1.Color(0, 0, 0, 255)); // white
safe_delay(500);
#endif
@ -158,7 +158,7 @@ void Marlin_NeoPixel::init() {
safe_delay(500);
set_color_startup(adaneo.Color(0, 0, 255, 0)); // blue
safe_delay(500);
#if HAS_WHITE_LED2
#if HAS_WHITE_NEOPIXEL_2
set_color_startup(adaneo.Color(0, 0, 0, 255)); // white
safe_delay(500);
#endif

View file

@ -42,19 +42,17 @@
// Defines
// ------------------------
#define _NEO_IS_RGB(N) (N == NEO_RGB || N == NEO_RBG || N == NEO_GRB || N == NEO_GBR || N == NEO_BRG || N == NEO_BGR)
#define _NEO_IS_RGBW(N) ((N) & 0x30) != (((N) >> 2) & 0x30)
#if !_NEO_IS_RGB(NEOPIXEL_TYPE)
#define HAS_WHITE_LED 1
#if _NEO_IS_RGBW(NEOPIXEL_TYPE)
#define HAS_WHITE_NEOPIXEL_1 1
#endif
#if HAS_WHITE_LED
#define NEO_WHITE 0, 0, 0, 255
#else
#define NEO_WHITE 255, 255, 255
#endif
#if defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE && DISABLED(NEOPIXEL2_SEPARATE)
#if ENABLED(NEOPIXEL2_SEPARATE)
#if _NEO_IS_RGBW(NEOPIXEL2_TYPE)
#define HAS_WHITE_NEOPIXEL_2 1
#endif
#elif defined(NEOPIXEL2_TYPE) && NEOPIXEL2_TYPE != NEOPIXEL_TYPE
#define MULTIPLE_NEOPIXEL_TYPES 1
#endif
@ -62,6 +60,8 @@
#define CONJOINED_NEOPIXEL 1
#endif
#undef _NEO_IS_RGBW
// ------------------------
// Types
// ------------------------
@ -141,8 +141,17 @@ public:
static uint8_t brightness() { return adaneo1.getBrightness(); }
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w)) {
return adaneo1.Color(r, g, b OPTARG(HAS_WHITE_LED, w));
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_NEOPIXEL_1, uint8_t w=0)) {
return adaneo1.Color(r, g, b OPTARG(HAS_WHITE_NEOPIXEL_1, w));
}
static uint32_t White() {
return Color(
#if HAS_WHITE_NEOPIXEL_1
0, 0, 0, 255
#else
255, 255, 255
#endif
);
}
};
@ -151,15 +160,6 @@ extern Marlin_NeoPixel neo;
// Neo pixel channel 2
#if ENABLED(NEOPIXEL2_SEPARATE)
#if _NEO_IS_RGB(NEOPIXEL2_TYPE)
#define NEOPIXEL2_IS_RGB 1
#define NEO2_WHITE 255, 255, 255
#else
#define NEOPIXEL2_IS_RGBW 1
#define HAS_WHITE_LED2 1 // A white component can be passed for NEOPIXEL2
#define NEO2_WHITE 0, 0, 0, 255
#endif
class Marlin_NeoPixel2 {
private:
static Adafruit_NeoPixel adaneo;
@ -184,13 +184,20 @@ extern Marlin_NeoPixel neo;
static uint16_t pixels() { return adaneo.numPixels();}
static uint32_t pixel_color(const uint16_t n) { return adaneo.getPixelColor(n); }
static uint8_t brightness() { return adaneo.getBrightness(); }
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED2, uint8_t w)) {
return adaneo.Color(r, g, b OPTARG(HAS_WHITE_LED2, w));
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_NEOPIXEL_2, uint8_t w=0)) {
return adaneo.Color(r, g, b OPTARG(HAS_WHITE_NEOPIXEL_2, w));
}
static uint32_t White() {
return Color(
#if HAS_WHITE_NEOPIXEL_2
0, 0, 0, 255
#else
255, 255, 255
#endif
);
}
};
extern Marlin_NeoPixel2 neo2;
#endif // NEOPIXEL2_SEPARATE
#undef _NEO_IS_RGB

View file

@ -68,7 +68,7 @@
#ifndef PCA9632_BLU
#define PCA9632_BLU 0x04
#endif
#if HAS_WHITE_LED && !defined(PCA9632_WHT)
#if ENABLED(PCA9632_RGBW) && !defined(PCA9632_WHT)
#define PCA9632_WHT 0x06
#endif
@ -124,7 +124,7 @@ static void PCA9632_WriteAllRegisters(const byte addr, const byte regadd, const
}
#endif
void PCA9632_set_led_color(const LEDColor &color) {
void PCA9632_set_led_color(const LED1Color_t &color) {
Wire.begin();
if (!PCA_init) {
PCA_init = 1;
@ -135,10 +135,7 @@ void PCA9632_set_led_color(const LEDColor &color) {
const byte LEDOUT = (color.r ? LED_PWM << PCA9632_RED : 0)
| (color.g ? LED_PWM << PCA9632_GRN : 0)
| (color.b ? LED_PWM << PCA9632_BLU : 0)
#if ENABLED(PCA9632_RGBW)
| (color.w ? LED_PWM << PCA9632_WHT : 0)
#endif
;
| (TERN0(PCA9632_RGBW, color.w ? LED_PWM << PCA9632_WHT : 0));
PCA9632_WriteAllRegisters(PCA9632_ADDRESS,PCA9632_PWM0, color.r, color.g, color.b
OPTARG(PCA9632_RGBW, color.w)

View file

@ -26,10 +26,9 @@
* Written by Robert Mendon Feb 2017.
*/
struct LEDColor;
typedef LEDColor LEDColor;
struct LED1Color_t;
void PCA9632_set_led_color(const LEDColor &color);
void PCA9632_set_led_color(const LED1Color_t &color);
#if ENABLED(PCA9632_BUZZER)
#include <stdint.h>

View file

@ -47,7 +47,7 @@ PrinterEventLEDs printerEventLEDs;
inline void pel_set_rgb(const uint8_t r, const uint8_t g, const uint8_t b OPTARG(HAS_WHITE_LED, const uint8_t w=0)) {
leds.set_color(
LEDColor(r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, neo.brightness()))
LED1Color_t(r, g, b OPTARG(HAS_WHITE_LED, w) OPTARG(NEOPIXEL_LED, neo.brightness()))
OPTARG(NEOPIXEL_IS_SEQUENTIAL, true)
);
}

View file

@ -40,23 +40,23 @@ private:
public:
#if HAS_TEMP_HOTEND
static LEDColor onHotendHeatingStart() { old_intensity = 0; return leds.get_color(); }
static LED1Color_t onHotendHeatingStart() { old_intensity = 0; return leds.get_color(); }
static void onHotendHeating(const celsius_t start, const celsius_t current, const celsius_t target);
#endif
#if HAS_HEATED_BED
static LEDColor onBedHeatingStart() { old_intensity = 127; return leds.get_color(); }
static LED1Color_t onBedHeatingStart() { old_intensity = 127; return leds.get_color(); }
static void onBedHeating(const celsius_t start, const celsius_t current, const celsius_t target);
#endif
#if HAS_HEATED_CHAMBER
static LEDColor onChamberHeatingStart() { old_intensity = 127; return leds.get_color(); }
static LED1Color_t onChamberHeatingStart() { old_intensity = 127; return leds.get_color(); }
static void onChamberHeating(const celsius_t start, const celsius_t current, const celsius_t target);
#endif
#if HAS_TEMP_HOTEND || HAS_HEATED_BED || HAS_HEATED_CHAMBER
static void onHeatingDone() { leds.set_white(); }
static void onPIDTuningDone(LEDColor c) { leds.set_color(c); }
static void onPIDTuningDone(LED1Color_t c) { leds.set_color(c); }
#endif
#if HAS_MEDIA

View file

@ -1,5 +1,4 @@
Startup sequence
================
# Startup sequence
When initialized, MMU sends
@ -20,18 +19,17 @@ We follow with
#endif
- MMU <= 'P0\n'
- MMU => '*FINDA status*\n'
- MMU => '_FINDA status_\n'
Now we are sure MMU is available and ready. If there was a timeout or other communication problem somewhere, printer will be killed.
- *Firmware version* is an integer value, but we don't care about it
- *Build number* is an integer value and has to be >=126, or =>132 if 12V mode is enabled
- *FINDA status* is 1 if the filament is loaded to the extruder, 0 otherwise
- _Firmware version_ is an integer value, but we don't care about it
- _Build number_ is an integer value and has to be >=126, or =>132 if 12V mode is enabled
- _FINDA status_ is 1 if the filament is loaded to the extruder, 0 otherwise
*Build number* is checked against the required value, if it does not match, printer is halted.
_Build number_ is checked against the required value, if it does not match, printer is halted.
Toolchange
==========
# Toolchange
- MMU <= 'T*Filament index*\n'
@ -51,16 +49,14 @@ When done, the MMU sends
We don't wait for a response here but immediately continue with the next G-code which should
be one or more extruder moves to feed the filament into the hotend.
FINDA status
============
# FINDA status
- MMU <= 'P0\n'
- MMU => '*FINDA status*\n'
- MMU => '_FINDA status_\n'
*FINDA status* is 1 if the is filament loaded to the extruder, 0 otherwise. This could be used as filament runout sensor if probed regularly.
_FINDA status_ is 1 if the is filament loaded to the extruder, 0 otherwise. This could be used as filament runout sensor if probed regularly.
Load filament
=============
# Load filament
- MMU <= 'L*Filament index*\n'
@ -68,8 +64,7 @@ MMU will feed filament down to the extruder, when done
- MMU => 'ok\n'
Unload filament
=============
# Unload filament
- MMU <= 'U0\n'
@ -77,8 +72,7 @@ MMU will retract current filament from the extruder, when done
- MMU => 'ok\n'
Eject filament
==============
# Eject filament
- MMU <= 'E*Filament index*\n'
- MMU => 'ok\n'

View file

@ -28,6 +28,7 @@ This set of responses combines to indicate firmware version 3.0.2.
## Startup sequence
When initialized the MMU waits for requests. Marlin repeatedly sends `S0` commands until it gets an answer:
```
MMU3:>S0*c6\n
MMU3:>S0*c6\n
@ -36,11 +37,13 @@ MMU3:>S0*c6\n
```
Once communication is established the MMU responds with:
```
MMU3:<S0 A3*22\n
```
Then Marlin continues to get the rest of the MMU firmware version.
```
MMU3:>S1*ad\n
MMU3:<S1 A0*34\n
@ -49,6 +52,7 @@ MMU3:<S2 A2*65\n
```
Setting the stepper mode to SpreadCycle (M0) or StealthChop (M1):
```
MMU3:>M1*{CRC8};
MMU3:<---nothing---
@ -61,10 +65,10 @@ MMU3:<P0 A{FINDA status}*{CRC8}\n
At this point we can be sure the MMU is available and ready. If there was a timeout or other communication problem somewhere, the printer will not be killed, but for safety the MMU feature will be disabled.
- *Firmware version* is an integer value, and we care about it. As there is no other way of knowing which protocol to use.
- *FINDA status* is 1 if the filament is loaded to the extruder, 0 otherwise.
- _Firmware version_ is an integer value, and we care about it. As there is no other way of knowing which protocol to use.
- _FINDA status_ is 1 if the filament is loaded to the extruder, 0 otherwise.
The *Firmware version* is checked against the required value. If it doesn't match the printer will not be halted, but for safety the MMU feature will be disabled.
The _Firmware version_ is checked against the required value. If it doesn't match the printer will not be halted, but for safety the MMU feature will be disabled.
## Toolchange
@ -74,11 +78,13 @@ MMU3:<Q0*ea\n
```
The MMU sends:
```
MMU3:<T{filament index}*P{ProgressCode}{CRC8}\n
```
Which in normal operation would be as follows, let's say that we requested MMU to load `T0``:
```
MMU3:>T0*{CRC8}\n
@ -96,6 +102,7 @@ MMU3:>C0*{CRC8}\n
```
The MMU will feed a few more millimeters of filament for the extruder gears to grab. When done, the MMU sends:
```
MMU3:>Q0*{CRC8}\n
MMU3:<T0*P9{CRC8}\n # P9 => FinishingMoves
@ -103,18 +110,20 @@ MMU3:<T0*P9{CRC8}\n # P9 => FinishingMoves
After the `T0*P9` response we immediately continue with the next G-code which should be one or more extruder moves to feed the filament into the hotend.
## FINDA status
```
MMU3:>P0*{CRC8}\n
```
If the filament is loaded to the extruder, FINDA status is 1 and the MMU responds with:
```
MMU3:<P0 A1*{CRC8}\n
```
…otherwise it replies:
```
MMU3:<P0 A0*7b\n
```
@ -124,22 +133,26 @@ This could be used as a filament runout sensor if polled regularly.
## Load filament
To load a filament to the MMU itself, we run:
```
MMU3:>L{Filament index}*{CRC8}\n
MMU3:<L{Filament index} A1*{CRC8}\n
```
…and immediately after that we query the status:
```
MMU3:>Q0*{CRC8}\n
```
The MMU will respond with status messages:
```
MMU3:<L0*P5{CRC8}\n
```
The MMU will load the filament and when done:
```
MMU3:>Q0*{CRC8}\n
MMU3:<L0*P9{CRC8}\n

View file

@ -1162,7 +1162,7 @@ namespace MMU3 {
//
// Instead of doing a very long extrude as in PrusaFirmware,
// Marlin's own MMU2s code has a better approach to this by spinning
// the extruder indefinitelly...
// the extruder indefinitely...
//
// this ensures that while the MMU is pushing the filament,
// the extruder will keep rotating, preventing the filament to hit

View file

@ -115,12 +115,12 @@
void powerOn();
// Read from a MMU register (See gcode M707)
// @param address Address of register in hexidecimal
// @param address Address of register in hexadecimal
// @return true upon success
bool readRegister(uint8_t address);
// Write from a MMU register (See gcode M708)
// @param address Address of register in hexidecimal
// @param address Address of register in hexadecimal
// @param data Data to write to register
// @return true upon success
bool writeRegister(uint8_t address, uint16_t data);
@ -204,7 +204,7 @@
ErrorCode getLastErrorCode() const { return lastErrorCode; }
// @return the version of the connected MMU FW.
// In the future we'll return the trully detected FW version
// In the future we'll return the truly detected FW version
Version getMMUFWVersion() const {
if (state() == xState::Active) {
return { logic.mmuFwVersionMajor(), logic.mmuFwVersionMinor(), logic.mmuFwVersionRevision() };

View file

@ -60,7 +60,7 @@ namespace MMU3 {
return (i != errorCodesEnd) ? (i - errorCodes) : (errorCodesSize - 1);
}
// check that the searching algoritm works
// check that the searching algorithm works
// static_assert( FindErrorIndex(ERR_MECHANICAL_FINDA_DIDNT_TRIGGER) == 0);
// static_assert( FindErrorIndex(ERR_MECHANICAL_FINDA_FILAMENT_STUCK) == 1);
// static_assert( FindErrorIndex(ERR_MECHANICAL_FSENSOR_DIDNT_TRIGGER) == 2);

View file

@ -32,7 +32,7 @@
namespace MMU3 {
// Can be used to block printer's filament sensor handling - to avoid errorneous injecting of M600
// Can be used to block printer's filament sensor handling - to avoid erroneous injecting of M600
// while doing a toolchange with the MMU
// In case of "no filament sensor" these methods default to an empty implementation
class FSensorBlockRunout {

View file

@ -115,7 +115,7 @@ namespace protocol {
// A response message - responses are being sent from the MMU into the printer as a response to a request message.
struct ResponseMsg {
RequestMsg request; //!< response is always preceeded by the request message
RequestMsg request; //!< response is always preceded by the request message
ResponseMsgParamCodes paramCode; //!< code of the parameter
uint16_t paramValue; //!< value of the parameter
@ -157,7 +157,7 @@ namespace protocol {
// Protocol class is responsible for creating/decoding messages in Rx/Tx buffer
//
// Beware - in the decoding more, it is meant to be a statefull instance which works through public methods
// Beware - in the decoding more, it is meant to be a stateful instance which works through public methods
// processing one input byte per call.
class Protocol {
public:
@ -186,11 +186,11 @@ namespace protocol {
static uint8_t EncodeWriteRequest(uint8_t address, uint16_t value, uint8_t *txbuff);
// @return the maximum byte length necessary to encode a request message
// Beneficial in case of pre-allocating a buffer for enconding a RequestMsg.
// Beneficial in case of pre-allocating a buffer for encoding a RequestMsg.
static constexpr uint8_t MaxRequestSize() { return 13; }
// @return the maximum byte length necessary to encode a response message
// Beneficial in case of pre-allocating a buffer for enconding a ResponseMsg.
// Beneficial in case of pre-allocating a buffer for encoding a ResponseMsg.
static constexpr uint8_t MaxResponseSize() { return 14; }
// Encode generic response Command Accepted or Rejected

View file

@ -449,7 +449,7 @@ namespace MMU3 {
const uint8_t ei = PrusaErrorCodeIndex((ErrorCode)ec);
// This should be the equivelent of the switch..case above...
// This should be the equivalent of the switch..case above...
if ((uint8_t)ReportErrorHookState == (uint8_t)ReportErrorHookStates::RENDER_ERROR_SCREEN) {
KEEPALIVE_STATE(PAUSED_FOR_USER);
#if HAS_WIRED_LCD

View file

@ -33,7 +33,7 @@
* therefore the error codes have been extracted to one place.
*
* Please note the errors are intentionally coded as "negative" values (highest bit set),
* becase they are a complement to reporting the state of the high-level state machines -
* because they are a complement to reporting the state of the high-level state machines -
* positive values are considered as normal progress, negative values are errors.
*
* Please note, that multiple TMC errors can occur at once, thus they are defined as a bitmask of the higher byte.

View file

@ -114,7 +114,7 @@ typedef enum : uint16_t {
} err_num_t;
// Avr gcc has serious trouble understanding static data structures in PROGMEM
// and inadvertedly falls back to copying the whole structure into RAM (which is obviously unwanted).
// and inadvertently falls back to copying the whole structure into RAM (which is obviously unwanted).
// But since this file ought to be generated in the future from yaml prescription,
// it really makes no difference if there are "nice" data structures or plain arrays.
static const constexpr err_num_t errorCodes[] PROGMEM = {

View file

@ -420,8 +420,11 @@ void PrintJobRecovery::resume() {
#endif
// Interpret the saved Z according to flags
const float z_print = resume_pos.z,
z_raised = z_print + info.zraise;
const float z_print = resume_pos.z;
#if ANY(Z_HOME_TO_MAX, POWER_LOSS_RECOVER_ZHOME) || DISABLED(BELTPRINTER)
const float z_raised = z_print + info.zraise;
#endif
//
// Home the axes that can safely be homed, and
@ -482,7 +485,7 @@ void PrintJobRecovery::resume() {
#if !HOMING_Z_DOWN
// The physical Z was adjusted at power-off so undo the M420S1 correction to Z with G92.9.
PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 1)));
PROCESS_SUBCOMMANDS_NOW(TS(F("G92.9Z"), p_float_t(z_now, 3)));
#endif
#endif
@ -529,7 +532,7 @@ void PrintJobRecovery::resume() {
}
#endif
// Restore retract and hop state from an active `G10` command
// Restore retract and hop state from an active 'G10' command
#if ENABLED(FWRETRACT)
EXTRUDER_LOOP() {
if (info.retract[e] != 0.0) {

View file

@ -54,7 +54,7 @@ bool FilamentMonitorBase::enabled = true,
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
bool RunoutResponseDelayed::ignore_motion = false;
constexpr float RunoutResponseDelayed::motion_distance_mm;
float RunoutResponseDelayed::motion_distance_mm = FILAMENT_MOTION_DISTANCE_MM;
#endif
#else
int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0

View file

@ -122,6 +122,8 @@ class TFilamentMonitor : public FilamentMonitorBase {
static void filament_motion_present(const uint8_t extruder) {
response.filament_motion_present(extruder);
}
static float& motion_distance() { return response.motion_distance_mm; }
static void set_motion_distance(const_float_t mm) { response.motion_distance_mm = mm; }
#endif
#if HAS_FILAMENT_RUNOUT_DISTANCE
@ -380,7 +382,7 @@ class FilamentSensorBase {
static float runout_distance_mm;
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
static constexpr float motion_distance_mm = FILAMENT_MOTION_DISTANCE_MM;
static float motion_distance_mm;
#endif
static void set_ignore_motion(const bool ignore=true) { ignore_motion = ignore; }

View file

@ -24,6 +24,12 @@
#if HAS_TRINAMIC_CONFIG
/**
* feature/tmc_util.cpp - Functions for debugging Trinamic stepper drivers.
* The main entry point is `tmc_report_all` which is called by M122 to collect
* and report diagnostic information about each enabled TMC driver.
*/
#include "tmc_util.h"
#include "../MarlinCore.h"
@ -83,9 +89,7 @@
#if HAS_TMCX1X0
#if ENABLED(TMC_DEBUG)
static uint32_t get_pwm_scale(TMC2130Stepper &st) { return st.PWM_SCALE(); }
#endif
static uint32_t get_pwm_scale(TMC2130Stepper &st) { return st.PWM_SCALE(); }
static TMC_driver_data get_driver_data(TMC2130Stepper &st) {
constexpr uint8_t OT_bp = 25, OTPW_bp = 26;
@ -144,9 +148,7 @@
#if HAS_DRIVER(TMC2240)
#if ENABLED(TMC_DEBUG)
static uint32_t get_pwm_scale(TMC2240Stepper &st) { return st.PWM_SCALE(); }
#endif
static uint32_t get_pwm_scale(TMC2240Stepper &st) { return st.PWM_SCALE(); }
static TMC_driver_data get_driver_data(TMC2240Stepper &st) {
constexpr uint8_t OT_bp = 25, OTPW_bp = 26;
@ -205,9 +207,7 @@
#if HAS_TMC220x
#if ENABLED(TMC_DEBUG)
static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); }
#endif
static uint32_t get_pwm_scale(TMC2208Stepper &st) { return st.pwm_scale_sum(); }
static TMC_driver_data get_driver_data(TMC2208Stepper &st) {
constexpr uint8_t OTPW_bp = 0, OT_bp = 1;
@ -242,9 +242,7 @@
#if HAS_DRIVER(TMC2660)
#if ENABLED(TMC_DEBUG)
static uint32_t get_pwm_scale(TMC2660Stepper) { return 0; }
#endif
static uint32_t get_pwm_scale(TMC2660Stepper) { return 0; }
static TMC_driver_data get_driver_data(TMC2660Stepper &st) {
constexpr uint8_t OT_bp = 1, OTPW_bp = 2;
@ -292,12 +290,13 @@
SString<50>(F(" driver overtemperature warning! ("), st.getMilliamps(), F("mA)")).echoln();
}
template<typename TMC>
void report_polled_driver_data(TMC &st, const TMC_driver_data &data) {
const uint32_t pwm_scale = get_pwm_scale(st);
st.printLabel();
SString<60> report(':', pwm_scale);
#if ENABLED(TMC_DEBUG)
#if ENABLED(TMC_DEBUG)
template<typename TMC>
void report_polled_driver_data(TMC &st, const TMC_driver_data &data) {
const uint32_t pwm_scale = get_pwm_scale(st);
st.printLabel();
SString<60> report(':', pwm_scale);
#if HAS_TMCX1X0_OR_2240 || HAS_TMC220x
report.append('/', data.cs_actual);
#endif
@ -308,22 +307,21 @@
else
report += '-';
#endif
#endif
report += '|';
if (st.error_count) report += 'E'; // Error
if (data.is_ot) report += 'O'; // Over-temperature
if (data.is_otpw) report += 'W'; // over-temperature pre-Warning
#if ENABLED(TMC_DEBUG)
report += '|';
if (st.error_count) report += 'E'; // Error
if (data.is_ot) report += 'O'; // Over-temperature
if (data.is_otpw) report += 'W'; // over-temperature pre-Warning
if (data.is_stall) report += 'G'; // stallGuard
if (data.is_stealth) report += 'T'; // stealthChop
if (data.is_standstill) report += 'I'; // standstIll
#endif
if (st.flag_otpw) report += 'F'; // otpw Flag
report += '|';
if (st.otpw_count > 0) report += st.otpw_count;
report += '\t';
report.echo();
}
if (st.flag_otpw) report += 'F'; // otpw Flag
report += '|';
if (st.otpw_count > 0) report += st.otpw_count;
report += '\t';
report.echo();
}
#endif // TMC_DEBUG
#if CURRENT_STEP_DOWN > 0
@ -383,9 +381,9 @@
else if (st.otpw_count > 0) st.otpw_count = 0;
}
#if ENABLED(TMC_DEBUG)
if (need_debug_reporting) report_polled_driver_data(st, data);
#endif
if (need_debug_reporting) {
TERN_(TMC_DEBUG, report_polled_driver_data(st, data));
}
return should_step_down;
}
@ -518,7 +516,7 @@
TMC_TSTEP,
TMC_TPWMTHRS,
TMC_TPWMTHRS_MMS,
TMC_OTPW,
TMC_DEBUG_OTPW,
TMC_OTPW_TRIGGERED,
TMC_TOFF,
TMC_TBL,
@ -575,7 +573,9 @@
TMC_GET_DRVCTRL,
TMC_GET_DRVSTATUS,
TMC_GET_SGCSCONF,
TMC_GET_SMARTEN
TMC_GET_SMARTEN,
TMC_GET_SG4_THRS,
TMC_GET_SG4_RESULT
};
template<class TMC>
@ -603,6 +603,7 @@
static void print_true_or_false(const bool tf) { SERIAL_ECHO(TRUE_FALSE(tf)); }
#if HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC5130)
// Additional tmc_status fields for 2130/5130 and related drivers
static void _tmc_status(TMC2130Stepper &st, const TMC_debug_enum i) {
switch (i) {
case TMC_PWM_SCALE: SERIAL_ECHO(st.PWM_SCALE()); break;
@ -614,6 +615,7 @@
}
#endif
#if HAS_TMCX1X0
// Additional tmc_parse_drv_status fields for 2130 and related drivers
static void _tmc_parse_drv_status(TMC2130Stepper &st, const TMC_drv_status_enum i) {
switch (i) {
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('*'); break;
@ -626,18 +628,17 @@
#endif
#if HAS_DRIVER(TMC2160) || HAS_DRIVER(TMC5160)
// Additional tmc_status fields for 2160/5160 and related drivers
static void _tmc_status(TMC2160Stepper &st, const TMC_debug_enum i) {
switch (i) {
case TMC_PWM_SCALE: SERIAL_ECHO(st.PWM_SCALE()); break;
case TMC_SGT: SERIAL_ECHO(st.sgt()); break;
case TMC_STEALTHCHOP: print_true_or_false(st.en_pwm_mode()); break;
case TMC_GLOBAL_SCALER:
{
const uint16_t value = st.GLOBAL_SCALER();
SERIAL_ECHO(value ?: 256);
SERIAL_ECHOPGM("/256");
}
break;
case TMC_GLOBAL_SCALER: {
const uint16_t value = st.GLOBAL_SCALER();
SERIAL_ECHO(value ?: 256);
SERIAL_ECHOPGM("/256");
} break;
case TMC_INTERPOLATE: print_true_or_false(st.intpol()); break;
default: break;
}
@ -646,12 +647,16 @@
#if HAS_TMC220x
// Additional tmc_status fields for 2208/2224/2209 drivers
static void _tmc_status(TMC2208Stepper &st, const TMC_debug_enum i) {
switch (i) {
// PWM_SCALE
case TMC_PWM_SCALE_SUM: SERIAL_ECHO(st.pwm_scale_sum()); break;
case TMC_PWM_SCALE_AUTO: SERIAL_ECHO(st.pwm_scale_auto()); break;
// PWM_AUTO
case TMC_PWM_OFS_AUTO: SERIAL_ECHO(st.pwm_ofs_auto()); break;
case TMC_PWM_GRAD_AUTO: SERIAL_ECHO(st.pwm_grad_auto()); break;
// CHOPCONF
case TMC_STEALTHCHOP: print_true_or_false(st.stealth()); break;
case TMC_INTERPOLATE: print_true_or_false(st.intpol()); break;
default: break;
@ -659,19 +664,20 @@
}
#if HAS_DRIVER(TMC2209)
// Additional tmc_status fields for 2209 drivers
template<char AXIS_LETTER, char DRIVER_ID, AxisEnum AXIS_ID>
static void _tmc_status(TMCMarlin<TMC2209Stepper, AXIS_LETTER, DRIVER_ID, AXIS_ID> &st, const TMC_debug_enum i) {
switch (i) {
case TMC_SGT: SERIAL_ECHO(st.SGTHRS()); break;
case TMC_UART_ADDR: SERIAL_ECHO(st.get_address()); break;
default:
TMC2208Stepper *parent = &st;
_tmc_status(*parent, i);
_tmc_status(static_cast<TMC2208Stepper &>(st), i);
break;
}
}
#endif
// Additional tmc_parse_drv_status fields for 2208/2224/2209 drivers
static void _tmc_parse_drv_status(TMC2208Stepper &st, const TMC_drv_status_enum i) {
switch (i) {
case TMC_T157: if (st.t157()) SERIAL_CHAR('*'); break;
@ -686,10 +692,13 @@
}
#if HAS_DRIVER(TMC2209)
// Additional tmc_parse_drv_status fields for 2209 drivers
static void _tmc_parse_drv_status(TMC2209Stepper &st, const TMC_drv_status_enum i) {
switch (i) {
case TMC_SG_RESULT: SERIAL_ECHO(st.SG_RESULT()); break;
default: _tmc_parse_drv_status(static_cast<TMC2208Stepper &>(st), i); break;
default:
_tmc_parse_drv_status(static_cast<TMC2208Stepper &>(st), i);
break;
}
}
#endif
@ -697,13 +706,32 @@
#endif // HAS_TMC220x
#if HAS_DRIVER(TMC2240)
static void _tmc_parse_drv_status(TMC2240Stepper, const TMC_drv_status_enum) { }
// Additional tmc_parse_drv_status fields for 2240 drivers
static void _tmc_parse_drv_status(TMC2240Stepper &st, const TMC_drv_status_enum i) {
switch (i) {
case TMC_S2VSA: if (st.s2vsa()) SERIAL_CHAR('*'); break;
case TMC_S2VSB: if (st.s2vsb()) SERIAL_CHAR('*'); break;
case TMC_STEALTHCHOP: print_true_or_false(st.stealth()); break;
case TMC_FSACTIVE: if (st.fsactive()) SERIAL_CHAR('*'); break;
case TMC_DRV_CS_ACTUAL: if (st.CS_ACTUAL()) SERIAL_CHAR('*'); break;
case TMC_STALLGUARD: if (st.stallguard()) SERIAL_CHAR('*'); break;
case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_SG_RESULT: SERIAL_ECHO(st.SG_RESULT()); break;
default: break; // other...
}
}
// Additional tmc_status fields for 2240 drivers
static void _tmc_status(TMC2240Stepper &st, const TMC_debug_enum i) {
switch (i) {
// PWM_SCALE
case TMC_PWM_SCALE_SUM: SERIAL_ECHO(st.pwm_scale_sum()); break;
case TMC_PWM_SCALE_AUTO: SERIAL_ECHO(st.pwm_scale_auto()); break;
// PWM_AUTO
case TMC_PWM_OFS_AUTO: SERIAL_ECHO(st.pwm_ofs_auto()); break;
case TMC_PWM_GRAD_AUTO: SERIAL_ECHO(st.pwm_grad_auto()); break;
// CHOPCONF
case TMC_STEALTHCHOP: print_true_or_false(st.stealth()); break;
case TMC_INTERPOLATE: print_true_or_false(st.intpol()); break;
case TMC_VAIN: SERIAL_ECHO(st.get_ain_voltage()); break;
@ -714,7 +742,8 @@
default: break;
}
}
#endif
#endif // TMC2240
#if HAS_DRIVER(TMC2660)
static void _tmc_parse_drv_status(TMC2660Stepper, const TMC_drv_status_enum) { }
@ -750,14 +779,8 @@
case TMC_CURRENT: SERIAL_ECHO(st.getMilliamps()); break;
case TMC_RMS_CURRENT: SERIAL_ECHO(st.rms_current()); break;
case TMC_MAX_CURRENT: SERIAL_ECHO(p_float_t(st.rms_current() * 1.41, 0)); break;
case TMC_IRUN:
SERIAL_ECHO(st.irun());
SERIAL_ECHOPGM("/31");
break;
case TMC_IHOLD:
SERIAL_ECHO(st.ihold());
SERIAL_ECHOPGM("/31");
break;
case TMC_IRUN: SERIAL_ECHO(st.irun()); SERIAL_ECHOPGM("/31"); break;
case TMC_IHOLD: SERIAL_ECHO(st.ihold()); SERIAL_ECHOPGM("/31"); break;
case TMC_CS_ACTUAL: print_cs_actual(st); break;
case TMC_VSENSE: print_vsense(st); break;
case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break;
@ -769,7 +792,7 @@
if (tpwmthrs_val) SERIAL_ECHO(tpwmthrs_val); else SERIAL_CHAR('-');
} break;
#endif
case TMC_OTPW: print_true_or_false(st.otpw()); break;
case TMC_DEBUG_OTPW: print_true_or_false(st.otpw()); break;
#if ENABLED(MONITOR_DRIVER_STATUS)
case TMC_OTPW_TRIGGERED: print_true_or_false(st.getOTPW()); break;
#endif
@ -792,13 +815,10 @@
case TMC_CURRENT: SERIAL_ECHO(st.getMilliamps()); break;
case TMC_RMS_CURRENT: SERIAL_ECHO(st.rms_current()); break;
case TMC_MAX_CURRENT: SERIAL_ECHO(p_float_t(st.rms_current() * 1.41, 0)); break;
case TMC_IRUN:
SERIAL_ECHO(st.cs());
SERIAL_ECHOPGM("/31");
break;
case TMC_IRUN: SERIAL_ECHO(st.cs()); SERIAL_ECHOPGM("/31"); break;
case TMC_VSENSE: SERIAL_ECHO(st.vsense() ? F("1=.165") : F("0=.310")); break;
case TMC_MICROSTEPS: SERIAL_ECHO(st.microsteps()); break;
//case TMC_OTPW: print_true_or_false(st.otpw()); break;
//case TMC_DEBUG_OTPW: print_true_or_false(st.otpw()); break;
//case TMC_OTPW_TRIGGERED: print_true_or_false(st.getOTPW()); break;
case TMC_SGT: SERIAL_ECHO(st.sgt()); break;
case TMC_TOFF: SERIAL_ECHO(st.toff()); break;
@ -808,30 +828,27 @@
default: _tmc_status(st, i); break;
}
}
#endif
#endif // TMC2660
template <typename TMC>
static void tmc_parse_drv_status(TMC &st, const TMC_drv_status_enum i) {
SERIAL_CHAR('\t');
switch (i) {
case TMC_DRV_CODES: st.printLabel(); break;
case TMC_STST: if (!st.stst()) SERIAL_CHAR('*'); break;
case TMC_OLB: if (st.olb()) SERIAL_CHAR('*'); break;
case TMC_OLA: if (st.ola()) SERIAL_CHAR('*'); break;
case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('*'); break;
case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('*'); break;
case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('*'); break;
case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_DRV_CODES: st.printLabel(); break;
case TMC_STST: if (!st.stst()) SERIAL_CHAR('*'); break;
case TMC_OLB: if (st.olb()) SERIAL_CHAR('*'); break;
case TMC_OLA: if (st.ola()) SERIAL_CHAR('*'); break;
case TMC_S2GB: if (st.s2gb()) SERIAL_CHAR('*'); break;
case TMC_S2GA: if (st.s2ga()) SERIAL_CHAR('*'); break;
case TMC_DRV_OTPW: if (st.otpw()) SERIAL_CHAR('*'); break;
case TMC_OT: if (st.ot()) SERIAL_CHAR('*'); break;
case TMC_DRV_STATUS_HEX: {
const uint32_t drv_status = st.DRV_STATUS();
SERIAL_CHAR('\t');
st.printLabel();
SERIAL_CHAR('\t');
print_hex_long(drv_status, ':', true);
SERIAL_CHAR('\t'); st.printLabel();
SERIAL_CHAR('\t'); print_hex_long(drv_status, ':', true);
if (drv_status == 0xFFFFFFFF || drv_status == 0) SERIAL_ECHOPGM("\t Bad response!");
SERIAL_EOL();
break;
}
} break;
default: _tmc_parse_drv_status(st, i); break;
}
}
@ -946,7 +963,7 @@
TMC_REPORT("tstep\t", TMC_TSTEP);
TMC_REPORT("PWM thresh.", TMC_TPWMTHRS);
TMC_REPORT("[mm/s]\t", TMC_TPWMTHRS_MMS);
TMC_REPORT("OT prewarn", TMC_OTPW);
TMC_REPORT("OT prewarn", TMC_DEBUG_OTPW);
#if ENABLED(MONITOR_DRIVER_STATUS)
TMC_REPORT("triggered\n OTP\t", TMC_OTPW_TRIGGERED);
#endif
@ -964,6 +981,7 @@
TMC_REPORT(" -start\t", TMC_HSTRT);
TMC_REPORT("Stallguard thrs", TMC_SGT);
TMC_REPORT("uStep count", TMC_MSCNT);
DRV_REPORT("DRVSTATUS", TMC_DRV_CODES);
#if HAS_TMCX1X0_OR_2240 || HAS_TMC220x
DRV_REPORT("sg_result", TMC_SG_RESULT);
@ -984,16 +1002,18 @@
DRV_REPORT("150C\t", TMC_T150);
DRV_REPORT("143C\t", TMC_T143);
DRV_REPORT("120C\t", TMC_T120);
#endif
#if HAS_TMC220x || HAS_DRIVER(TMC2240)
DRV_REPORT("s2vsa\t", TMC_S2VSA);
DRV_REPORT("s2vsb\t", TMC_S2VSB);
#endif
DRV_REPORT("Driver registers:\n",TMC_DRV_STATUS_HEX);
DRV_REPORT("Driver registers:\n", TMC_DRV_STATUS_HEX);
#if HAS_DRIVER(TMC2240)
TMC_REPORT("Analog in (v)", TMC_VAIN);
TMC_REPORT("Supply (v)", TMC_VSUPPLY);
TMC_REPORT("Temp (°C)", TMC_TEMP);
TMC_REPORT("OT pre warn (°C)", TMC_OVERTEMP);
TMC_REPORT("OV theshold (v)", TMC_OVERVOLT_THD);
TMC_REPORT("OV threshold (v)", TMC_OVERVOLT_THD);
#endif
SERIAL_EOL();
}
@ -1035,6 +1055,7 @@
}
SERIAL_CHAR('\t');
}
#endif // HAS_TRINAMIC_CONFIG
#if HAS_DRIVER(TMC2660)
@ -1147,6 +1168,9 @@
bool tmc_enable_stallguard(TMC2240Stepper &st) {
const bool stealthchop_was_enabled = st.en_pwm_mode();
// TODO: Use StallGuard4 when stealthChop is enabled
// and leave stealthChop state unchanged.
st.TCOOLTHRS(0xFFFFF);
st.en_pwm_mode(false);
st.diag0_stall(true);
@ -1230,75 +1254,3 @@ void test_tmc_connection(LOGICAL_AXIS_ARGS_LC(const bool)) {
}
#endif // HAS_TRINAMIC_CONFIG
#if HAS_TMC_SPI
#define SET_CS_PIN(st) OUT_WRITE(st##_CS_PIN, HIGH)
void tmc_init_cs_pins() {
#if AXIS_HAS_SPI(X)
SET_CS_PIN(X);
#endif
#if AXIS_HAS_SPI(Y)
SET_CS_PIN(Y);
#endif
#if AXIS_HAS_SPI(Z)
SET_CS_PIN(Z);
#endif
#if AXIS_HAS_SPI(X2)
SET_CS_PIN(X2);
#endif
#if AXIS_HAS_SPI(Y2)
SET_CS_PIN(Y2);
#endif
#if AXIS_HAS_SPI(Z2)
SET_CS_PIN(Z2);
#endif
#if AXIS_HAS_SPI(Z3)
SET_CS_PIN(Z3);
#endif
#if AXIS_HAS_SPI(Z4)
SET_CS_PIN(Z4);
#endif
#if AXIS_HAS_SPI(I)
SET_CS_PIN(I);
#endif
#if AXIS_HAS_SPI(J)
SET_CS_PIN(J);
#endif
#if AXIS_HAS_SPI(K)
SET_CS_PIN(K);
#endif
#if AXIS_HAS_SPI(U)
SET_CS_PIN(U);
#endif
#if AXIS_HAS_SPI(V)
SET_CS_PIN(V);
#endif
#if AXIS_HAS_SPI(W)
SET_CS_PIN(W);
#endif
#if AXIS_HAS_SPI(E0)
SET_CS_PIN(E0);
#endif
#if AXIS_HAS_SPI(E1)
SET_CS_PIN(E1);
#endif
#if AXIS_HAS_SPI(E2)
SET_CS_PIN(E2);
#endif
#if AXIS_HAS_SPI(E3)
SET_CS_PIN(E3);
#endif
#if AXIS_HAS_SPI(E4)
SET_CS_PIN(E4);
#endif
#if AXIS_HAS_SPI(E5)
SET_CS_PIN(E5);
#endif
#if AXIS_HAS_SPI(E6)
SET_CS_PIN(E6);
#endif
#if AXIS_HAS_SPI(E7)
SET_CS_PIN(E7);
#endif
}
#endif // HAS_TMC_SPI

View file

@ -434,7 +434,7 @@ void test_tmc_connection(LOGICAL_AXIS_DECL_LC(const bool, true));
bool TMCMarlin<TMC, AXIS_LETTER, DRIVER_ID, AXIS_ID>::test_stall_status() {
this->switchCSpin(LOW);
// read stallGuard flag from TMC library, will handle HW and SW SPI
// Read stallGuard flag from TMC library, will handle HW and SW SPI
TMC2130_n::DRV_STATUS_t drv_status{0};
drv_status.sr = this->DRV_STATUS();
@ -474,7 +474,3 @@ void test_tmc_connection(LOGICAL_AXIS_DECL_LC(const bool, true));
#endif // HAS_HOMING_CURRENT
#endif // HAS_TRINAMIC_CONFIG
#if HAS_TMC_SPI
void tmc_init_cs_pins();
#endif

View file

@ -45,14 +45,14 @@
/**
* M420: Enable/Disable Bed Leveling and/or set the Z fade height.
*
* S[bool] Turns leveling on or off
* Z[height] Sets the Z fade height (0 or none to disable)
* V[bool] Verbose - Print the leveling grid
* S<bool> Turns leveling on or off
* Z<height> Sets the Z fade height (0 or none to disable)
* V<bool> Verbose - Print the leveling grid
*
* With AUTO_BED_LEVELING_UBL only:
*
* L[index] Load UBL mesh from index (0 is default)
* T[map] 0:Human-readable 1:CSV 2:"LCD" 4:Compact
* L<index> Load UBL mesh from index (0 is default)
* T<map> 0:Human-readable 1:CSV 2:"LCD" 4:Compact
*
* With mesh-based leveling only:
*

View file

@ -156,81 +156,72 @@ public:
#endif
/**
* G29: Detailed Z probe, probes the bed at 3 or more points.
* Will fail if the printer has not been homed with G28.
* G29: Bed Leveling
*
* Enhanced G29 Auto Bed Leveling Probe Routine
* Enhanced G29 Auto Bed Leveling Probe Routine.
* Probes the bed at 3 or more points.
* Will fail if the printer has not been homed with G28.
*
* O Auto-level only if needed
* Parameters:
* O Auto-level only if needed (Optional)
*
* D Dry-Run mode. Just evaluate the bed Topology - Don't apply
* or alter the bed level data. Useful to check the topology
* after a first run of G29.
* D<bool> Dry-Run mode. Just evaluate the bed Topology -
* Don't apply or alter the bed level data.
* Useful to check the topology after a first run of G29.
*
* J Jettison current bed leveling data
* J<bool> Jettison current bed leveling data
*
* V Set the verbose level (0-4). Example: "G29 V3"
* V<0-4> Set the verbose level (0-4)
* Example: G29 V3
*
* Parameters With LINEAR leveling only:
* With AUTO_BED_LEVELING_LINEAR:
* P<int> Set the size of the grid that will be probed (P x P points)
* Example: G29 P4
*
* P Set the size of the grid that will be probed (P x P points).
* Example: "G29 P4"
* X<int> Set the X size of the grid that will be probed (X x Y points)
* Example: G29 X7 Y5
*
* X Set the X size of the grid that will be probed (X x Y points).
* Example: "G29 X7 Y5"
* Y<int> Set the Y size of the grid that will be probed (X x Y points)
*
* Y Set the Y size of the grid that will be probed (X x Y points).
* T Generate a Bed Topology Report
* Example: G29 P5 T - for a detailed report.
* This is useful for manual bed leveling and finding flaws in the bed
* (to assist with part placement).
* Not supported by non-linear delta printer bed leveling.
*
* T Generate a Bed Topology Report. Example: "G29 P5 T" for a detailed report.
* This is useful for manual bed leveling and finding flaws in the bed (to
* assist with part placement).
* Not supported by non-linear delta printer bed leveling.
* With AUTO_BED_LEVELING_LINEAR and AUTO_BED_LEVELING_BILINEAR:
* S<rate> Set the XY travel speed between probe points (in units/min)
* H<linear> Set bounds to a centered square H x H units in size
* -or-
* F<linear> Set the Front limit of the probing grid
* B<linear> Set the Back limit of the probing grid
* L<linear> Set the Left limit of the probing grid
* R<linear> Set the Right limit of the probing grid
*
* Parameters With LINEAR and BILINEAR leveling only:
* With AUTO_BED_LEVELING_BILINEAR:
* Z<float> Supply additional Z offset to all probe points.
* W<bool> Write a mesh point. (If G29 is idle.)
* I<index> Index for mesh point
* J<index> Index for mesh point
* X<float> For mesh point, overrides I
* Y<float> For mesh point, overrides J
* Z<float> For mesh point. If omitted, uses current position's raw Z
*
* S Set the XY travel speed between probe points (in units/min)
* With DEBUG_LEVELING_FEATURE:
* C<bool> Make a totally fake grid with no actual probing.
* For use in testing when no probing is possible.
*
* H Set bounds to a centered square H x H units in size
* With PROBE_MANUALLY:
* To do manual probing simply repeat G29 until the procedure is complete.
* The first G29 accepts parameters. 'G29 Q' for status, 'G29 A' to abort.
*
* -or-
* Q<bool> Query leveling and G29 state
* A<bool> Abort current leveling procedure
*
* F Set the Front limit of the probing grid
* B Set the Back limit of the probing grid
* L Set the Left limit of the probing grid
* R Set the Right limit of the probing grid
*
* Parameters with DEBUG_LEVELING_FEATURE only:
*
* C Make a totally fake grid with no actual probing.
* For use in testing when no probing is possible.
*
* Parameters with BILINEAR leveling only:
*
* Z Supply an additional Z probe offset
*
* Extra parameters with PROBE_MANUALLY:
*
* To do manual probing simply repeat G29 until the procedure is complete.
* The first G29 accepts parameters. 'G29 Q' for status, 'G29 A' to abort.
*
* Q Query leveling and G29 state
*
* A Abort current leveling procedure
*
* Extra parameters with BILINEAR only:
*
* W Write a mesh point. (If G29 is idle.)
* I X index for mesh point
* J Y index for mesh point
* X X for mesh point, overrides I
* Y Y for mesh point, overrides J
* Z Z for mesh point. Otherwise, raw current Z.
*
* Without PROBE_MANUALLY:
*
* E By default G29 will engage the Z probe, test the bed, then disengage.
* Include "E" to engage/disengage the Z probe for each sample.
* There's no extra effect if you have a fixed Z probe.
* Without PROBE_MANUALLY:
* E<bool> By default G29 will engage the Z probe, test the bed, then disengage
* Include "E" to engage/disengage the Z probe for each sample.
* There's no extra effect if you have a fixed Z probe.
*/
G29_TYPE GcodeSuite::G29() {
@ -855,15 +846,15 @@ G29_TYPE GcodeSuite::G29() {
}
#endif // !PROBE_MANUALLY
//
// G29 Finishing Code
//
// Unless this is a dry run, auto bed leveling will
// definitely be enabled after this point.
//
// If code above wants to continue leveling, it should
// return or loop before this point.
//
/**
* G29 Finishing Code
*
* Unless this is a dry run, auto bed leveling will
* definitely be enabled after this point.
*
* If code above wants to continue leveling, it should
* return or loop before this point.
*/
if (DEBUGGING(LEVELING)) DEBUG_POS("> probing complete", current_position);
@ -892,12 +883,12 @@ G29_TYPE GcodeSuite::G29() {
// For LINEAR leveling calculate matrix, print reports, correct the position
/**
* solve the plane equation ax + by + d = z
* Solve the plane equation ax + by + d = z
* A is the matrix with rows [x y 1] for all the probed points
* B is the vector of the Z positions
* the normal vector to the plane is formed by the coefficients of the
* The normal vector to the plane is formed by the coefficients of the
* plane equation in the standard form, which is Vx*x+Vy*y+Vz*z+d = 0
* so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z
* so Vx = -a Vy = -b Vz = 1 (we want the vector facing towards positive Z).
*/
struct { float a, b, d; } plane_equation_coefficients;

View file

@ -200,11 +200,12 @@
#endif // IMPROVE_HOMING_RELIABILITY
/**
* G28: Home all axes according to settings
* G28: Auto Home
*
* Parameters
* Home all axes according to settings
*
* None Home to all axes with no parameters.
* Parameters:
* None Home all axes
* With QUICK_HOME enabled XY will home together, then Z.
*
* L<bool> Force leveling state ON (if possible) or OFF after homing (Requires RESTORE_LEVELING_AFTER_G28 or ENABLE_LEVELING_AFTER_G28)
@ -216,7 +217,7 @@
* fail with position unreachable due to probe/nozzle offset. This
* can be used to avoid a model.
*
* Cartesian/SCARA parameters
* Cartesian/SCARA parameters:
*
* X Home to the X endstop
* Y Home to the Y endstop

View file

@ -41,8 +41,8 @@
constexpr uint8_t _7P_STEP = 1, // 7-point step - to change number of calibration points
_4P_STEP = _7P_STEP * 2, // 4-point step
NPP = _7P_STEP * 6; // number of calibration points on the radius
enum CalEnum : char { // the 7 main calibration points - add definitions if needed
NPP = _7P_STEP * 6; // Number of calibration points on the radius
enum CalEnum : char { // The 7 main calibration points - add definitions if needed
CEN = 0,
__A = 1,
_AB = __A + _7P_STEP,
@ -197,13 +197,13 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
if (!_0p_calibration) {
if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // probe the center
if (!_7p_no_intermediates && !_7p_4_intermediates && !_7p_11_intermediates) { // Probe the center
const xy_pos_t center{0};
z_pt[CEN] += calibration_probe(center, stow_after_each, probe_at_offset);
if (isnan(z_pt[CEN])) return false;
}
if (_7p_calibration) { // probe extra center points
if (_7p_calibration) { // Probe extra center points
const float start = _7p_9_center ? float(_CA) + _7P_STEP / 3.0f : _7p_6_center ? float(_CA) : float(__C),
steps = _7p_9_center ? _4P_STEP / 3.0f : _7p_6_center ? _7P_STEP : _4P_STEP;
I_LOOP_CAL_PT(rad, start, steps) {
@ -216,7 +216,7 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
z_pt[CEN] /= float(_7p_2_intermediates ? 7 : probe_points);
}
if (!_1p_calibration) { // probe the radius
if (!_1p_calibration) { // Probe the radius
const CalEnum start = _4p_opposite_points ? _AB : __A;
const float steps = _7p_14_intermediates ? _7P_STEP / 15.0f : // 15r * 6 + 10c = 100
_7p_11_intermediates ? _7P_STEP / 12.0f : // 12r * 6 + 9c = 81
@ -254,10 +254,11 @@ static bool probe_calibration_points(float z_pt[NPP + 1], const int8_t probe_poi
}
/**
* kinematics routines and auto tune matrix scaling parameters:
* see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for
* - formulae for approximative forward kinematics in the end-stop displacement matrix
* - definition of the matrix scaling parameters
* Kinematics routines and auto tune matrix scaling parameters
*
* NOTE: See https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for:
* - Formula for approximative forward kinematics in the end-stop displacement matrix
* - Definition of the matrix scaling parameters
*/
static void reverse_kinematics_probe_points(float z_pt[NPP + 1], abc_float_t mm_at_pt_axis[NPP + 1], const float dcr) {
xyz_pos_t pos{0};
@ -346,43 +347,43 @@ static float auto_tune_a(const float dcr) {
}
/**
* G33 - Delta '1-4-7-point' Auto-Calibration
* Calibrate height, z_offset, endstops, delta radius, and tower angles.
* G33: Delta Auto Calibration
*
* Calibrate height, z_offset, endstops, delta radius, and tower angles.
*
* Parameters:
* P<int> Number of probe points:
* P0 Normalizes end-stops and tower angle corrections only (no probing)
* P1 Probe center and set height only
* P2 Probe center and towers. Set height, endstops, and delta radius
* P3 Probe all positions - center, towers and opposite towers. Set all
* P4-P10 Probe all positions with intermediate locations, averaging them
*
* Pn Number of probe points:
* P0 Normalizes calibration.
* P1 Calibrates height only with center probe.
* P2 Probe center and towers. Calibrate height, endstops and delta radius.
* P3 Probe all positions: center, towers and opposite towers. Calibrate all.
* P4-P10 Probe all positions at different intermediate locations and average them.
* R<float> Temporarily reduce the size of the probe grid by the specified amount
*
* Rn.nn Temporary reduce the probe grid by the specified amount (mm)
* T<bool> Disable tower angle corrections calibration (P3-P7)
*
* T Don't calibrate tower angle corrections
* C<float> Calibration precision; if omitted iterations stop at best achievable precision
*
* Cn.nn Calibration precision; when omitted calibrates to maximum precision
* F<1-30> Run (force) this number of iterations and take the best result
*
* Fn Force to run at least n iterations and take the best result
* V<int> Verbose level:
* V0 Dry-run mode. Report settings and probe results. No calibration
* V1 Report start and end settings only
* V2 Report settings at each iteration
* V3 Report settings and probe results
*
* Vn Verbose level:
* V0 Dry-run mode. Report settings and probe results. No calibration.
* V1 Report start and end settings only
* V2 Report settings at each iteration
* V3 Report settings and probe results
* E<bool> Engage the probe for each point
*
* E Engage the probe for each point
* O<bool> Probe at probe-offset-relative positions instead of the required kinematic points
*
* O Probe at offsetted probe positions (this is wrong but it seems to work)
*
* With SENSORLESS_PROBING:
* Use these flags to calibrate stall sensitivity: (e.g., `G33 P1 Y Z` to calibrate X only.)
* X Don't activate stallguard on X.
* Y Don't activate stallguard on Y.
* Z Don't activate stallguard on Z.
*
* S Save offset_sensorless_adj
* With HAS_DELTA_SENSORLESS_PROBING:
* Use these flags to calibrate stall sensitivity:
* Example: G33 P1 Y Z - to calibrate X only
* X Don't activate stallguard on X
* Y Don't activate stallguard on Y
* Z Don't activate stallguard on Z
* S Save offset_sensorless_adj
*/
void GcodeSuite::G33() {
@ -481,11 +482,11 @@ void GcodeSuite::G33() {
caltower({ false, true, false }); // B
caltower({ false, false, true }); // C
probe.test_sensitivity = { true, true, true }; // reset to all
probe.test_sensitivity = { true, true, true }; // Reset to all
}
#endif
do { // start iterations
do { // Start iterations
float z_at_pt[NPP + 1] = { 0.0f };
@ -505,11 +506,11 @@ void GcodeSuite::G33() {
if ((zero_std_dev < test_precision || iterations <= force_iterations) && zero_std_dev > calibration_precision) {
#if !HAS_BED_PROBE
test_precision = 0.0f; // forced end
test_precision = 0.0f; // Forced end
#endif
if (zero_std_dev < zero_std_dev_min) {
// set roll-back point
// Set roll-back point
e_old = delta_endstop_adj;
r_old = delta_radius;
h_old = delta_height;
@ -520,10 +521,11 @@ void GcodeSuite::G33() {
float r_delta = 0.0f;
/**
* convergence matrices:
* see https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for
* - definition of the matrix scaling parameters
* - matrices for 4 and 7 point calibration
* Convergence matrices
*
* NOTE: See https://github.com/LVD-AC/Marlin-AC/tree/1.1.x-AC/documentation for:
* - Definition of the matrix scaling parameters
* - Matrices for 4 and 7 point calibration
*/
#define ZP(N,I) ((N) * z_at_pt[I] / 4.0f) // 4.0 = divider to normalize to integers
#define Z12(I) ZP(12, I)
@ -532,7 +534,7 @@ void GcodeSuite::G33() {
#define Z1(I) ZP(1, I)
#define Z0(I) ZP(0, I)
// calculate factors
// Calculate factors
if (_7p_9_center) dcr *= 0.9f;
h_factor = auto_tune_h(dcr);
r_factor = auto_tune_r(dcr);
@ -541,22 +543,22 @@ void GcodeSuite::G33() {
switch (probe_points) {
case 0:
test_precision = 0.0f; // forced end
test_precision = 0.0f; // Forced end
break;
case 1:
test_precision = 0.0f; // forced end
test_precision = 0.0f; // Forced end
LOOP_NUM_AXES(axis) e_delta[axis] = +Z4(CEN);
break;
case 2:
if (towers_set) { // see 4 point calibration (towers) matrix
if (towers_set) { // See 4 point calibration (towers) matrix
e_delta.set((+Z4(__A) -Z2(__B) -Z2(__C)) * h_factor +Z4(CEN),
(-Z2(__A) +Z4(__B) -Z2(__C)) * h_factor +Z4(CEN),
(-Z2(__A) -Z2(__B) +Z4(__C)) * h_factor +Z4(CEN));
r_delta = (+Z4(__A) +Z4(__B) +Z4(__C) -Z12(CEN)) * r_factor;
}
else { // see 4 point calibration (opposites) matrix
else { // See 4 point calibration (opposites) matrix
e_delta.set((-Z4(_BC) +Z2(_CA) +Z2(_AB)) * h_factor +Z4(CEN),
(+Z2(_BC) -Z4(_CA) +Z2(_AB)) * h_factor +Z4(CEN),
(+Z2(_BC) +Z2(_CA) -Z4(_AB)) * h_factor +Z4(CEN));
@ -564,13 +566,13 @@ void GcodeSuite::G33() {
}
break;
default: // see 7 point calibration (towers & opposites) matrix
default: // See 7 point calibration (towers & opposites) matrix
e_delta.set((+Z2(__A) -Z1(__B) -Z1(__C) -Z2(_BC) +Z1(_CA) +Z1(_AB)) * h_factor +Z4(CEN),
(-Z1(__A) +Z2(__B) -Z1(__C) +Z1(_BC) -Z2(_CA) +Z1(_AB)) * h_factor +Z4(CEN),
(-Z1(__A) -Z1(__B) +Z2(__C) +Z1(_BC) +Z1(_CA) -Z2(_AB)) * h_factor +Z4(CEN));
r_delta = (+Z2(__A) +Z2(__B) +Z2(__C) +Z2(_BC) +Z2(_CA) +Z2(_AB) -Z12(CEN)) * r_factor;
if (towers_set) { // see 7 point tower angle calibration (towers & opposites) matrix
if (towers_set) { // See 7 point tower angle calibration (towers & opposites) matrix
t_delta.set((+Z0(__A) -Z4(__B) +Z4(__C) +Z0(_BC) -Z4(_CA) +Z4(_AB) +Z0(CEN)) * a_factor,
(+Z4(__A) +Z0(__B) -Z4(__C) +Z4(_BC) +Z0(_CA) -Z4(_AB) +Z0(CEN)) * a_factor,
(-Z4(__A) +Z4(__B) +Z0(__C) -Z4(_BC) +Z4(_CA) +Z0(_AB) +Z0(CEN)) * a_factor);
@ -582,14 +584,14 @@ void GcodeSuite::G33() {
delta_tower_angle_trim += t_delta;
}
else if (zero_std_dev >= test_precision) {
// roll back
// Roll back
delta_endstop_adj = e_old;
delta_radius = r_old;
delta_height = h_old;
delta_tower_angle_trim = a_old;
}
if (verbose_level != 0) { // !dry run
if (verbose_level != 0) { // !Dry-run
// Normalize angles to least-squares
if (_angle_results) {
@ -620,7 +622,7 @@ void GcodeSuite::G33() {
#endif
}
if (verbose_level != 0) { // !dry run
if (verbose_level != 0) { // !Dry-run
if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations
SERIAL_ECHOPGM("Calibration OK");
SERIAL_ECHO_SP(32);
@ -657,7 +659,7 @@ void GcodeSuite::G33() {
print_calibration_settings(_endstop_results, _angle_results);
}
}
else { // dry run
else { // Dry-run
FSTR_P const enddryrun = F("End DRY-RUN");
SERIAL_ECHO(enddryrun);
SERIAL_ECHO_SP(35);

View file

@ -40,7 +40,9 @@
#include "../../core/debug_out.h"
/**
* G34 - Align the ends of the X gantry. See https://youtu.be/3jAFQdTk8iw
* G34: Mechanical Gantry Calibration
*
* Align the ends of the X gantry. See https://youtu.be/3jAFQdTk8iw
*
* - The carriage moves to GANTRY_CALIBRATION_SAFE_POSITION, also called the pounce position.
* - If possible, the Z stepper current is reduced to the value specified by 'S'
@ -53,8 +55,8 @@
* - The machine is re-homed, according to GANTRY_CALIBRATION_COMMANDS_POST.
*
* Parameters:
* [S<mA>] - Current value to use for the raise move. (Default: GANTRY_CALIBRATION_CURRENT)
* [Z<linear>] - Extra distance past Z_MAX_POS to move the Z axis. (Default: GANTRY_CALIBRATION_EXTRA_HEIGHT)
* S<mA> Current value to use for the raise move. (Default: GANTRY_CALIBRATION_CURRENT)
* Z<linear> Extra distance past Z_MAX_POS to move the Z axis. (Default: GANTRY_CALIBRATION_EXTRA_HEIGHT)
*/
void GcodeSuite::G34() {

View file

@ -56,23 +56,24 @@
#endif
/**
* G34: Z-Stepper automatic alignment
* G34: Z Steppers Auto-Alignment
*
* Manual stepper lock controls (reset by G28):
* L Unlock all steppers
* Z<1-4> Z stepper to lock / unlock
* S<state> 0=UNLOCKED 1=LOCKED. If omitted, assume LOCKED.
* Parameters:
* Manual stepper lock controls (reset by G28):
* L Unlock all steppers
* Z<int> Target specific Z stepper to lock/unlock (1-4)
* S<bool> Lock state; 0=UNLOCKED 1=LOCKED. If omitted, assume LOCKED
*
* Examples:
* G34 Z1 ; Lock Z1
* G34 L Z2 ; Unlock all, then lock Z2
* G34 Z2 S0 ; Unlock Z2
* With Z_STEPPER_AUTO_ALIGN:
* I<int> Number of test iterations. If omitted, Z_STEPPER_ALIGN_ITERATIONS. (1-30)
* T<float> Target Accuracy factor. If omitted, Z_STEPPER_ALIGN_ACC. (0.01-1.0)
* A<float> Provide an Amplification value. If omitted, Z_STEPPER_ALIGN_AMP. (0.5-2.0)
* R Recalculate points based on current probe offsets
*
* With Z_STEPPER_AUTO_ALIGN:
* I<iterations> Number of tests. If omitted, Z_STEPPER_ALIGN_ITERATIONS.
* T<accuracy> Target Accuracy factor. If omitted, Z_STEPPER_ALIGN_ACC.
* A<amplification> Provide an Amplification value. If omitted, Z_STEPPER_ALIGN_AMP.
* R Flag to recalculate points based on current probe offsets
* Example:
* G34 Z1 ; Lock Z1
* G34 L Z2 ; Unlock all, then lock Z2
* G34 Z2 S0 ; Unlock Z2
*/
void GcodeSuite::G34() {
@ -142,6 +143,11 @@ void GcodeSuite::G34() {
probe.use_probing_tool();
#ifdef EVENT_GCODE_BEFORE_G34
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("Before G34 G-code: ", F(EVENT_GCODE_BEFORE_G34));
gcode.process_subcommands_now(F(EVENT_GCODE_BEFORE_G34));
#endif
TERN_(HAS_DUPLICATION_MODE, set_duplication_enabled(false));
// Compute a worst-case clearance height to probe from. After the first
@ -213,19 +219,20 @@ void GcodeSuite::G34() {
// Probing sanity check is disabled, as it would trigger even in normal cases because
// current_position.z has been manually altered in the "dirty trick" above.
if (DEBUGGING(LEVELING))
DEBUG_ECHOLNPGM(
"Z_PROBE_LOW_POINT: ", p_float_t(Z_PROBE_LOW_POINT, 2),
"z_probe: ", p_float_t(z_probe, 2),
"Probe Tgt: ", p_float_t((Z_PROBE_LOW_POINT) - z_probe * 0.5f, 2)
);
const float minz = (Z_PROBE_LOW_POINT) - (z_probe * 0.5f);
if (DEBUGGING(LEVELING)) {
DEBUG_ECHOPGM("Z_PROBE_LOW_POINT: " STRINGIFY(Z_PROBE_LOW_POINT));
DEBUG_ECHOLNPGM(" z_probe: ", p_float_t(z_probe, 3),
" Probe Tgt: ", p_float_t(minz, 3));
}
const float z_probed_height = probe.probe_at_point(
DIFF_TERN(HAS_HOME_OFFSET, ppos, xy_pos_t(home_offset)), // xy
raise_after, // raise_after
(DEBUGGING(LEVELING) || DEBUGGING(INFO)) ? 3 : 0, // verbose_level
true, false, // probe_relative, sanity_check
(Z_PROBE_LOW_POINT) - (z_probe * 0.5f), // z_min_point
minz, // z_min_point
Z_TWEEN_SAFE_CLEARANCE // z_clearance
);
@ -302,7 +309,7 @@ void GcodeSuite::G34() {
SERIAL_EOL();
SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("1:2="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
SString<15 + TERN0(TRIPLE_Z, 30) + TERN0(QUAD_Z, 45)> msg(F("2-1="), p_float_t(ABS(z_measured[1] - z_measured[0]), 3));
#if TRIPLE_Z
msg.append(F(" 3-2="), p_float_t(ABS(z_measured[2] - z_measured[1]), 3))
.append(F(" 3-1="), p_float_t(ABS(z_measured[2] - z_measured[0]), 3));
@ -413,7 +420,7 @@ void GcodeSuite::G34() {
SERIAL_ECHOLNPGM("G34 aborted.");
else {
SERIAL_ECHOLNPGM("Did ", iteration + (iteration != z_auto_align_iterations), " of ", z_auto_align_iterations);
SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 2));
SERIAL_ECHOLNPGM("Accuracy: ", p_float_t(z_maxdiff, 3));
}
// Stow the probe because the last call to probe.probe_at_point(...)
@ -429,9 +436,9 @@ void GcodeSuite::G34() {
// Ideally, this would be equal to the 'z_probe * 0.5f' which was added earlier.
if (DEBUGGING(LEVELING))
DEBUG_ECHOLNPGM(
"z_measured_min: ", p_float_t(z_measured_min, 2),
"Z_TWEEN_SAFE_CLEARANCE: ", p_float_t(Z_TWEEN_SAFE_CLEARANCE, 2),
"zoffs: ", p_float_t(zoffs, 2)
"z_measured_min: ", p_float_t(z_measured_min, 3),
"Z_TWEEN_SAFE_CLEARANCE: ", p_float_t(Z_TWEEN_SAFE_CLEARANCE, 3),
"zoffs: ", p_float_t(zoffs, 3)
);
if (!err_break)
@ -439,6 +446,12 @@ void GcodeSuite::G34() {
sync_plan_position();
#endif
#ifdef EVENT_GCODE_AFTER_G34
if (DEBUGGING(LEVELING)) DEBUG_ECHOLNPGM("After G34 G-code: ", F(EVENT_GCODE_AFTER_G34));
planner.synchronize();
process_subcommands_now(F(EVENT_GCODE_AFTER_G34));
#endif
probe.use_probing_tool(false);
#if ALL(HAS_LEVELING, RESTORE_LEVELING_AFTER_G34)

View file

@ -100,7 +100,9 @@
enum side_t : uint8_t {
TOP, RIGHT, FRONT, LEFT, BACK, NUM_SIDES,
LIST_N(DOUBLE(SECONDARY_AXES), IMINIMUM, IMAXIMUM, JMINIMUM, JMAXIMUM, KMINIMUM, KMAXIMUM, UMINIMUM, UMAXIMUM, VMINIMUM, VMAXIMUM, WMINIMUM, WMAXIMUM)
LIST_N(DOUBLE(SECONDARY_AXES),
IMINIMUM, IMAXIMUM, JMINIMUM, JMAXIMUM, KMINIMUM, KMAXIMUM,
UMINIMUM, UMAXIMUM, VMINIMUM, VMAXIMUM, WMINIMUM, WMAXIMUM)
};
static constexpr xyz_pos_t true_center CALIBRATION_OBJECT_CENTER;

View file

@ -38,47 +38,53 @@
#include "../../lcd/marlinui.h"
/**
* G76: calibrate probe and/or bed temperature offsets
* Notes:
* - When calibrating probe, bed temperature is held constant.
* Compensation values are deltas to first probe measurement at probe temp. = 30°C.
* - When calibrating bed, probe temperature is held constant.
* Compensation values are deltas to first probe measurement at bed temp. = 60°C.
* - The hotend will not be heated at any time.
* - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
* so the hotend fan would not cool my probe constantly. Alternatively you could just
* make sure the fan is not running while running the calibration process.
* G76: Probe Temperature Calibration
*
* Probe calibration:
* - Moves probe to cooldown point.
* - Heats up bed to 100°C.
* - Moves probe to probing point (1mm above heatbed).
* - Waits until probe reaches target temperature (30°C).
* - Does a z-probing (=base value) and increases target temperature by 5°C.
* - Waits until probe reaches increased target temperature.
* - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C.
* - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further).
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
* While this is not exact by any means it is still better than simply using the last compensation value.
* Calibrate probe and/or bed temperature offsets.
*
* Bed calibration:
* - Moves probe to cooldown point.
* - Heats up bed to 60°C.
* - Moves probe to probing point (1mm above heatbed).
* - Waits until probe reaches target temperature (30°C).
* - Does a z-probing (=base value) and increases bed temperature by 5°C.
* - Moves probe to cooldown point.
* - Waits until probe is below 30°C and bed has reached target temperature.
* - Moves probe to probing point and waits until it reaches target temperature (30°C).
* - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C.
* - Repeats last four points until max. bed temperature reached (110°C) or timeout.
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
* While this is not exact by any means it is still better than simply using the last compensation value.
* Probe calibration:
* - Moves probe to cooldown point.
* - Heats up bed to 100°C.
* - Moves probe to probing point (1mm above heatbed).
* - Waits until probe reaches target temperature (30°C).
* - Does a z-probing (=base value) and increases target temperature by 5°C.
* - Waits until probe reaches increased target temperature.
* - Does a z-probing (delta to base value will be a compensation value) and increases target temperature by 5°C.
* - Repeats last two steps until max. temperature reached or timeout (i.e. probe does not heat up any further).
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
* While this is not exact by any means it is still better than simply using the last compensation value.
*
* G76 [B | P]
* - no flag - Both calibration procedures will be run.
* - `B` - Run bed temperature calibration.
* - `P` - Run probe temperature calibration.
* Bed calibration:
* - Moves probe to cooldown point.
* - Heats up bed to 60°C.
* - Moves probe to probing point (1mm above heatbed).
* - Waits until probe reaches target temperature (30°C).
* - Does a z-probing (=base value) and increases bed temperature by 5°C.
* - Moves probe to cooldown point.
* - Waits until probe is below 30°C and bed has reached target temperature.
* - Moves probe to probing point and waits until it reaches target temperature (30°C).
* - Does a z-probing (delta to base value will be a compensation value) and increases bed temperature by 5°C.
* - Repeats last four points until max. bed temperature reached (110°C) or timeout.
* - Compensation values of higher temperatures will be extrapolated (using linear regression first).
* While this is not exact by any means it is still better than simply using the last compensation value.
*
* Usage:
* G76 [ B | P ]
*
* Parameters:
* None Run Both calibration procedures
* B Calibrate bed only
* P Calibrate probe only
*
* NOTES:
* - When calibrating probe, bed temperature is held constant.
* Compensation values are deltas to first probe measurement at probe temp. = 30°C.
* - When calibrating bed, probe temperature is held constant.
* Compensation values are deltas to first probe measurement at bed temp. = 60°C.
* - The hotend will not be heated at any time.
* - On my Průša MK3S clone I put a piece of paper between the probe and the hotend
* so the hotend fan would not cool my probe constantly. Alternatively you could just
* make sure the fan is not running while running the calibration process.
*/
#if ALL(PTC_PROBE, PTC_BED)
@ -291,22 +297,26 @@
#endif // PTC_PROBE && PTC_BED
/**
* M871: Report / reset temperature compensation offsets.
* Note: This does not affect values in EEPROM until M500.
* M871: Probe Temperature Config
*
* Report / reset temperature compensation offsets.
* NOTE: This does not affect values in EEPROM until M500.
*
* Usage:
* M871 [ R | B | P | E ]
*
* No Parameters - Print current offset values.
* Parameters:
* None Print current offset values
*
* Select only one of these flags:
* R - Reset all offsets to zero (i.e., disable compensation).
* B - Manually set offset for bed
* P - Manually set offset for probe
* E - Manually set offset for extruder
* Select only one of these flags:
* R Reset all offsets to zero (i.e., disable compensation)
* B Manually set offset for bed
* P Manually set offset for probe
* E Manually set offset for extruder
*
* With B, P, or E:
* I[index] - Index in the array
* V[value] - Adjustment in µm
* With B, P, or E:
* I<index> Index in the array
* V<value> Adjustment in µm
*/
void GcodeSuite::M871() {

View file

@ -31,32 +31,32 @@
#include "../../MarlinCore.h" // for idle()
/**
* M100 Free Memory Watcher
* M100: Free Memory Watcher
*
* This code watches the free memory block between the bottom of the heap and the top of the stack.
* This memory block is initialized and watched via the M100 command.
*
* M100 I Initializes the free memory block and prints vitals statistics about the area
* Parameters:
* I Initializes the free memory block and prints vitals statistics about the area
*
* M100 F Identifies how much of the free memory block remains free and unused. It also
* detects and reports any corruption within the free memory block that may have
* happened due to errant firmware.
* F Identifies how much of the free memory block remains free and unused. It also
* detects and reports any corruption within the free memory block that may have
* happened due to errant firmware.
*
* M100 D Does a hex display of the free memory block along with a flag for any errant
* data that does not match the expected value.
* D Does a hex display of the free memory block along with a flag for any errant
* data that does not match the expected value.
*
* M100 C x Corrupts x locations within the free memory block. This is useful to check the
* correctness of the M100 F and M100 D commands.
* C x Corrupts x locations within the free memory block. This is useful to check the
* correctness of the M100 F and M100 D commands.
*
* Also, there are two support functions that can be called from a developer's C code.
*
* uint16_t check_for_free_memory_corruption(PGM_P const free_memory_start);
* void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size);
* uint16_t check_for_free_memory_corruption(PGM_P const free_memory_start);
* void M100_dump_routine(FSTR_P const title, const char * const start, const uintptr_t size);
*
* Initial version by Roxy-3D
*/
#define M100_FREE_MEMORY_DUMPER // Enable for the `M100 D` Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Enable for the `M100 C` Corrupt sub-command
#define M100_FREE_MEMORY_DUMPER // Enable for the 'M100 D' Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Enable for the 'M100 C' Corrupt sub-command
#define TEST_BYTE ((char) 0xE5)

View file

@ -109,25 +109,26 @@ void GcodeSuite::M425_report(const bool forReplay/*=true*/) {
TERN_(MARLIN_SMALL_BUILD, return);
report_heading_etc(forReplay, F(STR_BACKLASH_COMPENSATION));
SERIAL_ECHOLNPGM_P(
SERIAL_ECHOPGM_P(
PSTR(" M425 F"), backlash.get_correction()
#ifdef BACKLASH_SMOOTHING_MM
, PSTR(" S"), LINEAR_UNIT(backlash.get_smoothing_mm())
#endif
#if NUM_AXES
, LIST_N(DOUBLE(NUM_AXES),
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
SP_I_STR, I_AXIS_UNIT(backlash.get_distance_mm(I_AXIS)),
SP_J_STR, J_AXIS_UNIT(backlash.get_distance_mm(J_AXIS)),
SP_K_STR, K_AXIS_UNIT(backlash.get_distance_mm(K_AXIS)),
SP_U_STR, U_AXIS_UNIT(backlash.get_distance_mm(U_AXIS)),
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
)
#endif
);
#if NUM_AXES
SERIAL_ECHOPGM_P(NUM_AXIS_PAIRED_LIST(
SP_X_STR, LINEAR_UNIT(backlash.get_distance_mm(X_AXIS)),
SP_Y_STR, LINEAR_UNIT(backlash.get_distance_mm(Y_AXIS)),
SP_Z_STR, LINEAR_UNIT(backlash.get_distance_mm(Z_AXIS)),
SP_I_STR, I_AXIS_UNIT(backlash.get_distance_mm(I_AXIS)),
SP_J_STR, J_AXIS_UNIT(backlash.get_distance_mm(J_AXIS)),
SP_K_STR, K_AXIS_UNIT(backlash.get_distance_mm(K_AXIS)),
SP_U_STR, U_AXIS_UNIT(backlash.get_distance_mm(U_AXIS)),
SP_V_STR, V_AXIS_UNIT(backlash.get_distance_mm(V_AXIS)),
SP_W_STR, W_AXIS_UNIT(backlash.get_distance_mm(W_AXIS))
));
#endif
SERIAL_EOL();
}
#endif // BACKLASH_GCODE

View file

@ -39,7 +39,15 @@
#if ENABLED(DELTA)
/**
* M666: Set delta endstop adjustment
* M666: Set Delta endstop adjustments
*
* Adjust the endstop offsets on a Delta printer.
*
* Parameters:
* None Report current offsets
* X<intint> Adjustment for the X actuator endstop
* Y<intint> Adjustment for the Y actuator endstop
* Z<int> Adjustment for the Z actuator endstop
*/
void GcodeSuite::M666() {
DEBUG_SECTION(log_M666, "M666", DEBUGGING(LEVELING));
@ -74,14 +82,22 @@
#else
/**
* M666: Set Dual Endstops offsets for X, Y, and/or Z.
* With no parameters report current offsets.
* M666: Set Dual Endstop Offsets
*
* For Triple / Quad Z Endstops:
* Set Z2 Only: M666 S2 Z<offset>
* Set Z3 Only: M666 S3 Z<offset>
* Set Z4 Only: M666 S4 Z<offset>
* Set All: M666 Z<offset>
* Adjust the offsets for dual (or multiple) endstops.
*
* Parameters:
* None Report current offsets
* X<int> Offset for the X axis endstops
* Y<int> Offset for the Y axis endstops
* Z<int> Offset for the Z axis endstops
*
* Example:
* For Triple / Quad Z Endstops:
* M666 S2 Z<offset> ; Set Z2 Only
* M666 S3 Z<offset> ; Set Z3 Only
* M666 S4 Z<offset> ; Set Z4 Only
* M666 Z<offset> ; Set All
*/
void GcodeSuite::M666() {
if (!parser.seen_any()) return M666_report();

View file

@ -28,12 +28,16 @@
#include "../../module/planner.h"
/**
* M852: Get or set the machine skew factors. Reports current values with no arguments.
* M852: Bed Skew Compensation
*
* S[xy_factor] - Alias for 'I'
* I[xy_factor] - New XY skew factor
* J[xz_factor] - New XZ skew factor
* K[yz_factor] - New YZ skew factor
* Get or set the machine skew factors; correct for misalignment
*
* Parameters:
* None Report current values
* S<xy_factor> Alias for 'I'
* I<xy_factor> New XY skew factor
* J<xz_factor> New XZ skew factor
* K<yz_factor> New YZ skew factor
*/
void GcodeSuite::M852() {
if (!parser.seen("SIJK")) return M852_report();

View file

@ -157,19 +157,17 @@ void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
#if NUM_AXES
eol = true;
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
SP_I_STR, I_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
SP_J_STR, J_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
SP_K_STR, K_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]),
SP_U_STR, U_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[U_AXIS]),
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
)
);
SERIAL_ECHOPGM_P(NUM_AXIS_PAIRED_LIST(
PSTR(" M201 X"), LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_acceleration_mm_per_s2[Z_AXIS]),
SP_I_STR, I_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[I_AXIS]),
SP_J_STR, J_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[J_AXIS]),
SP_K_STR, K_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[K_AXIS]),
SP_U_STR, U_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[U_AXIS]),
SP_V_STR, V_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[V_AXIS]),
SP_W_STR, W_AXIS_UNIT(planner.settings.max_acceleration_mm_per_s2[W_AXIS])
));
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
@ -224,19 +222,17 @@ void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
#if NUM_AXES
eol = true;
SERIAL_ECHOPGM_P(
LIST_N(DOUBLE(NUM_AXES),
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]),
SP_U_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[U_AXIS]),
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
)
);
SERIAL_ECHOPGM_P(NUM_AXIS_PAIRED_LIST(
PSTR(" M203 X"), LINEAR_UNIT(planner.settings.max_feedrate_mm_s[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[Z_AXIS]),
SP_I_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[I_AXIS]),
SP_J_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[J_AXIS]),
SP_K_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[K_AXIS]),
SP_U_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[U_AXIS]),
SP_V_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[V_AXIS]),
SP_W_STR, LINEAR_UNIT(planner.settings.max_feedrate_mm_s[W_AXIS])
));
#endif
#if HAS_EXTRUDERS && DISABLED(DISTINCT_E_FACTORS)
@ -377,7 +373,7 @@ void GcodeSuite::M205_report(const bool forReplay/*=true*/) {
, PSTR(" J"), LINEAR_UNIT(planner.junction_deviation_mm)
#endif
#if ENABLED(CLASSIC_JERK) && NUM_AXES
, LIST_N(DOUBLE(NUM_AXES),
, NUM_AXIS_PAIRED_LIST(
SP_X_STR, LINEAR_UNIT(planner.max_jerk.x),
SP_Y_STR, LINEAR_UNIT(planner.max_jerk.y),
SP_Z_STR, LINEAR_UNIT(planner.max_jerk.z),

View file

@ -82,19 +82,17 @@ void GcodeSuite::M210_report(const bool forReplay/*=true*/) {
report_heading_etc(forReplay, F(STR_HOMING_FEEDRATE));
SERIAL_ECHOPGM(" M210");
SERIAL_ECHOLNPGM_P(
LIST_N(DOUBLE(NUM_AXES)
, SP_X_STR, X_AXIS_UNIT(homing_feedrate_mm_m.x)
, SP_Y_STR, Y_AXIS_UNIT(homing_feedrate_mm_m.y)
, SP_Z_STR, Z_AXIS_UNIT(homing_feedrate_mm_m.z)
, SP_I_STR, I_AXIS_UNIT(homing_feedrate_mm_m.i)
, SP_J_STR, J_AXIS_UNIT(homing_feedrate_mm_m.j)
, SP_K_STR, K_AXIS_UNIT(homing_feedrate_mm_m.k)
, SP_U_STR, U_AXIS_UNIT(homing_feedrate_mm_m.u)
, SP_V_STR, V_AXIS_UNIT(homing_feedrate_mm_m.v)
, SP_W_STR, W_AXIS_UNIT(homing_feedrate_mm_m.w)
)
);
SERIAL_ECHOLNPGM_P(NUM_AXIS_PAIRED_LIST(
SP_X_STR, X_AXIS_UNIT(homing_feedrate_mm_m.x),
SP_Y_STR, Y_AXIS_UNIT(homing_feedrate_mm_m.y),
SP_Z_STR, Z_AXIS_UNIT(homing_feedrate_mm_m.z),
SP_I_STR, I_AXIS_UNIT(homing_feedrate_mm_m.i),
SP_J_STR, J_AXIS_UNIT(homing_feedrate_mm_m.j),
SP_K_STR, K_AXIS_UNIT(homing_feedrate_mm_m.k),
SP_U_STR, U_AXIS_UNIT(homing_feedrate_mm_m.u),
SP_V_STR, V_AXIS_UNIT(homing_feedrate_mm_m.v),
SP_W_STR, W_AXIS_UNIT(homing_feedrate_mm_m.w)
));
}
#endif // EDITABLE_HOMING_FEEDRATE

View file

@ -24,16 +24,15 @@
#include "../../module/motion.h"
/**
* M220: Set speed percentage factor, aka "Feed Rate"
* M220: Set Feedrate Percentage
*
* Parameters
* S<percent> : Set the feed rate percentage factor
* Parameters:
* None Report the current speed percentage factor
* S<percent> Set the feed rate percentage factor
*
* Report the current speed percentage factor if no parameter is specified
*
* For MMU2 and MMU2S devices...
* B : Flag to back up the current factor
* R : Flag to restore the last-saved factor
* For MMU2 and MMU2S devices:
* B<flag> Back up the current factor
* R<flag> Restore the last-saved factor
*/
void GcodeSuite::M220() {
if (!parser.seen_any()) {

View file

@ -28,22 +28,22 @@
#include "../../module/temperature.h"
/**
* M301: Set PID parameters P I D (and optionally C, L)
* M301: Set Hotend PID
*
* E[extruder] Default: 0
* Set PID parameters P I D (and optionally C, L)
*
* P[float] Kp term
* I[float] Ki term (unscaled)
* D[float] Kd term (unscaled)
* Parameters:
* E<extruder> Default: 0
* P<float> Kp term
* I<float> Ki term (unscaled)
* D<float> Kd term (unscaled)
*
* With PID_EXTRUSION_SCALING:
* With PID_EXTRUSION_SCALING:
* C<float> Kc term
* L<int> LPQ length
*
* C[float] Kc term
* L[int] LPQ length
*
* With PID_FAN_SCALING:
*
* F[float] Kf term
* With PID_FAN_SCALING:
* F<float> Kf term
*/
void GcodeSuite::M301() {
// multi-extruder PID patch: M301 updates or prints a single extruder's PID values

View file

@ -101,7 +101,7 @@ void GcodeSuite::M92_report(const bool forReplay/*=true*/, const int8_t e/*=-1*/
report_heading_etc(forReplay, F(STR_STEPS_PER_UNIT));
#if NUM_AXES
#define PRINT_EOL
SERIAL_ECHOPGM_P(LIST_N(DOUBLE(NUM_AXES),
SERIAL_ECHOPGM_P(NUM_AXIS_PAIRED_LIST(
PSTR(" M92 X"), LINEAR_UNIT(planner.settings.axis_steps_per_mm[X_AXIS]),
SP_Y_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Y_AXIS]),
SP_Z_STR, LINEAR_UNIT(planner.settings.axis_steps_per_mm[Z_AXIS]),

View file

@ -46,15 +46,16 @@ void protected_pin_err() {
/**
* M42: Change pin status via G-Code
*
* P<pin> Pin number (LED if omitted)
* For LPC1768 specify pin P1_02 as M42 P102,
* P1_20 as M42 P120, etc.
* Parameters:
* P<pin> Pin number (LED if omitted)
* For LPC1768 specify pin P1_02 as M42 P102,
* P1_20 as M42 P120, etc.
*
* S<byte> Pin status from 0 - 255
* I Flag to ignore Marlin's pin protection
* S<byte> Pin status from 0-255
* I Flag to ignore Marlin's pin protection
*
* T<mode> Pin mode: 0=INPUT 1=OUTPUT 2=INPUT_PULLUP 3=INPUT_PULLDOWN
* 4=INPUT_ANALOG 5=OUTPUT_OPEN_DRAIN
* T<mode> Pin mode: 0=INPUT | 1=OUTPUT | 2=INPUT_PULLUP | 3=INPUT_PULLDOWN
* 4=INPUT_ANALOG | 5=OUTPUT_OPEN_DRAIN
*/
void GcodeSuite::M42() {
const int pin_index = PARSED_PIN_INDEX('P', GET_PIN_MAP_INDEX(LED_PIN));

View file

@ -155,13 +155,16 @@
#elif ENABLED(MULTI_NOZZLE_DUPLICATION)
/**
* M605: Set multi-nozzle duplication mode
* M605: Multi Nozzle Mode
*
* S2 - Enable duplication mode
* P[mask] - Bit-mask of nozzles to include in the duplication set.
* A value of 0 disables duplication.
* E[index] - Last nozzle index to include in the duplication set.
* A value of 0 disables duplication.
* Set multi-nozzle duplication mode.
*
* Parameters:
* S2 Enable duplication mode
* P<mask> Bit-mask of nozzles to include in the duplication set
* A value of 0 disables duplication
* E<index> Last nozzle index to include in the duplication set
* A value of 0 disables duplication
*/
void GcodeSuite::M605() {
bool ena = false;

View file

@ -49,7 +49,8 @@ void GcodeSuite::M993() {
W25QXX.SPI_FLASH_BufferRead(buf, addr, COUNT(buf));
addr += COUNT(buf);
card.write(buf, COUNT(buf));
if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.');
if (!(addr % (COUNT(buf) * 10))) SERIAL_CHAR('.');
if (!(addr % (COUNT(buf) * 32))) hal.watchdog_refresh();
}
SERIAL_ECHOLNPGM(" done");
@ -78,7 +79,8 @@ void GcodeSuite::M994() {
card.read(buf, COUNT(buf));
W25QXX.SPI_FLASH_BufferWrite(buf, addr, COUNT(buf));
addr += COUNT(buf);
if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.');
if (!(addr % (COUNT(buf) * 10))) SERIAL_CHAR('.');
if (!(addr % (COUNT(buf) * 32))) hal.watchdog_refresh();
}
SERIAL_ECHOLNPGM(" done");

View file

@ -43,14 +43,15 @@
/**
* T0-T<n>: Switch tool, usually switching extruders
*
* F[units/min] Set the movement feedrate
* S1 Don't move the tool in XY after change
* Parameters:
* F<units/min> Set the movement feedrate
* S1 Don't move the tool in XY after change
*
* For PRUSA_MMU2(S) and EXTENDABLE_EMU_MMU2(S)
* T[n] G-code to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels.
* T? G-code to extrude shouldn't have to follow. Load to extruder wheels is done automatically.
* Tx Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load.
* Tc Load to nozzle after filament was prepared by Tc and nozzle is already heated.
* For PRUSA_MMU2(S) and EXTENDABLE_EMU_MMU2(S)
* T<n> G-code to extrude at least 38.10 mm at feedrate 19.02 mm/s must follow immediately to load to extruder wheels.
* T? G-code to extrude shouldn't have to follow. Load to extruder wheels is done automatically.
* Tx Same as T?, but nozzle doesn't have to be preheated. Tc requires a preheated nozzle to finish filament load.
* Tc Load to nozzle after filament was prepared by Tc and nozzle is already heated.
*/
void GcodeSuite::T(const int8_t tool_index) {

View file

@ -46,24 +46,22 @@
* M710 I127 A1 S255 D160 ; Set controller fan idle speed 50%, AutoMode On, Fan speed 100%, duration to 160 Secs
*/
void GcodeSuite::M710() {
if (!parser.seen("ADIRS")) return M710_report();
const bool seenR = parser.seen('R');
if (seenR) controllerFan.reset();
if (parser.seen_test('R'))
controllerFan.reset();
const bool seenS = parser.seenval('S');
if (seenS) controllerFan.settings.active_speed = parser.value_byte();
if (parser.seenval('S'))
controllerFan.settings.active_speed = parser.value_byte();
const bool seenI = parser.seenval('I');
if (seenI) controllerFan.settings.idle_speed = parser.value_byte();
if (parser.seenval('I'))
controllerFan.settings.idle_speed = parser.value_byte();
const bool seenA = parser.seenval('A');
if (seenA) controllerFan.settings.auto_mode = parser.value_bool();
if (parser.seenval('A'))
controllerFan.settings.auto_mode = parser.value_bool();
const bool seenD = parser.seenval('D');
if (seenD) controllerFan.settings.duration = parser.value_ushort();
if (!(seenR || seenS || seenI || seenA || seenD))
M710_report();
if (parser.seenval('D'))
controllerFan.settings.duration = parser.value_ushort();
}
void GcodeSuite::M710_report(const bool forReplay/*=true*/) {

View file

@ -80,24 +80,28 @@ void GcodeSuite::M150() {
#endif
#endif
const LEDColor color = LEDColor(
parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : (old_color >> 16) & 0xFF,
parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : (old_color >> 8) & 0xFF,
parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : old_color & 0xFF
OPTARG(HAS_WHITE_LED, parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : (old_color >> 24) & 0xFF)
OPTARG(NEOPIXEL_LED, parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : brightness)
);
#if ENABLED(NEOPIXEL2_SEPARATE)
switch (unit) {
case 0: leds.set_color(color); return;
case 1: leds2.set_color(color); return;
}
const uint8_t valR = parser.seen('R') ? (parser.has_value() ? parser.value_byte() : 255) : (old_color >> 16) & 0xFF,
valU = parser.seen('U') ? (parser.has_value() ? parser.value_byte() : 255) : (old_color >> 8) & 0xFF,
valB = parser.seen('B') ? (parser.has_value() ? parser.value_byte() : 255) : old_color & 0xFF;
#if HAS_WHITE_LED || HAS_WHITE_LED2
const uint8_t valW = parser.seen('W') ? (parser.has_value() ? parser.value_byte() : 255) : (old_color >> 24) & 0xFF;
#endif
#if ENABLED(NEOPIXEL_LED)
const uint8_t valP = parser.seen('P') ? (parser.has_value() ? parser.value_byte() : 255) : brightness;
#endif
// If 'S' is not specified use both
leds.set_color(color);
TERN_(NEOPIXEL2_SEPARATE, leds2.set_color(color));
const LED1Color_t color = LED1Color_t(valR, valU, valB OPTARG(HAS_WHITE_LED, valW) OPTARG(NEOPIXEL_LED, valP) );
#if ENABLED(NEOPIXEL2_SEPARATE)
const LED2Color_t color2 = LED2Color_t(valR, valU, valB OPTARG(HAS_WHITE_LED2, valW) OPTARG(NEOPIXEL_LED, valP) );
switch (unit) {
case 0: leds.set_color(color); return;
case 1: leds2.set_color(color2); return;
}
leds2.set_color(color2); // If 'S' is not specified set both leds2...
#endif
leds.set_color(color); // ...and leds1
}
#endif // HAS_COLOR_LEDS

View file

@ -28,12 +28,15 @@
#include "../../../feature/mixing.h"
/**
* M163: Set a single mix factor for a mixing extruder
* This is called "weight" by some systems.
* Must be followed by M164 to normalize and commit them.
* M163: Set Mix Factor
*
* S[index] The channel index to set
* P[float] The mix value
* Set a single mix factor for a mixing extruder
* This is called "weight" by some systems.
* Must be followed by M164 to normalize and commit them.
*
* Parameters:
* S<index> The channel index to set
* P<float> The mix value
*/
void GcodeSuite::M163() {
const int mix_index = parser.intval('S');
@ -42,10 +45,13 @@ void GcodeSuite::M163() {
}
/**
* M164: Normalize and commit the mix.
* M164: Save Mix
*
* S[index] The virtual tool to store
* If 'S' is omitted update the active virtual tool.
* Normalize and commit the mix.
*
* Parameters:
* S<index> The virtual tool to store
* If 'S' is omitted update the active virtual tool.
*/
void GcodeSuite::M164() {
#if MIXING_VIRTUAL_TOOLS > 1
@ -64,16 +70,19 @@ void GcodeSuite::M164() {
#if ENABLED(DIRECT_MIXING_IN_G1)
/**
* M165: Set multiple mix factors for a mixing extruder.
* Omitted factors will be set to 0.
* The mix is normalized and stored in the current virtual tool.
* M165: Set Mix
*
* A[factor] Mix factor for extruder stepper 1
* B[factor] Mix factor for extruder stepper 2
* C[factor] Mix factor for extruder stepper 3
* D[factor] Mix factor for extruder stepper 4
* H[factor] Mix factor for extruder stepper 5
* I[factor] Mix factor for extruder stepper 6
* Set multiple mix factors for a mixing extruder.
* Omitted factors will be set to 0.
* The mix is normalized and stored in the current virtual tool.
*
* Parameters:
* A<factor> Mix factor for extruder stepper 1
* B<factor> Mix factor for extruder stepper 2
* C<factor> Mix factor for extruder stepper 3
* D<factor> Mix factor for extruder stepper 4
* H<factor> Mix factor for extruder stepper 5
* I<factor> Mix factor for extruder stepper 6
*/
void GcodeSuite::M165() {
// Get mixing parameters from the G-Code

View file

@ -40,19 +40,23 @@ inline void echo_zt(const int t, const_float_t z) {
}
/**
* M166: Set a simple gradient mix for a two-component mixer
* based on the Geeetech A10M implementation by Jone Liu.
* M166: Gradient Mix
*
* S[bool] - Enable / disable gradients
* A[float] - Starting Z for the gradient
* Z[float] - Ending Z for the gradient. (Must be greater than the starting Z.)
* I[index] - V-Tool to use as the starting mix.
* J[index] - V-Tool to use as the ending mix.
* Set a simple gradient mix for a two-component mixer
* based on the Geeetech A10M implementation by Jone Liu.
*
* T[index] - A V-Tool index to use as an alias for the Gradient (Requires GRADIENT_VTOOL)
* T with no index clears the setting. Note: This can match the I or J value.
* Parameters:
* S<bool> Enable / disable gradients
* A<float> Starting Z for the gradient
* Z<float> Ending Z for the gradient. (Must be greater than the starting Z.)
* I<index> V-Tool to use as the starting mix
* J<index> V-Tool to use as the ending mix
* T<index> A V-Tool index to use as an alias for the Gradient (Requires GRADIENT_VTOOL)
* T T with no index clears the setting
* NOTE: This can match the I or J value.
*
* Example: M166 S1 A0 Z20 I0 J1
* Example:
* M166 S1 A0 Z20 I0 J1
*/
void GcodeSuite::M166() {
if (parser.seenval('A')) mixer.gradient.start_z = parser.value_float();

Some files were not shown because too many files have changed in this diff Show more