Compare commits
177 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bbae4676f | |||
| 6802260626 | |||
| ed34dbb4b6 | |||
| 721209a898 | |||
| 7c6dfc4ec2 | |||
| 62008024cd | |||
| e09672edac | |||
| 825e0b800c | |||
| 0f489c6584 | |||
| 6ae43349f7 | |||
| f6b52a80d6 | |||
| 38711ed5e6 | |||
| 5a714c76b8 | |||
| 8c1a547f2a | |||
| 16be10d2f3 | |||
| d4dde255ad | |||
| b5c7712531 | |||
| 8dc8361f02 | |||
| 433f3ba3ab | |||
| 78e2aa6eac | |||
| 54da1da13f | |||
| 544765f1a1 | |||
| f261fea59a | |||
| 00785eb14e | |||
| 6713185aea | |||
| 298c3f2344 | |||
| 82c1171028 | |||
| 122b01d253 | |||
| 42e4321b6f | |||
| 87faa73bee | |||
| 666e8c0116 | |||
| 5a0332ddee | |||
| f67a0f847f | |||
| 0f1a5a7434 | |||
| e7c9cf3e1d | |||
| 01df7e11dc | |||
| 9200e8c284 | |||
| 6710616a09 | |||
| 2064c83c66 | |||
| 2e97ad1f4b | |||
| 4f85f88ae3 | |||
| 0dcfc91c9e | |||
| acf53d6f84 | |||
| 181a57ae9b | |||
| 3ee1248cf2 | |||
| 68c3916d46 | |||
| e3bbacd8b9 | |||
| f915371248 | |||
| ea848aa891 | |||
| 5157849c60 | |||
| ca31f9789e | |||
| 78d3cf1de1 | |||
| 521e7eafce | |||
| 2d78a80cf6 | |||
| 5f32698da5 | |||
| 1845056014 | |||
| 0b8ec2aa74 | |||
| 578bdd4b20 | |||
| 6b6865d068 | |||
| 6c018eb770 | |||
| 5561bafbe6 | |||
| 75eee04972 | |||
| ee1d1faa52 | |||
| dbd3e10959 | |||
| fde330af5a | |||
| e8d953257e | |||
| cc86e9ecce | |||
| 5a6db519d6 | |||
| 98d09e5304 | |||
| d87a0ea7f7 | |||
| 0e2bd069d4 | |||
| feca9a33d5 | |||
| eec1aec071 | |||
| a97d1088f0 | |||
| a7317de3b4 | |||
| 06762db050 | |||
| 4f3ebea3a6 | |||
| fa88e0f054 | |||
| 2fd7c2b865 | |||
| ef0bd975cf | |||
| bdc14ddbd7 | |||
| 383e6f4646 | |||
| e37415c95b | |||
| a33112a4c0 | |||
| 7e8007f024 | |||
| f320c2a455 | |||
| 6eedeaedaf | |||
| 6b5e19cfc4 | |||
| 3dc437add4 | |||
| 5f96dffb9b | |||
| 6423b8031d | |||
| bbdad79ce5 | |||
| a2daee8f7a | |||
| 909e3ad116 | |||
| 556616c4f0 | |||
| 46e426ce96 | |||
| f5f6c37c17 | |||
| 08fe8a3076 | |||
| dabcea991f | |||
| 4a5bd47b6a | |||
| e5742a98df | |||
| 774cecc3b4 | |||
| 83b7e32ec4 | |||
| a22155bd96 | |||
| 1da947f548 | |||
| a3960dfa53 | |||
| bab1917311 | |||
| 49348716f5 | |||
| eb781afe7b | |||
| 39f53c3f8c | |||
| b5307aaaad | |||
| f5cf667c95 | |||
| 737095f852 | |||
| f56952c9e6 | |||
| ca5a7be5e8 | |||
| 582c5a36d7 | |||
| a8058729cc | |||
| a2f024ffe3 | |||
| e1d65cc5e0 | |||
| 75cda8d191 | |||
| af8dcc6ee8 | |||
| 2270bf41d7 | |||
| 489ef6e5e1 | |||
| cecc745844 | |||
| 5366362e47 | |||
| a1ecea60fd | |||
| 882421a03e | |||
| a36f72e886 | |||
| 247e989377 | |||
| 91ae676b9b | |||
| a955e06259 | |||
| 31683ce35b | |||
| d773570cd6 | |||
| 556da2b3fc | |||
| 9e19a6efe1 | |||
| f433b2c433 | |||
| bc0d7d7140 | |||
| 24f8831021 | |||
| 9a8fb80eed | |||
| ca12459b9c | |||
| e1ab911c35 | |||
| 58d4494365 | |||
| d502e5beaa | |||
| b4a95db7da | |||
| 02ba6f9f3a | |||
| dba0010607 | |||
| 90667f6114 | |||
| d6961b2626 | |||
| 07ebb8171f | |||
| 245db73929 | |||
| 9342dae8f0 | |||
| 1f84f50fd8 | |||
| 3326c749f8 | |||
| 0269106066 | |||
| 95d38a8e54 | |||
| dca6afc26e | |||
| 19684f23bc | |||
| 52a561399e | |||
| 0683e8a9a3 | |||
| 1bb4a042e2 | |||
| d10861e478 | |||
| cf7c86d581 | |||
| d99e150097 | |||
| 9e88eb6100 | |||
| 71d9a3e1df | |||
| 6575dcc803 | |||
| 2715e5ba1b | |||
| da068d5bb1 | |||
| 7f339f7001 | |||
| 7150d0eb5c | |||
| ca18690349 | |||
| 0316242347 | |||
| 6087ab6347 | |||
| a44871b272 | |||
| bef646d52c | |||
| 4d78a91cbd | |||
| 95bafca9d9 |
@@ -1,9 +1,9 @@
|
||||
#
|
||||
# test-builds.yml
|
||||
# ci-build-tests.yml
|
||||
# Do test builds to catch compile errors
|
||||
#
|
||||
|
||||
name: CI
|
||||
name: CI - Build Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
@@ -14,6 +14,8 @@ on:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- test/**
|
||||
- Marlin/tests/**
|
||||
- '**/*.md'
|
||||
push:
|
||||
branches:
|
||||
@@ -23,11 +25,13 @@ on:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- test/**
|
||||
- Marlin/tests/**
|
||||
- '**/*.md'
|
||||
|
||||
jobs:
|
||||
test_builds:
|
||||
name: Run All Tests
|
||||
name: Build Test
|
||||
if: github.repository == 'MarlinFirmware/Marlin'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
@@ -0,0 +1,73 @@
|
||||
#
|
||||
# ci-unit-tests.yml
|
||||
# Build and execute unit tests to catch functional issues in code
|
||||
#
|
||||
|
||||
name: CI - Unit Tests
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- bugfix-2.1.x
|
||||
# Cannot be enabled on 2.1.x until it contains the unit test framework
|
||||
#- 2.1.x
|
||||
paths-ignore:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- '**/*.md'
|
||||
push:
|
||||
branches:
|
||||
- bugfix-2.1.x
|
||||
# Cannot be enabled on 2.1.x until it contains the unit test framework
|
||||
#- 2.1.x
|
||||
paths-ignore:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- '**/*.md'
|
||||
|
||||
jobs:
|
||||
# This runs all unit tests as a single job. While it should be possible to break this up into
|
||||
# multiple jobs, they currently run quickly and finish long before the compilation tests.
|
||||
run_unit_tests:
|
||||
name: Unit Test
|
||||
# These tests will only be able to run on the bugfix-2.1.x branch, until the next release
|
||||
# pulls them into additional branches.
|
||||
if: github.repository == 'MarlinFirmware/Marlin'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out the PR
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: Cache PlatformIO
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.platformio
|
||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
||||
|
||||
- name: Select Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.9'
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
pip install -U platformio
|
||||
pio upgrade --dev
|
||||
pio pkg update --global
|
||||
|
||||
- name: Run All Unit Tests
|
||||
run: |
|
||||
make unit-test-all-local
|
||||
@@ -0,0 +1,51 @@
|
||||
#
|
||||
# ci-validate-pins.yml
|
||||
# Validate that all of the pins files are unchanged by pinsformat.py
|
||||
#
|
||||
|
||||
name: CI - Validate Pins Files
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- bugfix-2.1.x
|
||||
# Cannot be enabled on 2.1.x until it contains the unit test framework
|
||||
#- 2.1.x
|
||||
paths:
|
||||
- 'Marlin/src/pins/*/**'
|
||||
push:
|
||||
branches:
|
||||
- bugfix-2.1.x
|
||||
# Cannot be enabled on 2.1.x until it contains the unit test framework
|
||||
#- 2.1.x
|
||||
paths:
|
||||
- 'Marlin/src/pins/*/**'
|
||||
|
||||
jobs:
|
||||
validate_pins_files:
|
||||
name: Validate Pins Files
|
||||
if: github.repository == 'MarlinFirmware/Marlin'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out the PR
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Cache pip
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/pip
|
||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-pip-
|
||||
|
||||
- name: Select Python 3.9
|
||||
uses: actions/setup-python@v5
|
||||
with:
|
||||
python-version: '3.9'
|
||||
architecture: 'x64'
|
||||
|
||||
- name: Validate all pins files
|
||||
run: |
|
||||
make validate-pins -j
|
||||
@@ -2,17 +2,23 @@ SCRIPTS_DIR := buildroot/share/scripts
|
||||
CONTAINER_RT_BIN := docker
|
||||
CONTAINER_RT_OPTS := --rm -v $(PWD):/code -v platformio-cache:/root/.platformio
|
||||
CONTAINER_IMAGE := marlin-dev
|
||||
UNIT_TEST_CONFIG ?= default
|
||||
|
||||
help:
|
||||
@echo "Tasks for local development:"
|
||||
@echo "make marlin : Build marlin for the configured board"
|
||||
@echo "make format-pins : Reformat all pins files"
|
||||
@echo "make format-pins -j : Reformat all pins files (-j for parallel execution)"
|
||||
@echo "make validate-pins -j : Validate all pins files, fails if any require reformatting"
|
||||
@echo "make tests-single-ci : Run a single test from inside the CI"
|
||||
@echo "make tests-single-local : Run a single test locally"
|
||||
@echo "make tests-single-local-docker : Run a single test locally, using docker"
|
||||
@echo "make tests-all-local : Run all tests locally"
|
||||
@echo "make tests-all-local-docker : Run all tests locally, using docker"
|
||||
@echo "make setup-local-docker : Build the local docker image"
|
||||
@echo "make unit-test-single-local : Run unit tests for a single config locally"
|
||||
@echo "make unit-test-single-local-docker : Run unit tests for a single config locally, using docker"
|
||||
@echo "make unit-test-all-local : Run all code tests locally"
|
||||
@echo "make unit-test-all-local-docker : Run all code tests locally, using docker"
|
||||
@echo "make setup-local-docker : Setup local docker using buildx"
|
||||
@echo ""
|
||||
@echo "Options for testing:"
|
||||
@echo " TEST_TARGET Set when running tests-single-*, to select the"
|
||||
@@ -22,6 +28,9 @@ help:
|
||||
@echo " run on GitHub CI"
|
||||
@echo " ONLY_TEST Limit tests to only those that contain this, or"
|
||||
@echo " the index of the test (1-based)"
|
||||
@echo " UNIT_TEST_CONFIG Set the name of the config from the test folder, without"
|
||||
@echo " the leading number. Default is 'default'". Used with the
|
||||
@echo " unit-test-single-* tasks"
|
||||
@echo " VERBOSE_PLATFORMIO If you want the full PIO output, set any value"
|
||||
@echo " GIT_RESET_HARD Used by CI: reset all local changes. WARNING:"
|
||||
@echo " THIS WILL UNDO ANY CHANGES YOU'VE MADE!"
|
||||
@@ -43,23 +52,53 @@ tests-single-local:
|
||||
tests-single-local-docker:
|
||||
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local-docker" ; return 1; fi
|
||||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
|
||||
|
||||
tests-all-local:
|
||||
@python -c "import yaml" 2>/dev/null || (echo 'pyyaml module is not installed. Install it with "python -m pip install pyyaml"' && exit 1)
|
||||
export PATH="./buildroot/bin/:./buildroot/tests/:${PATH}" \
|
||||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
||||
&& for TEST_TARGET in $$($(SCRIPTS_DIR)/get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
|
||||
&& for TEST_TARGET in $$(python $(SCRIPTS_DIR)/get_test_targets.py) ; do \
|
||||
if [ "$$TEST_TARGET" = "linux_native" ] && [ "$$(uname)" = "Darwin" ]; then \
|
||||
echo "Skipping tests for $$TEST_TARGET on macOS" ; \
|
||||
continue ; \
|
||||
fi ; \
|
||||
echo "Running tests for $$TEST_TARGET" ; \
|
||||
run_tests . $$TEST_TARGET || exit 1 ; \
|
||||
sleep 5; \
|
||||
done
|
||||
|
||||
tests-all-local-docker:
|
||||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) $(MAKE) tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
|
||||
|
||||
unit-test-single-local:
|
||||
platformio run -t marlin_$(UNIT_TEST_CONFIG) -e linux_native_test
|
||||
|
||||
unit-test-single-local-docker:
|
||||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-single-local UNIT_TEST_CONFIG=$(UNIT_TEST_CONFIG)
|
||||
|
||||
unit-test-all-local:
|
||||
platformio run -t test-marlin -e linux_native_test
|
||||
|
||||
unit-test-all-local-docker:
|
||||
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
|
||||
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) make unit-test-all-local
|
||||
|
||||
setup-local-docker:
|
||||
$(CONTAINER_RT_BIN) build -t $(CONTAINER_IMAGE) -f docker/Dockerfile .
|
||||
$(CONTAINER_RT_BIN) buildx build -t $(CONTAINER_IMAGE) -f docker/Dockerfile .
|
||||
|
||||
PINS := $(shell find Marlin/src/pins -mindepth 2 -name '*.h')
|
||||
|
||||
.PHONY: $(PINS) format-pins validate-pins
|
||||
|
||||
$(PINS): %:
|
||||
@echo "Formatting $@" && node $(SCRIPTS_DIR)/pinsformat.js $@
|
||||
@echo "Formatting $@"
|
||||
@python $(SCRIPTS_DIR)/pinsformat.py $< $@
|
||||
|
||||
format-pins: $(PINS)
|
||||
|
||||
validate-pins: format-pins
|
||||
@echo "Validating pins files"
|
||||
@git diff --exit-code || (git status && echo "\nError: Pins files are not formatted correctly. Run \"make format-pins\" to fix.\n" && exit 1)
|
||||
|
||||
+156
-408
File diff suppressed because it is too large
Load Diff
+162
-196
@@ -304,8 +304,8 @@
|
||||
* THERMAL_PROTECTION_HYSTERESIS and/or THERMAL_PROTECTION_PERIOD
|
||||
*/
|
||||
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
|
||||
#define THERMAL_PROTECTION_PERIOD 60 // (seconds)
|
||||
#define THERMAL_PROTECTION_HYSTERESIS 15 // (°C)
|
||||
#define THERMAL_PROTECTION_PERIOD 40 // (seconds)
|
||||
#define THERMAL_PROTECTION_HYSTERESIS 4 // (°C)
|
||||
|
||||
#define ADAPTIVE_FAN_SLOWING // Slow down the part-cooling fan if the temperature drops
|
||||
#if ENABLED(ADAPTIVE_FAN_SLOWING)
|
||||
@@ -327,7 +327,7 @@
|
||||
* and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set
|
||||
* below 2.
|
||||
*/
|
||||
#define WATCH_TEMP_PERIOD 60 // (seconds)
|
||||
#define WATCH_TEMP_PERIOD 40 // (seconds)
|
||||
#define WATCH_TEMP_INCREASE 2 // (°C)
|
||||
#endif
|
||||
|
||||
@@ -335,13 +335,13 @@
|
||||
* Thermal Protection parameters for the bed are just as above for hotends.
|
||||
*/
|
||||
#if ENABLED(THERMAL_PROTECTION_BED)
|
||||
#define THERMAL_PROTECTION_BED_PERIOD 120 // (seconds)
|
||||
#define THERMAL_PROTECTION_BED_PERIOD 90 // (seconds)
|
||||
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // (°C)
|
||||
|
||||
/**
|
||||
* As described above, except for the bed (M140/M190/M303).
|
||||
*/
|
||||
#define WATCH_BED_TEMP_PERIOD 120 // (seconds)
|
||||
#define WATCH_BED_TEMP_PERIOD 60 // (seconds)
|
||||
#define WATCH_BED_TEMP_INCREASE 2 // (°C)
|
||||
#endif
|
||||
|
||||
@@ -459,7 +459,7 @@
|
||||
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
|
||||
|
||||
#else
|
||||
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed)
|
||||
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power loss due to cooling = Kf * (fan_speed)
|
||||
#define DEFAULT_Kf 10 // A constant value added to the PID-tuner
|
||||
#define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING
|
||||
#endif
|
||||
@@ -549,8 +549,8 @@
|
||||
*/
|
||||
#define HOTEND_IDLE_TIMEOUT
|
||||
#if ENABLED(HOTEND_IDLE_TIMEOUT)
|
||||
#define HOTEND_IDLE_TIMEOUT_SEC (15*60) // (seconds) Time without extruder movement to trigger protection
|
||||
#define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection
|
||||
#define HOTEND_IDLE_TIMEOUT_SEC (30*60) // (seconds) Time without extruder movement to trigger protection
|
||||
#define HOTEND_IDLE_MIN_TRIGGER 170 // (°C) Minimum temperature to enable hotend protection
|
||||
#define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout
|
||||
#define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout
|
||||
#endif
|
||||
@@ -603,7 +603,7 @@
|
||||
* (Does not work on Sanguinololu with FAN_SOFT_PWM.)
|
||||
*/
|
||||
#define FAN_KICKSTART_TIME 100 // (ms)
|
||||
//#define FAN_KICKSTART_POWER 180 // 64-255
|
||||
#define FAN_KICKSTART_POWER 180 // 64-255
|
||||
|
||||
// Some coolers may require a non-zero "off" state.
|
||||
//#define FAN_OFF_PWM 1
|
||||
@@ -681,17 +681,8 @@
|
||||
* Multiple extruders can be assigned to the same pin in which case
|
||||
* the fan will turn on when any selected extruder is above the threshold.
|
||||
*/
|
||||
#if ENABLED(SKR12Pro, TREX3)
|
||||
#define E0_AUTO_FAN_PIN FAN2_PIN
|
||||
#define E1_AUTO_FAN_PIN FAN2_PIN
|
||||
#elif ENABLED(TREX3)
|
||||
#define E0_AUTO_FAN_PIN 6
|
||||
#define E1_AUTO_FAN_PIN 45
|
||||
#else
|
||||
#define E0_AUTO_FAN_PIN -1
|
||||
#define E1_AUTO_FAN_PIN -1
|
||||
#endif
|
||||
|
||||
#define E0_AUTO_FAN_PIN -1
|
||||
#define E1_AUTO_FAN_PIN -1
|
||||
#define E2_AUTO_FAN_PIN -1
|
||||
#define E3_AUTO_FAN_PIN -1
|
||||
#define E4_AUTO_FAN_PIN -1
|
||||
@@ -757,17 +748,15 @@
|
||||
* @section caselight
|
||||
* M355 Case Light on-off / brightness
|
||||
*/
|
||||
#define CASE_LIGHT_ENABLE
|
||||
//#define CASE_LIGHT_ENABLE
|
||||
#if ENABLED(CASE_LIGHT_ENABLE)
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define CASE_LIGHT_PIN HEATER_2_PIN // Override the default pin if needed
|
||||
#endif
|
||||
//#define CASE_LIGHT_PIN 4 // Override the default pin if needed
|
||||
#define INVERT_CASE_LIGHT false // Set true if Case Light is ON when pin is LOW
|
||||
#define CASE_LIGHT_DEFAULT_ON true // Set default power-up state on
|
||||
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 255 // Set default power-up brightness (0-255, requires PWM pin)
|
||||
#define CASE_LIGHT_DEFAULT_BRIGHTNESS 105 // Set default power-up brightness (0-255, requires PWM pin)
|
||||
//#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
|
||||
//#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255)
|
||||
#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
|
||||
//#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
|
||||
#if ENABLED(NEOPIXEL_LED)
|
||||
//#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light
|
||||
#endif
|
||||
@@ -826,26 +815,22 @@
|
||||
* Set the initial X offset and temperature differential with M605 S2 X[offs] R[deg] and
|
||||
* follow with M605 S3 to initiate mirrored movement.
|
||||
*/
|
||||
#define DUAL_X_CARRIAGE
|
||||
//#define DUAL_X_CARRIAGE
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
#define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS
|
||||
#define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage
|
||||
#define X2_MIN_POS 0 // A min coordinate so the X2 carriage can't hit the parked X1 carriage
|
||||
#if DISABLED(TREX3) || ENABLED(TREX3_UPGRADE)
|
||||
#define X2_MAX_POS 442 // The max position of the X2 carriage, typically also the home position
|
||||
#else
|
||||
#define X2_MAX_POS 446 // The max position of the X2 carriage, typically also the home position
|
||||
#endif
|
||||
#define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage
|
||||
#define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position
|
||||
#define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS.
|
||||
// NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS.
|
||||
// This allows recalibration of endstops distance without a rebuild.
|
||||
// Remember to set the second extruder's X-offset to 0 in your slicer.
|
||||
|
||||
// This is the default power-up mode which can be later using M605.
|
||||
// This is the default power-up mode which can be changed later using M605 S<mode>.
|
||||
#define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE
|
||||
|
||||
// Default x offset in duplication mode (typically set to half print bed width)
|
||||
#define DEFAULT_DUPLICATION_X_OFFSET 200
|
||||
#define DEFAULT_DUPLICATION_X_OFFSET 100
|
||||
|
||||
// Default action to execute following M605 mode change commands. Typically G28X to apply new mode.
|
||||
//#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
|
||||
@@ -1018,7 +1003,7 @@
|
||||
*
|
||||
* Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset.
|
||||
*/
|
||||
#define BLTOUCH_HS_MODE true
|
||||
//#define BLTOUCH_HS_MODE true
|
||||
|
||||
#ifdef BLTOUCH_HS_MODE
|
||||
// The probe Z offset (M851 Z) is the height at which the probe triggers.
|
||||
@@ -1035,7 +1020,7 @@
|
||||
* Z Steppers Auto-Alignment
|
||||
* Add the G34 command to align multiple Z steppers using a bed probe.
|
||||
*/
|
||||
//#define Z_STEPPER_AUTO_ALIGN
|
||||
#define Z_STEPPER_AUTO_ALIGN
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
/**
|
||||
* Define probe X and Y positions for Z1, Z2 [, Z3 [, Z4]]
|
||||
@@ -1219,14 +1204,14 @@
|
||||
//#define INPUT_SHAPING_Y
|
||||
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y)
|
||||
#if ENABLED(INPUT_SHAPING_X)
|
||||
#define SHAPING_FREQ_X 40.0 // (Hz) The default dominant resonant frequency on the X axis.
|
||||
#define SHAPING_ZETA_X 0.15 // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#define SHAPING_FREQ_X 40 // (Hz) The default dominant resonant frequency on the X axis.
|
||||
#define SHAPING_ZETA_X 0.15f // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
#define SHAPING_FREQ_Y 40.0 // (Hz) The default dominant resonant frequency on the Y axis.
|
||||
#define SHAPING_ZETA_Y 0.15 // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#define SHAPING_FREQ_Y 40 // (Hz) The default dominant resonant frequency on the Y axis.
|
||||
#define SHAPING_ZETA_Y 0.15f // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#endif
|
||||
//#define SHAPING_MIN_FREQ 20.0 // (Hz) By default the minimum of the shaping frequencies. Override to affect SRAM usage.
|
||||
//#define SHAPING_MIN_FREQ 20 // By default the minimum of the shaping frequencies. Override to affect SRAM usage.
|
||||
//#define SHAPING_MAX_STEPRATE 10000 // By default the maximum total step rate of the shaped axes. Override to affect SRAM usage.
|
||||
//#define SHAPING_MENU // Add a menu to the LCD to set shaping parameters.
|
||||
#endif
|
||||
@@ -1278,22 +1263,18 @@
|
||||
// Increase the slowdown divisor for larger buffer sizes.
|
||||
#define SLOWDOWN
|
||||
#if ENABLED(SLOWDOWN)
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define SLOWDOWN_DIVISOR 6
|
||||
#else
|
||||
#define SLOWDOWN_DIVISOR 2
|
||||
#endif
|
||||
#define SLOWDOWN_DIVISOR 2
|
||||
#endif
|
||||
|
||||
/**
|
||||
* XY Frequency limit
|
||||
* Reduce resonance by limiting the frequency of small zigzag infill moves.
|
||||
* See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html
|
||||
* Use M201 F<freq> S<min%> to change limits at runtime.
|
||||
* Use M201 F<freq> G<min%> to change limits at runtime.
|
||||
*/
|
||||
//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F<hertz>.
|
||||
#ifdef XY_FREQUENCY_LIMIT
|
||||
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 S<min%>.
|
||||
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 G<min%>.
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -1305,7 +1286,7 @@
|
||||
// Define values for backlash distance and correction.
|
||||
// If BACKLASH_GCODE is enabled these values are the defaults.
|
||||
#define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (linear=mm, rotational=°) One value for each linear axis
|
||||
#define BACKLASH_CORRECTION 0.5 // 0.0 = no correction; 1.0 = full correction
|
||||
#define BACKLASH_CORRECTION 0.0 // 0.0 = no correction; 1.0 = full correction
|
||||
|
||||
// Add steps for motor direction changes on CORE kinematics
|
||||
//#define CORE_BACKLASH
|
||||
@@ -1319,7 +1300,7 @@
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
// Measure the Z backlash when probing (G29) and set with "M425 Z"
|
||||
//#define MEASURE_BACKLASH_WHEN_PROBING
|
||||
#define MEASURE_BACKLASH_WHEN_PROBING
|
||||
|
||||
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
|
||||
// When measuring, the probe will move up to BACKLASH_MEASUREMENT_LIMIT
|
||||
@@ -1345,9 +1326,7 @@
|
||||
* Note: HOTEND_OFFSET and CALIBRATION_OBJECT_CENTER must be set to within
|
||||
* ±5mm of true values for G425 to succeed.
|
||||
*/
|
||||
#if ENABLED(autoCalibrationKit)
|
||||
#define CALIBRATION_GCODE
|
||||
#endif
|
||||
//#define CALIBRATION_GCODE
|
||||
#if ENABLED(CALIBRATION_GCODE)
|
||||
|
||||
//#define CALIBRATION_SCRIPT_PRE "M117 Starting Auto-Calibration\nT0\nG28\nG12\nM117 Calibrating..."
|
||||
@@ -1363,14 +1342,12 @@
|
||||
#define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm
|
||||
#define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // mm
|
||||
|
||||
// Uncomment to enable reporting (required for "G425 V", but consumes flash).
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define CALIBRATION_REPORTING
|
||||
#endif
|
||||
// Uncomment to enable reporting (required for "G425 V", but consumes PROGMEM).
|
||||
//#define CALIBRATION_REPORTING
|
||||
|
||||
// The true location and dimension the cube/bolt/washer on the bed.
|
||||
#define CALIBRATION_OBJECT_CENTER { 264.0, 25.0, 12.5 } // mm
|
||||
#define CALIBRATION_OBJECT_DIMENSIONS { 12.55, 12.55, 4.0 } // mm
|
||||
#define CALIBRATION_OBJECT_CENTER { 264.0, -22.0, -2.0 } // mm
|
||||
#define CALIBRATION_OBJECT_DIMENSIONS { 10.0, 10.0, 10.0 } // mm
|
||||
|
||||
// Comment out any sides which are unreachable by the probe. For best
|
||||
// auto-calibration results, all sides must be reachable.
|
||||
@@ -1394,16 +1371,12 @@
|
||||
|
||||
// Probing at the exact top center only works if the center is flat. If
|
||||
// probing on a screw head or hollow washer, probe near the edges.
|
||||
#define CALIBRATION_MEASURE_AT_TOP_EDGES
|
||||
//#define CALIBRATION_MEASURE_AT_TOP_EDGES
|
||||
|
||||
// Define the pin to read during calibration
|
||||
#ifndef CALIBRATION_PIN
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define CALIBRATION_PIN Z_MAX
|
||||
#else
|
||||
#define CALIBRATION_PIN 58 // Override in pins.h or set to -1 to use your Z endstop
|
||||
#endif
|
||||
#define CALIBRATION_PIN_INVERTING true // Set to true to invert the pin
|
||||
//#define CALIBRATION_PIN -1 // Define here to override the default pin
|
||||
#define CALIBRATION_PIN_INVERTING false // Set to true to invert the custom pin
|
||||
//#define CALIBRATION_PIN_PULLDOWN
|
||||
#define CALIBRATION_PIN_PULLUP
|
||||
#endif
|
||||
@@ -1413,7 +1386,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 32 //: [1, 2, 4, 8, 16, 32, 64, 128]
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
@@ -1421,7 +1394,7 @@
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
/**
|
||||
* Custom Microstepping
|
||||
@@ -1501,7 +1474,6 @@
|
||||
#if IS_ULTIPANEL
|
||||
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
|
||||
#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen
|
||||
//#define ULTIPANEL_FLOWPERCENT // Encoder sets the flow percentage on the Status Screen
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1567,7 +1539,6 @@
|
||||
* Axis moves <= 1/2 the axis length and Extruder moves <= EXTRUDE_MAXLENGTH
|
||||
* will be shown in the move submenus.
|
||||
*/
|
||||
|
||||
#define MANUAL_MOVE_DISTANCE_MM 10, 1.0, 0.1 // (mm)
|
||||
//#define MANUAL_MOVE_DISTANCE_MM 100, 50, 10, 1.0, 0.1 // (mm)
|
||||
//#define MANUAL_MOVE_DISTANCE_MM 500, 100, 50, 10, 1.0, 0.1 // (mm)
|
||||
@@ -1609,7 +1580,7 @@
|
||||
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
|
||||
#endif
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
|
||||
#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
|
||||
#endif
|
||||
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE)
|
||||
//#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup.
|
||||
@@ -1628,10 +1599,10 @@
|
||||
#endif
|
||||
|
||||
// The timeout to return to the status screen from sub-menus
|
||||
//#define LCD_TIMEOUT_TO_STATUS 15000 // (ms)
|
||||
#define LCD_TIMEOUT_TO_STATUS 15000 // (ms)
|
||||
|
||||
// Scroll a longer status message into view
|
||||
//#define STATUS_MESSAGE_SCROLLING
|
||||
#define STATUS_MESSAGE_SCROLLING
|
||||
|
||||
// Apply a timeout to low-priority status messages
|
||||
//#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds)
|
||||
@@ -1772,26 +1743,21 @@
|
||||
*/
|
||||
//#define POWER_LOSS_RECOVERY
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
#define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
|
||||
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
|
||||
//#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable)
|
||||
|
||||
//#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default.
|
||||
//#define POWER_LOSS_STATE HIGH // State of pin indicating power-loss
|
||||
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
|
||||
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS)
|
||||
//#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module.
|
||||
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
|
||||
//#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor
|
||||
//#define POWER_LOSS_PULLDOWN
|
||||
|
||||
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power-loss with UPS)
|
||||
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
|
||||
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
|
||||
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power.
|
||||
|
||||
// Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card,
|
||||
// especially with "vase mode" printing. Set too high and vases cannot be continued.
|
||||
#define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data
|
||||
|
||||
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power-loss
|
||||
#if ENABLED(BACKUP_POWER_SUPPLY)
|
||||
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail
|
||||
#endif
|
||||
|
||||
// Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
|
||||
//#define POWER_LOSS_RECOVER_ZHOME
|
||||
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
|
||||
@@ -1947,9 +1913,7 @@
|
||||
*
|
||||
* :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ]
|
||||
*/
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define SDCARD_CONNECTION ONBOARD
|
||||
#endif
|
||||
#define SDCARD_CONNECTION ONBOARD
|
||||
|
||||
// Enable if SD detect is rendered useless (e.g., by using an SD extender)
|
||||
//#define NO_SD_DETECT
|
||||
@@ -1999,6 +1963,17 @@
|
||||
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
|
||||
//#define USE_SMALL_INFOFONT
|
||||
|
||||
/**
|
||||
* Graphical Display Sleep
|
||||
*
|
||||
* The U8G library provides sleep / wake functions for SH1106, SSD1306,
|
||||
* SSD1309, and some other DOGM displays.
|
||||
* Enable this option to save energy and prevent OLED pixel burn-in.
|
||||
* Adds the menu item Configuration > LCD Timeout (m) to set a wait period
|
||||
* from 0 (disabled) to 99 minutes.
|
||||
*/
|
||||
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen. Set with M255 S.
|
||||
|
||||
/**
|
||||
* ST7920-based LCDs can emulate a 16 x 4 character display using
|
||||
* the ST7920 character-generator for very fast screen updates.
|
||||
@@ -2247,20 +2222,13 @@
|
||||
//#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Display Sleep
|
||||
* Enable this option to save energy and prevent OLED pixel burn-in.
|
||||
*/
|
||||
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen
|
||||
|
||||
/**
|
||||
* LCD Backlight Timeout
|
||||
* Requires a display with a controllable backlight
|
||||
*/
|
||||
//
|
||||
// LCD Backlight Timeout
|
||||
// Requires a display with a controllable backlight
|
||||
//
|
||||
//#define LCD_BACKLIGHT_TIMEOUT_MINS 1 // (minutes) Timeout before turning off the backlight
|
||||
|
||||
#if defined(DISPLAY_SLEEP_MINUTES) || defined(LCD_BACKLIGHT_TIMEOUT_MINS)
|
||||
#define EDITABLE_DISPLAY_TIMEOUT // Edit sleep / backlight timeout with M255 S<minutes> and a menu item
|
||||
#define EDITABLE_DISPLAY_TIMEOUT // Edit timeout with M255 S<minutes> and a menu item
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -2303,7 +2271,7 @@
|
||||
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
|
||||
//#define BABYSTEP_INVERT_Z // Enable if Z babysteps should go the other way
|
||||
//#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps
|
||||
#define BABYSTEP_MULTIPLICATOR_Z 20 // (steps or mm) Steps or millimeter distance for each Z babystep
|
||||
#define BABYSTEP_MULTIPLICATOR_Z 25 // (steps or mm) Steps or millimeter distance for each Z babystep
|
||||
#define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep
|
||||
|
||||
#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
|
||||
@@ -2320,8 +2288,8 @@
|
||||
|
||||
#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets
|
||||
#define BABYSTEP_ZPROBE_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
|
||||
//#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets
|
||||
//#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2345,9 +2313,9 @@
|
||||
#define LIN_ADVANCE
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
#define ADVANCE_K { 0.0 } // (mm) Compression length per 1mm/s extruder speed, per extruder
|
||||
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder
|
||||
#else
|
||||
#define ADVANCE_K 0.0 // (mm) Compression length applying to all extruders
|
||||
#define ADVANCE_K 0.22 // (mm) Compression length applying to all extruders
|
||||
#endif
|
||||
//#define ADVANCE_K_EXTRA // Add a second linear advance constant, configurable with M900 L.
|
||||
//#define LA_DEBUG // Print debug information to serial during operation. Disable for production use.
|
||||
@@ -2417,10 +2385,10 @@
|
||||
|
||||
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL)
|
||||
// Override the mesh area if the automatic (max) area is too large
|
||||
#define MESH_MIN_X X_MIN_POS + MESH_INSET
|
||||
#define MESH_MIN_Y Y_MIN_POS + MESH_INSET
|
||||
#define MESH_MAX_X X_MAX_POS - MESH_INSET
|
||||
#define MESH_MAX_Y Y_MAX_POS - MESH_INSET
|
||||
//#define MESH_MIN_X MESH_INSET
|
||||
//#define MESH_MIN_Y MESH_INSET
|
||||
//#define MESH_MAX_X X_BED_SIZE - (MESH_INSET)
|
||||
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
|
||||
#endif
|
||||
|
||||
#if ALL(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS)
|
||||
@@ -2535,7 +2503,7 @@
|
||||
#endif
|
||||
|
||||
// G5 Bézier Curve Support with XYZE destination and IJPQ offsets
|
||||
//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes
|
||||
#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes
|
||||
|
||||
#if ANY(ARC_SUPPORT, BEZIER_CURVE_SUPPORT)
|
||||
//#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes
|
||||
@@ -2596,7 +2564,7 @@
|
||||
*
|
||||
* Override the default value based on the driver type set in Configuration.h.
|
||||
*/
|
||||
//#define MINIMUM_STEPPER_PULSE 2
|
||||
//#define MINIMUM_STEPPER_PULSE 5
|
||||
|
||||
/**
|
||||
* Maximum stepping rate (in Hz) the stepper driver allows
|
||||
@@ -2610,7 +2578,7 @@
|
||||
*
|
||||
* Override the default value based on the driver type set in Configuration.h.
|
||||
*/
|
||||
//#define MAXIMUM_STEPPER_RATE 250000
|
||||
//#define MAXIMUM_STEPPER_RATE 150000
|
||||
|
||||
// @section temperature
|
||||
|
||||
@@ -2627,20 +2595,16 @@
|
||||
#if ALL(HAS_MEDIA, DIRECT_STEPPING)
|
||||
#define BLOCK_BUFFER_SIZE 8
|
||||
#elif HAS_MEDIA
|
||||
#define BLOCK_BUFFER_SIZE 16
|
||||
#define BLOCK_BUFFER_SIZE 32
|
||||
#else
|
||||
#define BLOCK_BUFFER_SIZE 16 // maximize block buffer
|
||||
#define BLOCK_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
// @section serial
|
||||
|
||||
// The ASCII buffer for serial input
|
||||
#define MAX_CMD_SIZE 96
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define BUFSIZE 16
|
||||
#else
|
||||
#define BUFSIZE 4
|
||||
#endif
|
||||
#define BUFSIZE 16
|
||||
|
||||
// Transmission to Host Buffer Size
|
||||
// To save 386 bytes of flash (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0.
|
||||
@@ -2772,9 +2736,7 @@
|
||||
*
|
||||
* Note that M207 / M208 / M209 settings are saved to EEPROM.
|
||||
*/
|
||||
#if ANY(ABL_Bilinear, SKR12Pro)
|
||||
#define FWRETRACT
|
||||
#endif
|
||||
//#define FWRETRACT
|
||||
#if ENABLED(FWRETRACT)
|
||||
#define FWRETRACT_AUTORETRACT // Override slicer retractions
|
||||
#if ENABLED(FWRETRACT_AUTORETRACT)
|
||||
@@ -2804,9 +2766,9 @@
|
||||
// Z raise distance for tool-change, as needed for some extruders
|
||||
#define TOOLCHANGE_ZRAISE 2 // (mm)
|
||||
//#define TOOLCHANGE_ZRAISE_BEFORE_RETRACT // Apply raise before swap retraction (if enabled)
|
||||
#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change
|
||||
//#define TOOLCHANGE_NO_RETURN // Never return to previous position on tool-change
|
||||
#if ENABLED(TOOLCHANGE_NO_RETURN)
|
||||
#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
|
||||
//#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -2835,11 +2797,11 @@
|
||||
* Retract and prime filament on tool-change to reduce
|
||||
* ooze and stringing and to get cleaner transitions.
|
||||
*/
|
||||
#define TOOLCHANGE_FILAMENT_SWAP
|
||||
//#define TOOLCHANGE_FILAMENT_SWAP
|
||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||
// Load / Unload
|
||||
#define TOOLCHANGE_FS_LENGTH 4 // (mm) Load / Unload length
|
||||
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 2 // (mm) Extra length for better restart. Adjust with LCD or M217 B.
|
||||
#define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length
|
||||
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B.
|
||||
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading)
|
||||
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down)
|
||||
|
||||
@@ -2925,45 +2887,45 @@
|
||||
#define ADVANCED_PAUSE_FEATURE
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
#define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate.
|
||||
#define PAUSE_PARK_RETRACT_LENGTH 4 // (mm) Initial retract.
|
||||
#define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract.
|
||||
// This short retract is done immediately, before parking the nozzle.
|
||||
#define FILAMENT_CHANGE_UNLOAD_FEEDRATE 41 // (mm/s) Unload filament feedrate. This can be pretty fast.
|
||||
#define FILAMENT_CHANGE_UNLOAD_FEEDRATE 10 // (mm/s) Unload filament feedrate. This can be pretty fast.
|
||||
#define FILAMENT_CHANGE_UNLOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate.
|
||||
#define FILAMENT_CHANGE_UNLOAD_LENGTH 70 // (mm) The length of filament for a complete unload.
|
||||
#define FILAMENT_CHANGE_UNLOAD_LENGTH 100 // (mm) The length of filament for a complete unload.
|
||||
// For Bowden, the full length of the tube and nozzle.
|
||||
// For direct drive, the full length of the nozzle.
|
||||
// Set to 0 for manual unloading.
|
||||
#define FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE 6 // (mm/s) Slow move when starting load.
|
||||
#define FILAMENT_CHANGE_SLOW_LOAD_LENGTH 0 // (mm) Slow length, to allow time to insert material.
|
||||
// 0 to disable start loading and skip to fast load only
|
||||
#define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 30 // (mm/s) Load filament feedrate. This can be pretty fast.
|
||||
#define FILAMENT_CHANGE_FAST_LOAD_FEEDRATE 6 // (mm/s) Load filament feedrate. This can be pretty fast.
|
||||
#define FILAMENT_CHANGE_FAST_LOAD_ACCEL 25 // (mm/s^2) Lower acceleration may allow a faster feedrate.
|
||||
#define FILAMENT_CHANGE_FAST_LOAD_LENGTH 50 // (mm) Load length of filament, from extruder gear to nozzle.
|
||||
#define FILAMENT_CHANGE_FAST_LOAD_LENGTH 0 // (mm) Load length of filament, from extruder gear to nozzle.
|
||||
// For Bowden, the full length of the tube and nozzle.
|
||||
// For direct drive, the full length of the nozzle.
|
||||
//#define ADVANCED_PAUSE_CONTINUOUS_PURGE // Purge continuously up to the purge length until interrupted.
|
||||
#define ADVANCED_PAUSE_PURGE_FEEDRATE 3 // (mm/s) Extrude feedrate (after loading). Should be slower than load feedrate.
|
||||
#define ADVANCED_PAUSE_PURGE_LENGTH 20 // (mm) Length to extrude after loading.
|
||||
#define ADVANCED_PAUSE_PURGE_LENGTH 50 // (mm) Length to extrude after loading.
|
||||
// Set to 0 for manual extrusion.
|
||||
// Filament can be extruded repeatedly from the Filament Change menu
|
||||
// until extrusion is consistent, and to purge old filament.
|
||||
#define ADVANCED_PAUSE_RESUME_PRIME 2 // (mm) Extra distance to prime nozzle after returning from park.
|
||||
#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused.
|
||||
#define ADVANCED_PAUSE_RESUME_PRIME 0 // (mm) Extra distance to prime nozzle after returning from park.
|
||||
//#define ADVANCED_PAUSE_FANS_PAUSE // Turn off print-cooling fans while the machine is paused.
|
||||
|
||||
// Filament Unload does a Retract, Delay, and Purge first:
|
||||
#define FILAMENT_UNLOAD_PURGE_RETRACT 4 // (mm) Unload initial retract length.
|
||||
#define FILAMENT_UNLOAD_PURGE_DELAY 2000 // (ms) Delay for the filament to cool after retract.
|
||||
#define FILAMENT_UNLOAD_PURGE_RETRACT 13 // (mm) Unload initial retract length.
|
||||
#define FILAMENT_UNLOAD_PURGE_DELAY 5000 // (ms) Delay for the filament to cool after retract.
|
||||
#define FILAMENT_UNLOAD_PURGE_LENGTH 8 // (mm) An unretract is done, then this length is purged.
|
||||
#define FILAMENT_UNLOAD_PURGE_FEEDRATE 25 // (mm/s) feedrate to purge before unload
|
||||
|
||||
#define PAUSE_PARK_NOZZLE_TIMEOUT 45 // (seconds) Time limit before the nozzle is turned off for safety.
|
||||
#define FILAMENT_CHANGE_ALERT_BEEPS 1 // Number of alert beeps to play when a response is needed.
|
||||
#define FILAMENT_CHANGE_ALERT_BEEPS 10 // Number of alert beeps to play when a response is needed.
|
||||
#define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change.
|
||||
//#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again.
|
||||
//#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing.
|
||||
|
||||
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
|
||||
#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
|
||||
//#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
|
||||
|
||||
#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
|
||||
#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
|
||||
@@ -2988,14 +2950,17 @@
|
||||
* Some boards have simple jumper connections! See your board's documentation.
|
||||
* - These drivers can also be used with Hardware Serial.
|
||||
*
|
||||
* The TMC26XStepper library is required for TMC26X stepper drivers.
|
||||
* https://github.com/MarlinFirmware/TMC26XStepper
|
||||
*
|
||||
* The TMCStepper library is required for other TMC stepper drivers.
|
||||
* https://github.com/teemuatlut/TMCStepper
|
||||
*
|
||||
* @section tmc/config
|
||||
*/
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
#if HAS_TRINAMIC_CONFIG || HAS_TMC26X
|
||||
|
||||
#define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current
|
||||
#define HOLD_MULTIPLIER 0.7 // Scales down the holding current from run current
|
||||
|
||||
/**
|
||||
* Interpolate microsteps to 256
|
||||
@@ -3007,7 +2972,7 @@
|
||||
#define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
|
||||
#define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing
|
||||
#define X_MICROSTEPS 16 // 0..256
|
||||
#define X_RSENSE 0.11
|
||||
#define X_RSENSE 0.022 // Multiplied x1000 for TMC26X
|
||||
#define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
|
||||
//#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis
|
||||
//#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis
|
||||
@@ -3027,7 +2992,7 @@
|
||||
#define Y_CURRENT 800
|
||||
#define Y_CURRENT_HOME Y_CURRENT
|
||||
#define Y_MICROSTEPS 16
|
||||
#define Y_RSENSE 0.11
|
||||
#define Y_RSENSE 0.022
|
||||
#define Y_CHAIN_POS -1
|
||||
//#define Y_INTERPOLATE true
|
||||
//#define Y_HOLD_MULTIPLIER 0.5
|
||||
@@ -3144,7 +3109,7 @@
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC_CONFIG(E0)
|
||||
#define E0_CURRENT 800
|
||||
#define E0_CURRENT 900
|
||||
#define E0_MICROSTEPS 16
|
||||
#define E0_RSENSE 0.11
|
||||
#define E0_CHAIN_POS -1
|
||||
@@ -3249,7 +3214,7 @@
|
||||
* The default SW SPI pins are defined the respective pins files,
|
||||
* but you can override or define them here.
|
||||
*/
|
||||
//#define TMC_USE_SW_SPI
|
||||
#define TMC_USE_SW_SPI
|
||||
//#define TMC_SPI_MOSI -1
|
||||
//#define TMC_SPI_MISO -1
|
||||
//#define TMC_SPI_SCK -1
|
||||
@@ -3309,7 +3274,7 @@
|
||||
* When disabled, Marlin will use spreadCycle stepping mode.
|
||||
*/
|
||||
#if HAS_STEALTHCHOP
|
||||
#define STEALTHCHOP_XY
|
||||
//#define STEALTHCHOP_XY
|
||||
#define STEALTHCHOP_Z
|
||||
#define STEALTHCHOP_I
|
||||
#define STEALTHCHOP_J
|
||||
@@ -3317,7 +3282,7 @@
|
||||
#define STEALTHCHOP_U
|
||||
#define STEALTHCHOP_V
|
||||
#define STEALTHCHOP_W
|
||||
#define STEALTHCHOP_E
|
||||
//#define STEALTHCHOP_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -3335,11 +3300,11 @@
|
||||
* Define your own with:
|
||||
* { <off_time[1..15]>, <hysteresis_end[-3..12]>, hysteresis_start[1..8] }
|
||||
*/
|
||||
#define CHOPPER_TIMING CHOPPER_DEFAULT_24V // All axes (override below)
|
||||
//#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below)
|
||||
//#define CHOPPER_TIMING CHOPPER_DEFAULT_36V // All axes (override below)
|
||||
#define CHOPPER_TIMING_X CHOPPER_DEFAULT_36V // For X Axes (override below)
|
||||
//#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X
|
||||
//#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below)
|
||||
//#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
|
||||
#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_36V // For Y Axes (override below)
|
||||
#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
|
||||
//#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below)
|
||||
//#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
|
||||
//#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
|
||||
@@ -3350,7 +3315,7 @@
|
||||
//#define CHOPPER_TIMING_U CHOPPER_TIMING // For U Axis
|
||||
//#define CHOPPER_TIMING_V CHOPPER_TIMING // For V Axis
|
||||
//#define CHOPPER_TIMING_W CHOPPER_TIMING // For W Axis
|
||||
//#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below)
|
||||
#define CHOPPER_TIMING_E CHOPPER_DEFAULT_24V // For Extruders (override below)
|
||||
//#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
|
||||
//#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E
|
||||
//#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E
|
||||
@@ -3377,7 +3342,7 @@
|
||||
#if ENABLED(MONITOR_DRIVER_STATUS)
|
||||
#define CURRENT_STEP_DOWN 50 // [mA]
|
||||
#define REPORT_CURRENT_CHANGE
|
||||
#define STOP_ON_ERROR
|
||||
//#define STOP_ON_ERROR
|
||||
#endif
|
||||
|
||||
// @section tmc/hybrid
|
||||
@@ -3389,7 +3354,7 @@
|
||||
* STEALTHCHOP_(XY|Z|E) must be enabled to use HYBRID_THRESHOLD.
|
||||
* M913 X/Y/Z/E to live tune the setting
|
||||
*/
|
||||
#define HYBRID_THRESHOLD
|
||||
//#define HYBRID_THRESHOLD
|
||||
|
||||
#define X_HYBRID_THRESHOLD 100 // [mm/s]
|
||||
#define X2_HYBRID_THRESHOLD 100
|
||||
@@ -3500,7 +3465,7 @@
|
||||
*/
|
||||
#define TMC_ADV() { }
|
||||
|
||||
#endif // HAS_TRINAMIC_CONFIG
|
||||
#endif // HAS_TRINAMIC_CONFIG || HAS_TMC26X
|
||||
|
||||
// @section i2cbus
|
||||
|
||||
@@ -3593,7 +3558,7 @@
|
||||
* Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
|
||||
* to set spindle speed, spindle direction, and laser power.
|
||||
*
|
||||
* SuperPID is a router/spindle speed controller used in the CNC milling community.
|
||||
* SuperPid is a router/spindle speed controller used in the CNC milling community.
|
||||
* Marlin can be used to turn the spindle on and off. It can also be used to set
|
||||
* the spindle speed from 5,000 to 30,000 RPM.
|
||||
*
|
||||
@@ -3607,10 +3572,7 @@
|
||||
#if ANY(SPINDLE_FEATURE, LASER_FEATURE)
|
||||
#define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH
|
||||
|
||||
#if ENABLED(SKR12Pro)
|
||||
#define SPINDLE_LASER_ENA_PIN PE4
|
||||
#endif
|
||||
//#define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power
|
||||
#define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power
|
||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
||||
#define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
|
||||
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC)
|
||||
@@ -3661,8 +3623,8 @@
|
||||
#define SPINDLE_CHANGE_DIR_STOP // Enable if the spindle should stop before changing spin direction
|
||||
#define SPINDLE_INVERT_DIR false // Set to "true" if the spin direction is reversed
|
||||
|
||||
#define SPINDLE_LASER_POWERUP_DELAY 1 // (ms) Delay to allow the spindle/laser to come up to speed/power
|
||||
#define SPINDLE_LASER_POWERDOWN_DELAY 1 // (ms) Delay to allow the spindle to stop
|
||||
#define SPINDLE_LASER_POWERUP_DELAY 5000 // (ms) Delay to allow the spindle/laser to come up to speed/power
|
||||
#define SPINDLE_LASER_POWERDOWN_DELAY 5000 // (ms) Delay to allow the spindle to stop
|
||||
|
||||
/**
|
||||
* M3/M4 Power Equation
|
||||
@@ -4041,41 +4003,33 @@
|
||||
// @section custom main menu
|
||||
|
||||
// Custom Menu: Main Menu
|
||||
#define CUSTOM_MENU_MAIN
|
||||
//#define CUSTOM_MENU_MAIN
|
||||
#if ENABLED(CUSTOM_MENU_MAIN)
|
||||
//#define CUSTOM_MENU_MAIN_SCRIPT_DONE "M117 User Script Done"
|
||||
#define CUSTOM_MENU_MAIN_TITLE "Setup"
|
||||
//#define CUSTOM_MENU_MAIN_TITLE "Custom Commands"
|
||||
#define CUSTOM_MENU_MAIN_SCRIPT_DONE "M117 User Script Done"
|
||||
#define CUSTOM_MENU_MAIN_SCRIPT_AUDIBLE_FEEDBACK
|
||||
#define CUSTOM_MENU_MAIN_SCRIPT_RETURN // Return to status screen after a script
|
||||
//#define CUSTOM_MENU_MAIN_SCRIPT_RETURN // Return to status screen after a script
|
||||
#define CUSTOM_MENU_MAIN_ONLY_IDLE // Only show custom menu when the machine is idle
|
||||
|
||||
#if ENABLED(TREX3)
|
||||
#define COMMFANNSPEED " "
|
||||
#else
|
||||
#define COMMFANNSPEED "M106 S128 \n"
|
||||
#endif
|
||||
#define MAIN_MENU_ITEM_1_DESC "Home & UBL Info"
|
||||
#define MAIN_MENU_ITEM_1_GCODE "G28\nG29 W"
|
||||
//#define MAIN_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action
|
||||
|
||||
#define MAIN_MENU_ITEM_1_DESC "Mesh Setup"
|
||||
#define MAIN_MENU_ITEM_1_CONFIRM
|
||||
#define MAIN_MENU_ITEM_3_DESC "Prep for Z Adjust"
|
||||
#if ENABLED(ABL_Bilinear)
|
||||
#define MAIN_MENU_ITEM_1_GCODE "M502 \n M500 \n M501 \n M190 S75 \n G28 \n G29 \n M500 \n G28 \n M420 S1 \n " COMMFANNSPEED " M109 S225 \n G1 X100 Y 100 \n G1 Z0 \n M77 \n M117 Set Z Offset"
|
||||
#define MAIN_MENU_ITEM_3_GCODE "M190 S75 \n " COMMFANNSPEED " M104 235 \n G28 \n M420 S1 \n G1 X100 Y 100 \n G1 Z0"
|
||||
#else
|
||||
#define MAIN_MENU_ITEM_1_GCODE "M502 \n M500 \n M501 \n M190 S75 \n G28 \n G29 P1 \n G29 S1 \n G29 S0 \n G29 F 10.0 \n G29 A \n M500 \n G28 \n G29 L1 \n " COMMFANNSPEED " M109 S225 \n G1 X150 Y 150 \n G1 Z0 \n M77 \n M117 Set Z Offset"
|
||||
#define MAIN_MENU_ITEM_3_GCODE "M190 S75 \n " COMMFANNSPEED " M104 235 \n G28 \n G29 L1 \n G1 X100 Y 100 \n G1 Z0"
|
||||
#endif
|
||||
#define MAIN_MENU_ITEM_2_DESC "Preheat for " PREHEAT_1_LABEL
|
||||
#define MAIN_MENU_ITEM_2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
|
||||
//#define MAIN_MENU_ITEM_2_CONFIRM
|
||||
|
||||
#define MAIN_MENU_ITEM_4_DESC "Fill Mesh Points"
|
||||
#define MAIN_MENU_ITEM_4_GCODE "G29 P3 \n G29 P3 \n G29 P3 \n G29 T"
|
||||
//#define MAIN_MENU_ITEM_3_DESC "Preheat for " PREHEAT_2_LABEL
|
||||
//#define MAIN_MENU_ITEM_3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
|
||||
//#define MAIN_MENU_ITEM_3_CONFIRM
|
||||
|
||||
#define MAIN_MENU_ITEM_2_DESC "PID Bed"
|
||||
#define MAIN_MENU_ITEM_2_GCODE "M303 C4 S75 E-1 U \n M500 \n M117 PID Tune Done"
|
||||
#define MAIN_MENU_ITEM_2_CONFIRM
|
||||
//#define MAIN_MENU_ITEM_4_DESC "Heat Bed/Home/Level"
|
||||
//#define MAIN_MENU_ITEM_4_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29"
|
||||
//#define MAIN_MENU_ITEM_4_CONFIRM
|
||||
|
||||
#define MAIN_MENU_ITEM_5_DESC "Run Mesh Validation"
|
||||
#define MAIN_MENU_ITEM_5_GCODE "G26"
|
||||
#define MAIN_MENU_ITEM_5_CONFIRM
|
||||
//#define MAIN_MENU_ITEM_5_DESC "Home & Info"
|
||||
//#define MAIN_MENU_ITEM_5_GCODE "G28\nM503"
|
||||
//#define MAIN_MENU_ITEM_5_CONFIRM
|
||||
#endif
|
||||
|
||||
// @section custom config menu
|
||||
@@ -4125,6 +4079,22 @@
|
||||
#define BUTTON1_GCODE "G28"
|
||||
#define BUTTON1_DESC "Homing" // Optional string to set the LCD status
|
||||
#endif
|
||||
|
||||
//#define BUTTON2_PIN -1
|
||||
#if PIN_EXISTS(BUTTON2)
|
||||
#define BUTTON2_HIT_STATE LOW
|
||||
#define BUTTON2_WHEN_PRINTING false
|
||||
#define BUTTON2_GCODE "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
|
||||
#define BUTTON2_DESC "Preheat for " PREHEAT_1_LABEL
|
||||
#endif
|
||||
|
||||
//#define BUTTON3_PIN -1
|
||||
#if PIN_EXISTS(BUTTON3)
|
||||
#define BUTTON3_HIT_STATE LOW
|
||||
#define BUTTON3_WHEN_PRINTING false
|
||||
#define BUTTON3_GCODE "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
|
||||
#define BUTTON3_DESC "Preheat for " PREHEAT_2_LABEL
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// @section host
|
||||
@@ -4338,7 +4308,6 @@
|
||||
// See class CodeProfiler.
|
||||
//#define MAX7219_DEBUG_MULTISTEPPING 6 // Show multi-stepping 1 to 128 on this LED matrix row.
|
||||
//#define MAX7219_DEBUG_SLOWDOWN 6 // Count (mod 16) how many times SLOWDOWN has reduced print speed.
|
||||
//#define MAX7219_REINIT_ON_POWERUP // Re-initialize MAX7129 when power supply turns on
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -4372,7 +4341,7 @@
|
||||
* Extras for an ESP32-based motherboard with WIFISUPPORT
|
||||
* These options don't apply to add-on WiFi modules based on ESP32 WiFi101.
|
||||
*/
|
||||
#if ANY(WIFISUPPORT, ESP3D_WIFISUPPORT)
|
||||
#if ENABLED(WIFISUPPORT)
|
||||
//#define WEBSUPPORT // Start a webserver (which may include auto-discovery) using SPIFFS
|
||||
//#define OTASUPPORT // Support over-the-air firmware updates
|
||||
//#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host
|
||||
@@ -4519,7 +4488,7 @@
|
||||
//
|
||||
// M42 - Set pin states
|
||||
//
|
||||
//#define DIRECT_PIN_CONTROL
|
||||
#define DIRECT_PIN_CONTROL
|
||||
|
||||
//
|
||||
// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe
|
||||
@@ -4555,6 +4524,3 @@
|
||||
|
||||
// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR.
|
||||
//#define OPTIBOOT_RESET_REASON
|
||||
|
||||
// Shrink the build for smaller boards by sacrificing some serial feedback
|
||||
//#define MARLIN_SMALL_BUILD
|
||||
|
||||
+6
-6
@@ -28,25 +28,25 @@
|
||||
/**
|
||||
* Marlin release version identifier
|
||||
*/
|
||||
#define SHORT_BUILD_VERSION "2.1.x-TR1"
|
||||
//#define SHORT_BUILD_VERSION "bugfix-2.1.x"
|
||||
|
||||
/**
|
||||
* Verbose version identifier which should contain a reference to the location
|
||||
* from where the binary was downloaded or the source code was compiled.
|
||||
*/
|
||||
#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " TM3D"
|
||||
//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION
|
||||
|
||||
/**
|
||||
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
//#define STRING_DISTRIBUTION_DATE "2024-04-11"
|
||||
//#define STRING_DISTRIBUTION_DATE "2024-05-27"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
*/
|
||||
#define MACHINE_NAME "TM3D Trex"
|
||||
//#define MACHINE_NAME "3D Printer"
|
||||
|
||||
/**
|
||||
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
|
||||
@@ -54,7 +54,7 @@
|
||||
* has a distinct Github fork— the Source Code URL should just be the main
|
||||
* Marlin repository.
|
||||
*/
|
||||
#define SOURCE_CODE_URL "https://github.com/InsanityAutomation/Marlin/tree/TM_Trex2+_2.0.x"
|
||||
//#define SOURCE_CODE_URL "github.com/MarlinFirmware/Marlin"
|
||||
|
||||
/**
|
||||
* Default generic printer UUID.
|
||||
@@ -65,7 +65,7 @@
|
||||
* The WEBSITE_URL is the location where users can get more information such as
|
||||
* documentation about a specific Marlin release.
|
||||
*/
|
||||
#define WEBSITE_URL "tinymachines3d.com"
|
||||
//#define WEBSITE_URL "marlinfw.org"
|
||||
|
||||
/**
|
||||
* Set the vendor info the serial USB interface, if changable
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom Bitmap for splashscreen
|
||||
*
|
||||
* You may use one of the following tools to generate the C++ bitmap array from
|
||||
* a black and white image:
|
||||
*
|
||||
* - http://www.marlinfw.org/tools/u8glib/converter.html
|
||||
* - http://www.digole.com/tools/PicturetoC_Hex_converter.php
|
||||
*/
|
||||
|
||||
#define CUSTOM_BOOTSCREEN_TIMEOUT 2500
|
||||
#define CUSTOM_BOOTSCREEN_BMPWIDTH 128
|
||||
#define CUSTOM_BOOTSCREEN_INVERTED
|
||||
|
||||
const unsigned char custom_start_bmp[] PROGMEM = {
|
||||
B11111101,B01010101,B01010101,B01010101,B01010101,B01010101,B01011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111110,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111101,B00000000,B00000000,B00000111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111110,B00000111,B11000000,B00000101,B01010101,B01010101,B01010101,B01010101,B01010101,B01011111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111100,B00001010,B00100000,B00000110,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111110,B00010100,B00010000,B00000101,B00000000,B00000000,B00000111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111100,B00101000,B00001000,B00000110,B00000111,B11000000,B00000101,B01010101,B01010101,B01010101,B01010101,B01010101,B01011111,B11111111,B11111111,B11111111,
|
||||
B11111110,B01010100,B00000100,B00000100,B00001010,B00100000,B00000110,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,B11111111,B11111111,B11111111,
|
||||
B11111100,B01100000,B00000100,B00000110,B00010100,B00010000,B00000101,B00000000,B00000000,B00000111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111110,B01010000,B00000100,B00000100,B00101000,B00001000,B00000110,B00000111,B11000000,B00000101,B01010101,B01010101,B01010101,B01010101,B01010101,B01011111,
|
||||
B11111100,B01100000,B00000100,B00000110,B01010100,B00000100,B00000100,B00001010,B00100000,B00000110,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
|
||||
B11111110,B01010100,B00000100,B00011100,B01100000,B00000100,B00000110,B00010100,B00010000,B00000101,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,
|
||||
B11111100,B00101000,B00001000,B00101110,B01010000,B00000100,B00000100,B00101000,B00001000,B00000110,B00000111,B11000000,B00000000,B00000001,B11110000,B00111111,
|
||||
B11111110,B00010100,B00010000,B01010100,B01100000,B00000100,B00000110,B01010100,B00000100,B00000100,B00001010,B00100000,B00000000,B00000010,B00001000,B00011111,
|
||||
B11111100,B00001010,B00100000,B01100110,B01010100,B00000100,B00011100,B01100000,B00000100,B00000110,B00010100,B00010000,B00000000,B00000101,B00000100,B00111111,
|
||||
B11111110,B00000111,B11000000,B01010100,B00101000,B00001000,B00101110,B01010000,B00000100,B00000100,B00101000,B00001000,B00000000,B00001010,B00000010,B00011111,
|
||||
B11111100,B00000000,B00000000,B00101110,B00010100,B00010000,B01010100,B01100000,B00000100,B00000110,B01010100,B00000100,B00000000,B00010101,B00000001,B00111111,
|
||||
B11111110,B00000000,B00000000,B00011100,B00001010,B00100000,B01100110,B01010100,B00000100,B00011100,B01100000,B00000100,B00000000,B00011000,B00000001,B00011111,
|
||||
B11111100,B00000000,B00000000,B00000110,B00000111,B11000000,B01010100,B00101000,B00001000,B00101110,B01010000,B00000100,B00000000,B00010100,B00000001,B00111111,
|
||||
B11111110,B00000000,B00000000,B00000100,B00000000,B00000000,B00101110,B00010100,B00010000,B01010100,B01100000,B00000100,B00000000,B00011000,B00000001,B00011111,
|
||||
B11111100,B11111111,B11111111,B11111110,B00000000,B00000000,B00011100,B00001010,B00100000,B01100110,B01010100,B00000100,B00011100,B00010101,B00000001,B00111111,
|
||||
B11111110,B11010101,B01010101,B01010100,B00000000,B00000000,B00000110,B00000111,B11000000,B01010100,B00101000,B00001000,B00101010,B00001010,B00000010,B00011111,
|
||||
B11111100,B10000100,B00010000,B01000110,B00000000,B00000000,B00000100,B00000000,B00000000,B00101110,B00010100,B00010000,B01010001,B00000101,B00000100,B00111111,
|
||||
B11111110,B11000100,B00010000,B01000100,B11111111,B11111111,B11111110,B00000000,B00000000,B00011100,B00001010,B00100000,B01100001,B00000010,B10001000,B00011111,
|
||||
B11111100,B10000100,B00010000,B01000110,B11010101,B01010101,B01010100,B00000000,B00000000,B00000110,B00000111,B11000000,B01010001,B00000001,B11110000,B00111111,
|
||||
B11111110,B10000100,B00010000,B01000100,B10000100,B00010000,B01000110,B00000000,B00000000,B00000100,B00000000,B00000000,B00101010,B00000000,B00000000,B00011111,
|
||||
B11111100,B11000100,B00010000,B01000110,B11000100,B00010000,B01000100,B11111111,B11111111,B11111110,B00000000,B00000000,B00011100,B00000000,B00000000,B00111111,
|
||||
B11111110,B10000100,B00010000,B01000100,B10000100,B00010000,B01000110,B11010101,B01010101,B01010100,B00000000,B00000000,B00000000,B00000000,B00000000,B00011111,
|
||||
B11111100,B11010101,B01010101,B01010110,B10000100,B00010000,B01000100,B10000100,B00010000,B01000110,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
|
||||
B11111100,B11111111,B11111111,B11111100,B11000100,B00010000,B01000110,B11000100,B00010000,B01000100,B11111111,B11111111,B11111111,B11111111,B11111111,B10011111,
|
||||
B11111110,B00000000,B00000000,B00000110,B10000100,B00010000,B01000100,B10000100,B00010000,B01000110,B11010101,B01010101,B01010101,B01010101,B01010101,B10111111,
|
||||
B11111101,B01010101,B01010101,B01010100,B11010101,B01010101,B01010110,B10000100,B00010000,B01000100,B10000100,B00010000,B01000001,B00000100,B00010000,B10011111,
|
||||
B11111111,B11111111,B11111111,B11111100,B11111111,B11111111,B11111100,B11000100,B00010000,B01000110,B11000100,B00010000,B01000001,B00000100,B00010001,B10111111,
|
||||
B11111111,B11111111,B11111111,B11111110,B00000000,B00000000,B00000110,B10000100,B00010000,B01000100,B10000100,B00010000,B01000001,B00000100,B00010000,B10011111,
|
||||
B11111111,B11111111,B11111111,B11111101,B01010101,B01010101,B01010100,B11010101,B01010101,B01010110,B10000100,B00010000,B01000001,B00000100,B00010000,B10011111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,B11111111,B11111111,B11111100,B11000100,B00010000,B01000001,B00000100,B00010001,B10111111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111110,B00000000,B00000000,B00000110,B10000100,B00010000,B01000001,B00000100,B00010000,B10011111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111101,B01010101,B01010101,B01010100,B11010101,B01010101,B01010101,B01010101,B01010101,B10111111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,B11111111,B11111111,B11111111,B11111111,B11111111,B10011111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111110,B00000000,B00000000,B00000000,B00000000,B00000000,B00111111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111101,B01010101,B01010101,B01010101,B01010101,B01010101,B01011111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,
|
||||
B11100000,B00101110,B11111011,B01111101,B11111011,B11111011,B11001111,B11000001,B11011111,B10111011,B00111110,B11000000,B11100001,B11111110,B00111100,B00011111,
|
||||
B11111101,B11101110,B01111011,B00111001,B11111001,B11110011,B11001111,B10011110,B11011111,B10111011,B00111110,B11011111,B11011110,B11111100,B11011101,B11100111,
|
||||
B11111101,B11101110,B00111011,B10111011,B11111001,B11101011,B11010111,B10111111,B01011111,B10111011,B01011110,B11011111,B11011110,B11111101,B11101101,B11110111,
|
||||
B11111101,B11101110,B10111011,B11010011,B11111010,B11101011,B10110111,B00111111,B11011111,B10111011,B01001110,B11011111,B11011111,B11111111,B11001101,B11110011,
|
||||
B11111101,B11101110,B11011011,B11000111,B11111010,B11101011,B10111011,B01111111,B11000000,B00111011,B01101110,B11000000,B11100011,B11111111,B00011101,B11110011,
|
||||
B11111101,B11101110,B11001011,B11101111,B11111010,B11011011,B10111011,B01111111,B11011111,B10111011,B01100110,B11011111,B11111000,B11111111,B11001101,B11110011,
|
||||
B11111101,B11101110,B11101011,B11101111,B11111011,B01011011,B00000011,B00111111,B01011111,B10111011,B01110110,B11011111,B11111110,B01111111,B11101101,B11110011,
|
||||
B11111101,B11101110,B11110011,B11101111,B11111011,B01011011,B01111001,B10111110,B11011111,B10111011,B01111010,B11011111,B11011110,B01111101,B11101101,B11110111,
|
||||
B11111101,B11101110,B11110011,B11101111,B11111011,B10111010,B11111101,B10011110,B11011111,B10111011,B01111100,B11011111,B11011110,B11111101,B11001101,B11100111,
|
||||
B11111101,B11101110,B11111011,B11101111,B11111011,B10111010,B11111101,B11000001,B11011111,B10111011,B01111110,B11000000,B11100000,B11111110,B00011100,B00011111
|
||||
};
|
||||
@@ -1,74 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Custom Status Screen bitmap
|
||||
*
|
||||
* Place this file in the root with your configuration files
|
||||
* and enable CUSTOM_STATUS_SCREEN_IMAGE in Configuration.h.
|
||||
*
|
||||
* Use the Marlin Bitmap Converter to make your own:
|
||||
* http://marlinfw.org/tools/u8glib/converter.html
|
||||
*/
|
||||
|
||||
//
|
||||
// Status Screen Logo bitmap
|
||||
//
|
||||
#define STATUS_LOGO_Y 3
|
||||
#define STATUS_LOGO_WIDTH 24
|
||||
|
||||
const unsigned char status_logo_bmp[] PROGMEM = {
|
||||
B11111111,B11111111,B11111111,
|
||||
B10000000,B00000000,B00000001,
|
||||
B10001110,B00000000,B11100001,
|
||||
B10011111,B00000001,B11110001,
|
||||
B10010011,B10000001,B00111001,
|
||||
B10011111,B10000001,B11111001,
|
||||
B10011111,B10000001,B11111001,
|
||||
B10011111,B10111001,B11111001,
|
||||
B10001111,B00101000,B11110001,
|
||||
B10000000,B00111000,B00000001,
|
||||
B10000000,B00000000,B00000001,
|
||||
B10011111,B11111111,B11111001,
|
||||
B10010001,B01110100,B10011001,
|
||||
B10011011,B00000110,B10101001,
|
||||
B10011011,B01010100,B10101001,
|
||||
B10011011,B01010110,B10101001,
|
||||
B10011011,B01010100,B10011001,
|
||||
B10011111,B11111111,B11111001,
|
||||
B11111111,B11111111,B11111111
|
||||
};
|
||||
|
||||
//
|
||||
// Use default bitmaps
|
||||
//
|
||||
#define STATUS_HOTEND_ANIM
|
||||
#define STATUS_BED_ANIM
|
||||
#if HOTENDS < 2
|
||||
#define STATUS_LOGO_X 8
|
||||
#define STATUS_HEATERS_X 40
|
||||
#define STATUS_BED_X 72
|
||||
#else
|
||||
#define STATUS_LOGO_X 0
|
||||
#define STATUS_HEATERS_X 32
|
||||
#define STATUS_BED_X 80
|
||||
#endif
|
||||
@@ -61,7 +61,7 @@
|
||||
#else
|
||||
#define G2_PWM_Z 0
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
#define G2_PWM_E 1
|
||||
#else
|
||||
#define G2_PWM_E 0
|
||||
|
||||
@@ -18,30 +18,30 @@ extern "C" {
|
||||
void sd_mmc_spi_mem_init() {
|
||||
}
|
||||
|
||||
Ctrl_status sd_mmc_spi_test_unit_ready() {
|
||||
#ifdef DISABLE_DUE_SD_MMC
|
||||
return CTRL_NO_PRESENT;
|
||||
#endif
|
||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
|
||||
return CTRL_NO_PRESENT;
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
// NOTE: This function is defined as returning the address of the last block
|
||||
// in the card, which is cardSize() - 1
|
||||
Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
|
||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
|
||||
return CTRL_NO_PRESENT;
|
||||
*nb_sector = card.diskIODriver()->cardSize() - 1;
|
||||
return CTRL_GOOD;
|
||||
inline bool media_ready() {
|
||||
return IS_SD_INSERTED() && !IS_SD_PRINTING() && !IS_SD_FILE_OPEN() && card.isMounted();
|
||||
}
|
||||
|
||||
bool sd_mmc_spi_unload(bool) { return true; }
|
||||
|
||||
bool sd_mmc_spi_wr_protect() { return false; }
|
||||
|
||||
bool sd_mmc_spi_removal() {
|
||||
return (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted());
|
||||
bool sd_mmc_spi_removal() { return !media_ready(); }
|
||||
|
||||
Ctrl_status sd_mmc_spi_test_unit_ready() {
|
||||
#ifdef DISABLE_DUE_SD_MMC
|
||||
return CTRL_NO_PRESENT;
|
||||
#endif
|
||||
if (!media_ready()) return CTRL_NO_PRESENT;
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
// NOTE: This function is defined as returning the address of the last block
|
||||
// in the card, which is cardSize() - 1
|
||||
Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
|
||||
if (!media_ready()) return CTRL_NO_PRESENT;
|
||||
*nb_sector = card.diskIODriver()->cardSize() - 1;
|
||||
return CTRL_GOOD;
|
||||
}
|
||||
|
||||
#if ACCESS_USB == true
|
||||
@@ -61,8 +61,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
|
||||
#ifdef DISABLE_DUE_SD_MMC
|
||||
return CTRL_NO_PRESENT;
|
||||
#endif
|
||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
|
||||
return CTRL_NO_PRESENT;
|
||||
if (!media_ready()) return CTRL_NO_PRESENT;
|
||||
|
||||
#ifdef DEBUG_MMC
|
||||
{
|
||||
@@ -101,8 +100,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
|
||||
#ifdef DISABLE_DUE_SD_MMC
|
||||
return CTRL_NO_PRESENT;
|
||||
#endif
|
||||
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
|
||||
return CTRL_NO_PRESENT;
|
||||
if (!media_ready()) return CTRL_NO_PRESENT;
|
||||
|
||||
#ifdef DEBUG_MMC
|
||||
{
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
//!
|
||||
//! @brief This function initializes the hw/sw resources required to drive the SD_MMC_SPI.
|
||||
//!/
|
||||
extern void sd_mmc_spi_mem_init(void);
|
||||
void sd_mmc_spi_mem_init();
|
||||
|
||||
//!
|
||||
//! @brief This function tests the state of the SD_MMC memory and sends it to the Host.
|
||||
@@ -87,7 +87,7 @@ extern void sd_mmc_spi_mem_init(void);
|
||||
//! Media not present -> CTRL_NO_PRESENT
|
||||
//! Media has changed -> CTRL_BUSY
|
||||
//!/
|
||||
extern Ctrl_status sd_mmc_spi_test_unit_ready(void);
|
||||
Ctrl_status sd_mmc_spi_test_unit_ready();
|
||||
|
||||
//!
|
||||
//! @brief This function gives the address of the last valid sector.
|
||||
@@ -98,7 +98,7 @@ extern Ctrl_status sd_mmc_spi_test_unit_ready(void);
|
||||
//! Media ready -> CTRL_GOOD
|
||||
//! Media not present -> CTRL_NO_PRESENT
|
||||
//!/
|
||||
extern Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector);
|
||||
Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector);
|
||||
|
||||
/*! \brief Unload/Load the SD/MMC card selected
|
||||
*
|
||||
@@ -109,7 +109,7 @@ extern Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector);
|
||||
*
|
||||
* \return \c true if unload/load done success.
|
||||
*/
|
||||
extern bool sd_mmc_spi_unload(bool unload);
|
||||
bool sd_mmc_spi_unload(bool unload);
|
||||
|
||||
//!
|
||||
//! @brief This function returns the write protected status of the memory.
|
||||
@@ -120,14 +120,14 @@ extern bool sd_mmc_spi_unload(bool unload);
|
||||
//!
|
||||
//! @return false -> the memory is not write-protected (always)
|
||||
//!/
|
||||
extern bool sd_mmc_spi_wr_protect(void);
|
||||
bool sd_mmc_spi_wr_protect();
|
||||
|
||||
//!
|
||||
//! @brief This function tells if the memory has been removed or not.
|
||||
//!
|
||||
//! @return false -> The memory isn't removed
|
||||
//!
|
||||
extern bool sd_mmc_spi_removal(void);
|
||||
bool sd_mmc_spi_removal();
|
||||
|
||||
//---- ACCESS DATA FUNCTIONS ----
|
||||
|
||||
@@ -147,7 +147,7 @@ extern bool sd_mmc_spi_removal(void);
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! A error occur -> CTRL_FAIL
|
||||
//!
|
||||
extern Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector);
|
||||
Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector);
|
||||
|
||||
//! This function initializes the SD/MMC memory for a write operation
|
||||
//!
|
||||
@@ -161,7 +161,7 @@ extern Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector);
|
||||
//! It is ready -> CTRL_GOOD
|
||||
//! An error occurs -> CTRL_FAIL
|
||||
//!
|
||||
extern Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector);
|
||||
Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector);
|
||||
|
||||
#endif // #if ACCESS_USB == true
|
||||
|
||||
|
||||
@@ -53,12 +53,11 @@ typedef uint64_t hal_timer_t;
|
||||
#if ENABLED(I2S_STEPPER_STREAM)
|
||||
#define STEPPER_TIMER_PRESCALE 1
|
||||
#define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25
|
||||
#else
|
||||
#define STEPPER_TIMER_PRESCALE 40
|
||||
#define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
|
||||
#endif
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
|
||||
|
||||
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
|
||||
|
||||
|
||||
@@ -142,12 +142,31 @@
|
||||
// ADC
|
||||
//
|
||||
#define HAL_ADC_VREF_MV 3300
|
||||
#define HAL_ADC_RESOLUTION 10
|
||||
#define HAL_ADC_RESOLUTION 12
|
||||
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
|
||||
//
|
||||
// Debug port disable
|
||||
// JTMS / SWDIO = PA13
|
||||
// JTCK / SWCLK = PA14
|
||||
// JTDI = PA15
|
||||
// JTDO = PB3
|
||||
// NJTRST = PB4
|
||||
//
|
||||
#define DBG_SWCLK _BV(0)
|
||||
#define DBG_SWDIO _BV(1)
|
||||
#define DBG_TDO _BV(2)
|
||||
#define DBG_TDI _BV(3)
|
||||
#define DBG_TRST _BV(4)
|
||||
#define DBG_ALL (DBG_SWCLK | DBG_SWDIO | DBG_TDO | DBG_TDI | DBG_TRST)
|
||||
|
||||
#define JTAGSWD_RESET() PORT_DebugPortSetting(DBG_ALL, Enable);
|
||||
#define JTAG_DISABLE() PORT_DebugPortSetting(DBG_TDO | DBG_TDI | DBG_TRST, Disable);
|
||||
#define JTAGSWD_DISABLE() PORT_DebugPortSetting(DBG_ALL, Disable);
|
||||
|
||||
//
|
||||
// MarlinHAL implementation
|
||||
//
|
||||
|
||||
@@ -123,6 +123,11 @@ void MarlinHAL::init() {
|
||||
|
||||
// Register min serial
|
||||
TERN_(POSTMORTEM_DEBUGGING, install_min_serial());
|
||||
|
||||
// warn if low memory after init
|
||||
if (freeMemory() < 1024) {
|
||||
SERIAL_WARN_MSG("HAL: low memory after init!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void MarlinHAL::init_board() {}
|
||||
@@ -147,7 +152,31 @@ void MarlinHAL::delay_ms(const int ms) {
|
||||
delay(ms);
|
||||
}
|
||||
|
||||
void MarlinHAL::idletask() {}
|
||||
void MarlinHAL::idletask() {
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
// check & print serial RX errors
|
||||
MSerialT *serials[] = { &MSerial1, &MSerial2 };
|
||||
for (int serial = 0; serial < 2; serial++) {
|
||||
usart_receive_error_t err = serials[serial]->getReceiveError();
|
||||
if (err != usart_receive_error_t::None) {
|
||||
// "Warning: MSerial[n] RX [Framing|Parity|Overrun] Error"
|
||||
SERIAL_WARN_START();
|
||||
SERIAL_ECHOPGM(" MSerial");
|
||||
SERIAL_ECHO(serial + 1);
|
||||
SERIAL_ECHOPGM(" RX ");
|
||||
switch(err) {
|
||||
case usart_receive_error_t::FramingError: SERIAL_ECHOPGM("Framing"); break;
|
||||
case usart_receive_error_t::ParityError: SERIAL_ECHOPGM("Parity"); break;
|
||||
case usart_receive_error_t::OverrunError: SERIAL_ECHOPGM("Overrun"); break;
|
||||
case usart_receive_error_t::RxDataDropped: SERIAL_ECHOPGM("DataDropped"); break;
|
||||
default: break;
|
||||
}
|
||||
SERIAL_ECHOPGM(" Error");
|
||||
SERIAL_EOL();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
// Query reset cause from RMU
|
||||
@@ -203,7 +232,9 @@ int MarlinHAL::freeMemory() {
|
||||
return &top - _sbrk(0);
|
||||
}
|
||||
|
||||
void MarlinHAL::adc_init() {}
|
||||
void MarlinHAL::adc_init() {
|
||||
analogReadResolution(HAL_ADC_RESOLUTION);
|
||||
}
|
||||
|
||||
void MarlinHAL::adc_enable(const pin_t pin) {
|
||||
#if TEMP_SENSOR_SOC
|
||||
|
||||
@@ -46,14 +46,34 @@ constexpr bool serial_handles_emergency(int port) {
|
||||
//
|
||||
// Define serial ports
|
||||
//
|
||||
#define DEFINE_HWSERIAL_MARLIN(name, n) \
|
||||
|
||||
// serial port where RX and TX use IRQs
|
||||
#define DEFINE_IRQ_SERIAL_MARLIN(name, n) \
|
||||
MSerialT name(serial_handles_emergency(n), \
|
||||
&USART##n##_config, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN);
|
||||
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial1, 1);
|
||||
DEFINE_HWSERIAL_MARLIN(MSerial2, 2);
|
||||
// serial port where RX uses DMA and TX uses IRQs
|
||||
// all serial ports use DMA1
|
||||
// since there are 4 USARTs and 4 DMA channels, we can use the USART number as the DMA channel
|
||||
#define DEFINE_DMA_SERIAL_MARLIN(name, n) \
|
||||
MSerialT name(serial_handles_emergency(n), \
|
||||
&USART##n##_config, \
|
||||
BOARD_USART##n##_TX_PIN, \
|
||||
BOARD_USART##n##_RX_PIN, \
|
||||
M4_DMA1, \
|
||||
((en_dma_channel_t)(n - 1))); // map USART1 to DMA channel 0, USART2 to DMA channel 1, etc.
|
||||
|
||||
#define DEFINE_SERIAL_MARLIN(name, n) TERN(SERIAL_DMA, DEFINE_DMA_SERIAL_MARLIN(name, n), DEFINE_IRQ_SERIAL_MARLIN(name, n))
|
||||
|
||||
DEFINE_SERIAL_MARLIN(MSerial1, 1);
|
||||
DEFINE_SERIAL_MARLIN(MSerial2, 2);
|
||||
|
||||
// TODO: remove this warning when SERIAL_DMA has been tested some more
|
||||
#if ENABLED(SERIAL_DMA)
|
||||
#warning "SERIAL_DMA may be unstable on HC32F460."
|
||||
#endif
|
||||
|
||||
//
|
||||
// Serial port assertions
|
||||
|
||||
@@ -25,17 +25,42 @@
|
||||
#include <drivers/usart/Usart.h>
|
||||
|
||||
// Optionally set uart IRQ priority to reduce overflow errors
|
||||
// #define UART_IRQ_PRIO 1
|
||||
//#define UART_RX_IRQ_PRIO 1
|
||||
//#define UART_TX_IRQ_PRIO 1
|
||||
//#define UART_RX_DMA_IRQ_PRIO 1
|
||||
|
||||
struct MarlinSerial : public Usart {
|
||||
MarlinSerial(struct usart_config_t *usart_device, gpio_pin_t tx_pin, gpio_pin_t rx_pin) : Usart(usart_device, tx_pin, rx_pin) {}
|
||||
MarlinSerial(
|
||||
struct usart_config_t *usart_device,
|
||||
gpio_pin_t tx_pin,
|
||||
gpio_pin_t rx_pin
|
||||
#if ENABLED(SERIAL_DMA)
|
||||
, M4_DMA_TypeDef *dma_unit = nullptr,
|
||||
en_dma_channel_t rx_dma_channel = DmaCh0
|
||||
#endif
|
||||
) : Usart(usart_device, tx_pin, rx_pin) {
|
||||
#if ENABLED(SERIAL_DMA)
|
||||
if (dma_unit != nullptr) {
|
||||
enableRxDma(dma_unit, rx_dma_channel);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef UART_IRQ_PRIO
|
||||
#if defined(UART_RX_IRQ_PRIO) || defined(UART_TX_IRQ_PRIO) || defined(UART_RX_DMA_IRQ_PRIO)
|
||||
void setPriority() {
|
||||
NVIC_SetPriority(c_dev()->interrupts.rx_data_available.interrupt_number, UART_IRQ_PRIO);
|
||||
NVIC_SetPriority(c_dev()->interrupts.rx_error.interrupt_number, UART_IRQ_PRIO);
|
||||
NVIC_SetPriority(c_dev()->interrupts.tx_buffer_empty.interrupt_number, UART_IRQ_PRIO);
|
||||
NVIC_SetPriority(c_dev()->interrupts.tx_complete.interrupt_number, UART_IRQ_PRIO);
|
||||
#if defined(UART_RX_IRQ_PRIO)
|
||||
NVIC_SetPriority(c_dev()->interrupts.rx_data_available.interrupt_number, UART_RX_IRQ_PRIO);
|
||||
NVIC_SetPriority(c_dev()->interrupts.rx_error.interrupt_number, UART_RX_IRQ_PRIO);
|
||||
#endif
|
||||
|
||||
#if defined(UART_TX_IRQ_PRIO)
|
||||
NVIC_SetPriority(c_dev()->interrupts.tx_buffer_empty.interrupt_number, UART_TX_IRQ_PRIO);
|
||||
NVIC_SetPriority(c_dev()->interrupts.tx_complete.interrupt_number, UART_TX_IRQ_PRIO);
|
||||
#endif
|
||||
|
||||
#if defined(UART_RX_DMA_IRQ_PRIO) && ENABLED(SERIAL_DMA)
|
||||
NVIC_SetPriority(c_dev()->dma.rx.rx_data_available_dma_btc.interrupt_number, UART_RX_DMA_IRQ_PRIO);
|
||||
#endif
|
||||
}
|
||||
|
||||
void begin(uint32_t baud) {
|
||||
@@ -47,7 +72,12 @@ struct MarlinSerial : public Usart {
|
||||
Usart::begin(baud, config);
|
||||
setPriority();
|
||||
}
|
||||
#endif
|
||||
|
||||
void begin(uint32_t baud, const stc_usart_uart_init_t *config, const bool rxNoiseFilter = true) {
|
||||
Usart::begin(baud, config, rxNoiseFilter);
|
||||
setPriority();
|
||||
}
|
||||
#endif // UART_RX_IRQ_PRIO || UART_TX_IRQ_PRIO || UART_RX_DMA_IRQ_PRIO
|
||||
};
|
||||
|
||||
typedef Serial1Class<MarlinSerial> MSerialT;
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* app_config.h is included by the hc32f460 arduino build script for every source file.
|
||||
* it is used to configure the arduino core (and ddl) automatically according
|
||||
* to the settings in Configuration.h and Configuration_adv.h.
|
||||
*/
|
||||
#pragma once
|
||||
#ifndef _HC32_APP_CONFIG_H_
|
||||
#define _HC32_APP_CONFIG_H_
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
//
|
||||
// dev mode
|
||||
//
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
#define __DEBUG 1
|
||||
#define __CORE_DEBUG 1
|
||||
#endif
|
||||
|
||||
//
|
||||
// Fault Handlers and Panic
|
||||
//
|
||||
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
// disable arduino core fault handler, as we define our own
|
||||
#define CORE_DISABLE_FAULT_HANDLER 1
|
||||
#endif
|
||||
|
||||
// force-enable panic handler so that we can use our custom one (in MinSerial)
|
||||
#define PANIC_ENABLE 1
|
||||
|
||||
// use short filenames in ddl debug and core panic output
|
||||
#define __DEBUG_SHORT_FILENAMES 1
|
||||
#define __PANIC_SHORT_FILENAMES 1
|
||||
|
||||
// omit panic messages in core panic output
|
||||
#define __OMIT_PANIC_MESSAGE 1
|
||||
|
||||
//
|
||||
// Usart
|
||||
//
|
||||
|
||||
// disable serial globals (Serial1, Serial2, ...), as we define our own
|
||||
#define DISABLE_SERIAL_GLOBALS 1
|
||||
|
||||
// increase the size of the Usart buffers (both RX and TX)
|
||||
// NOTE:
|
||||
// the heap usage will increase by (SERIAL_BUFFER_SIZE - 64) * "number of serial ports used"
|
||||
// if running out of heap, the system may become unstable
|
||||
//#define SERIAL_BUFFER_SIZE 256
|
||||
|
||||
// enable support for Usart Clock Divider / Oversampling auto config
|
||||
#define USART_AUTO_CLKDIV_OS_CONFIG 1
|
||||
|
||||
// enable USART_RX_DMA_SUPPORT core option when SERIAL_DMA is enabled
|
||||
#if ENABLED(SERIAL_DMA)
|
||||
#define USART_RX_DMA_SUPPORT 1
|
||||
#endif
|
||||
|
||||
//
|
||||
// Misc.
|
||||
//
|
||||
|
||||
// redirect printf to host serial
|
||||
#define REDIRECT_PRINTF_TO_SERIAL 1
|
||||
|
||||
// F_CPU must be known at compile time, but on HC32F460 it's not.
|
||||
// Thus we assume HCLK to be 200MHz, as that's what is configured in
|
||||
// 'core_hook_sysclock_init' in 'sysclock.cpp'.
|
||||
// If you face issues with this assumption, please double-check with the values
|
||||
// printed by 'MarlinHAL::HAL_clock_frequencies_dump'.
|
||||
// see also: HAL_TIMER_RATE in timers.h
|
||||
#define F_CPU 200000000 // 200MHz HCLK
|
||||
|
||||
#endif // _HC32_APP_CONFIG_H_
|
||||
@@ -20,6 +20,20 @@
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
#include <core_util.h>
|
||||
|
||||
#if !defined(ARDUINO_CORE_VERSION_INT) || !defined(GET_VERSION_INT)
|
||||
// version macros were introduced in arduino core version 1.1.0
|
||||
// below that version, we polyfill them
|
||||
#define GET_VERSION_INT(major, minor, patch) ((major * 100000) + (minor * 1000) + patch)
|
||||
#define ARDUINO_CORE_VERSION_INT GET_VERSION_INT(1, 0, 0)
|
||||
#endif
|
||||
|
||||
#if ARDUINO_CORE_VERSION_INT < GET_VERSION_INT(1, 1, 0)
|
||||
// because we use app_config.h introduced in arduino core version 1.1.0, the
|
||||
// HAL is not compatible with older versions
|
||||
#error "The HC32 HAL is not compatible with Arduino Core versions < 1.1.0. Consider updating the Arduino Core."
|
||||
#endif
|
||||
|
||||
#ifndef BOARD_XTAL_FREQUENCY
|
||||
#error "BOARD_XTAL_FREQUENCY is required for HC32F460."
|
||||
@@ -74,3 +88,18 @@
|
||||
#error "HC32 HAL uses a custom panic handler. Do not define PANIC_USARTx_TX_PIN."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(SERIAL_DMA)
|
||||
#if !defined(USART_RX_DMA_SUPPORT)
|
||||
#error "SERIAL_DMA requires USART_RX_DMA_SUPPORT to be enabled in the arduino core."
|
||||
#endif
|
||||
|
||||
// USART_RX_DMA_SUPPORT does not implement core_hook_usart_rx_irq, which is required for the emergency parser
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
#error "EMERGENCY_PARSER is not supported with SERIAL_DMA. Please disable either SERIAL_DMA or EMERGENCY_PARSER."
|
||||
#endif
|
||||
|
||||
#if ARDUINO_CORE_VERSION_INT < GET_VERSION_INT(1, 1, 0)
|
||||
#error "SERIAL_DMA is not supported with arduino core version < 1.1.0."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
fn \
|
||||
}
|
||||
|
||||
stc_sd_handle_t *handle;
|
||||
stc_sd_handle_t *handle = nullptr;
|
||||
|
||||
bool SDIO_Init() {
|
||||
// Configure SDIO pins
|
||||
@@ -66,36 +66,45 @@ bool SDIO_Init() {
|
||||
GPIO_SetFunc(BOARD_SDIO_CMD, Func_Sdio);
|
||||
GPIO_SetFunc(BOARD_SDIO_DET, Func_Sdio);
|
||||
|
||||
// If a handle is already initialized, free it before creating a new one
|
||||
// otherwise, we will leak memory, which will eventually crash the system
|
||||
if (handle != nullptr) {
|
||||
delete handle->pstcDmaInitCfg;
|
||||
delete handle->pstcCardInitCfg;
|
||||
delete handle;
|
||||
handle = nullptr;
|
||||
}
|
||||
|
||||
// Create DMA configuration
|
||||
stc_sdcard_dma_init_t *dmaConf = new stc_sdcard_dma_init_t;
|
||||
dmaConf->DMAx = SDIO_DMA_PERIPHERAL;
|
||||
dmaConf->enDmaCh = SDIO_DMA_CHANNEL;
|
||||
|
||||
// Create card configuration
|
||||
// This should be a fairly safe configuration for most cards
|
||||
stc_sdcard_init_t *cardConf = new stc_sdcard_init_t;
|
||||
cardConf->enBusWidth = SdiocBusWidth4Bit;
|
||||
cardConf->enClkFreq = SdiocClk400K;
|
||||
cardConf->enSpeedMode = SdiocNormalSpeedMode;
|
||||
cardConf->pstcInitCfg = nullptr;
|
||||
|
||||
// Create handle in DMA mode
|
||||
handle = new stc_sd_handle_t;
|
||||
handle->SDIOCx = SDIO_PERIPHERAL;
|
||||
handle->enDevMode = SdCardDmaMode;
|
||||
handle->pstcDmaInitCfg = dmaConf;
|
||||
|
||||
// Create card configuration
|
||||
// This should be a fairly safe configuration for most cards
|
||||
stc_sdcard_init_t cardConf = {
|
||||
.enBusWidth = SdiocBusWidth4Bit,
|
||||
.enClkFreq = SdiocClk400K,
|
||||
.enSpeedMode = SdiocNormalSpeedMode,
|
||||
//.pstcInitCfg = NULL,
|
||||
};
|
||||
//handle->pstcCardInitCfg = cardConf; // assigned in SDCARD_Init
|
||||
|
||||
// Initialize sd card
|
||||
en_result_t rc = SDCARD_Init(handle, &cardConf);
|
||||
en_result_t rc = SDCARD_Init(handle, cardConf);
|
||||
if (rc != Ok) printf("SDIO_Init() error (rc=%u)\n", rc);
|
||||
|
||||
return rc == Ok;
|
||||
}
|
||||
|
||||
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
|
||||
CORE_ASSERT(handle != NULL, "SDIO not initialized");
|
||||
CORE_ASSERT(dst != NULL, "SDIO_ReadBlock dst is NULL");
|
||||
CORE_ASSERT(handle != nullptr, "SDIO not initialized", return false);
|
||||
CORE_ASSERT(dst != nullptr, "SDIO_ReadBlock dst is NULL", return false);
|
||||
|
||||
WITH_RETRY(SDIO_READ_RETRIES, {
|
||||
en_result_t rc = SDCARD_ReadBlocks(handle, block, 1, dst, SDIO_READ_TIMEOUT);
|
||||
@@ -107,8 +116,8 @@ bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
|
||||
}
|
||||
|
||||
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
|
||||
CORE_ASSERT(handle != NULL, "SDIO not initialized");
|
||||
CORE_ASSERT(src != NULL, "SDIO_WriteBlock src is NULL");
|
||||
CORE_ASSERT(handle != nullptr, "SDIO not initialized", return false);
|
||||
CORE_ASSERT(src != nullptr, "SDIO_WriteBlock src is NULL", return false);
|
||||
|
||||
WITH_RETRY(SDIO_WRITE_RETRIES, {
|
||||
en_result_t rc = SDCARD_WriteBlocks(handle, block, 1, (uint8_t *)src, SDIO_WRITE_TIMEOUT);
|
||||
@@ -120,12 +129,12 @@ bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
|
||||
}
|
||||
|
||||
bool SDIO_IsReady() {
|
||||
CORE_ASSERT(handle != NULL, "SDIO not initialized");
|
||||
CORE_ASSERT(handle != nullptr, "SDIO not initialized", return false);
|
||||
return bool(handle->stcCardStatus.READY_FOR_DATA);
|
||||
}
|
||||
|
||||
uint32_t SDIO_GetCardSize() {
|
||||
CORE_ASSERT(handle != NULL, "SDIO not initialized");
|
||||
CORE_ASSERT(handle != nullptr, "SDIO not initialized", return 0);
|
||||
|
||||
// Multiply number of blocks with block size to get size in bytes
|
||||
const uint64_t cardSizeBytes = uint64_t(handle->stcSdCardInfo.u32LogBlockNbr) * uint64_t(handle->stcSdCardInfo.u32LogBlockSize);
|
||||
|
||||
@@ -96,29 +96,44 @@ void core_hook_sysclock_init() {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Setup clock divisors for sysclk = 200 MHz:
|
||||
// sysclk is now configured according to F_CPU (i.e., 200MHz PLL output)
|
||||
constexpr uint32_t sysclock = F_CPU;
|
||||
|
||||
// Setup clock divisors for sysclk = 200 MHz
|
||||
// Note: PCLK1 is used for step+temp timers, and need to be kept at 50 MHz (until there is a better solution)
|
||||
stc_clk_sysclk_cfg_t sysClkConf = {
|
||||
constexpr stc_clk_sysclk_cfg_t sysClkConf = {
|
||||
.enHclkDiv = ClkSysclkDiv1, // HCLK = 200 MHz (CPU)
|
||||
.enExclkDiv = ClkSysclkDiv2, // EXCLK = 100 MHz (SDIO)
|
||||
.enPclk0Div = ClkSysclkDiv1, // PCLK0 = 200 MHz (Timer6 (not used))
|
||||
.enPclk0Div = ClkSysclkDiv2, // PCLK0 = 100 MHz (Timer6 (not used))
|
||||
.enPclk1Div = ClkSysclkDiv4, // PCLK1 = 50 MHz (USART, SPI, I2S, Timer0 (step+temp), TimerA (Servo))
|
||||
.enPclk2Div = ClkSysclkDiv4, // PCLK2 = 50 MHz (ADC)
|
||||
.enPclk3Div = ClkSysclkDiv4, // PCLK3 = 50 MHz (I2C, WDT)
|
||||
.enPclk2Div = ClkSysclkDiv8, // PCLK2 = 25 MHz (ADC)
|
||||
.enPclk3Div = ClkSysclkDiv8, // PCLK3 = 25 MHz (I2C, WDT)
|
||||
.enPclk4Div = ClkSysclkDiv2, // PCLK4 = 100 MHz (ADC ctl)
|
||||
};
|
||||
|
||||
#if ARDUINO_CORE_VERSION_INT >= GET_VERSION_INT(1, 2, 0)
|
||||
assert_system_clocks_valid<
|
||||
sysclock,
|
||||
sysClkConf.enHclkDiv,
|
||||
sysClkConf.enPclk0Div,
|
||||
sysClkConf.enPclk1Div,
|
||||
sysClkConf.enPclk2Div,
|
||||
sysClkConf.enPclk3Div,
|
||||
sysClkConf.enPclk4Div,
|
||||
sysClkConf.enExclkDiv
|
||||
>();
|
||||
#endif
|
||||
|
||||
sysclock_set_clock_dividers(&sysClkConf);
|
||||
|
||||
// Set power mode
|
||||
#define POWER_MODE_SYSTEM_CLOCK 200000000 // 200 MHz
|
||||
power_mode_update_pre(POWER_MODE_SYSTEM_CLOCK);
|
||||
power_mode_update_pre(sysclock);
|
||||
|
||||
// Switch to MPLL as sysclk source
|
||||
CLK_SetSysClkSource(CLKSysSrcMPLL);
|
||||
|
||||
// Set power mode
|
||||
power_mode_update_post(POWER_MODE_SYSTEM_CLOCK);
|
||||
#undef POWER_MODE_SYSTEM_CLOCK
|
||||
power_mode_update_post(sysclock);
|
||||
}
|
||||
|
||||
#endif // ARDUINO_ARCH_HC32
|
||||
|
||||
@@ -38,44 +38,48 @@ extern Timer0 step_timer;
|
||||
// Timer Configurations
|
||||
//
|
||||
|
||||
// TODO: some calculations (step irq min_step_rate) require the timer rate to be known at compile time
|
||||
// this is not possible with the HC32F460, as the timer rate depends on PCLK1
|
||||
// as a workaround, PCLK1 = 50MHz is assumed (check with clock dump in MarlinHAL::init())
|
||||
#define HAL_TIMER_RATE 50000000 // 50MHz
|
||||
// #define HAL_TIMER_RATE TIMER0_BASE_FREQUENCY
|
||||
|
||||
// TODO: CYCLES_PER_MICROSECOND seems to be used by Marlin to calculate the number of cycles per microsecond in the timer ISRs
|
||||
// by default, it uses F_CPU, but since that is not known at compile time for HC32, we overwrite it here
|
||||
#undef CYCLES_PER_MICROSECOND
|
||||
#define CYCLES_PER_MICROSECOND (HAL_TIMER_RATE / 1000000UL)
|
||||
/**
|
||||
* HAL_TIMER_RATE must be known at compile time since it's used to calculate
|
||||
* STEPPER_TIMER_RATE, which is used in 'constexpr' calculations.
|
||||
* On the HC32F460 the timer rate depends on PCLK1, which is derived from the
|
||||
* system clock configured at runtime. As a workaround, we use the existing
|
||||
* assumption of a 200MHz clock, defining F_CPU as 200000000, then configure PCLK1
|
||||
* as F_CPU with a divider of 4 in 'sysclock.cpp::core_hook_sysclock_init'.
|
||||
*
|
||||
* If you face issues with this assumption, please double-check with the values
|
||||
* printed by 'MarlinHAL::HAL_clock_frequencies_dump'.
|
||||
*
|
||||
* TODO: If the 'constexpr' requirement is ever lifted, use TIMER0_BASE_FREQUENCY instead
|
||||
*/
|
||||
#define HAL_TIMER_RATE (F_CPU / 4) // i.e., 50MHz
|
||||
//#define HAL_TIMER_RATE TIMER0_BASE_FREQUENCY
|
||||
|
||||
// Temperature timer
|
||||
#define TEMP_TIMER_NUM (&temp_timer)
|
||||
#define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02
|
||||
#define TEMP_TIMER_PRESCALE 16ul
|
||||
#define TEMP_TIMER_RATE 1000 // 1kHz
|
||||
#define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // Alias for Marlin
|
||||
#define TEMP_TIMER_NUM (&temp_timer)
|
||||
#define TEMP_TIMER_PRIORITY DDL_IRQ_PRIORITY_02
|
||||
#define TEMP_TIMER_PRESCALE 16UL // 12.5MHz
|
||||
#define TEMP_TIMER_RATE 1000 // 1kHz
|
||||
#define TEMP_TIMER_FREQUENCY TEMP_TIMER_RATE // 1kHz also
|
||||
|
||||
// Stepper timer
|
||||
#define STEP_TIMER_NUM (&step_timer)
|
||||
#define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_01
|
||||
#define STEPPER_TIMER_PRESCALE 16ul
|
||||
#define STEP_TIMER_NUM (&step_timer)
|
||||
#define STEP_TIMER_PRIORITY DDL_IRQ_PRIORITY_00 // Top priority, nothing else uses it
|
||||
#define STEPPER_TIMER_PRESCALE 16UL // 12.5MHz
|
||||
|
||||
// TODO: STEPPER_TIMER_RATE seems to work fine like this, but requires further testing...
|
||||
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
|
||||
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000)
|
||||
#define STEPPER_TIMER_RATE (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE) // 50MHz / 16 = 3.125MHz
|
||||
#define STEPPER_TIMER_TICKS_PER_US (STEPPER_TIMER_RATE / 1000000UL) // Integer 3
|
||||
|
||||
// Pulse timer (== stepper timer)
|
||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||
|
||||
//
|
||||
// Channel aliases
|
||||
//
|
||||
#define MF_TIMER_TEMP TEMP_TIMER_NUM
|
||||
#define MF_TIMER_STEP STEP_TIMER_NUM
|
||||
#define MF_TIMER_PULSE PULSE_TIMER_NUM
|
||||
#define MF_TIMER_TEMP TEMP_TIMER_NUM
|
||||
#define MF_TIMER_STEP STEP_TIMER_NUM
|
||||
#define MF_TIMER_PULSE PULSE_TIMER_NUM
|
||||
|
||||
//
|
||||
// HAL functions
|
||||
|
||||
@@ -37,7 +37,10 @@ Timer::Timer() {
|
||||
}
|
||||
|
||||
Timer::~Timer() {
|
||||
timer_delete(timerid);
|
||||
if (timerid != 0) {
|
||||
timer_delete(timerid);
|
||||
timerid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Timer::init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn) {
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#ifdef __PLAT_LINUX__
|
||||
#ifndef UNIT_TEST
|
||||
|
||||
//#define GPIO_LOGGING // Full GPIO and Positional Logging
|
||||
|
||||
@@ -135,4 +136,5 @@ int main() {
|
||||
read_serial.join();
|
||||
}
|
||||
|
||||
#endif // UNIT_TEST
|
||||
#endif // __PLAT_LINUX__
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../shared/Delay.h"
|
||||
#include "../../../gcode/parser.h"
|
||||
|
||||
DefaultSerial1 USBSerial(false, MCDCSerial0);
|
||||
|
||||
uint32_t MarlinHAL::adc_result = 0;
|
||||
|
||||
// U8glib required functions
|
||||
extern "C" {
|
||||
void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); }
|
||||
void u8g_MicroDelay() { u8g_xMicroDelay(1); }
|
||||
void u8g_10MicroDelay() { u8g_xMicroDelay(10); }
|
||||
void u8g_Delay(uint16_t val) { delay(val); }
|
||||
}
|
||||
|
||||
// return free heap space
|
||||
int freeMemory() {
|
||||
char stack_end;
|
||||
void *heap_start = malloc(sizeof(uint32_t));
|
||||
if (heap_start == 0) return 0;
|
||||
|
||||
uint32_t result = (uint32_t)&stack_end - (uint32_t)heap_start;
|
||||
free(heap_start);
|
||||
return result;
|
||||
}
|
||||
|
||||
void MarlinHAL::reboot() { MCUCore::nvic_system_reset(); }
|
||||
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void MarlinHAL::clear_reset_source() { watchdog_clear_timeout_flag(); }
|
||||
|
||||
void flashFirmware(const int16_t) {
|
||||
delay(500); // Give OS time to disconnect
|
||||
//USB_Connect(false); // USB clear connection
|
||||
delay(1000); // Give OS time to notice
|
||||
hal.reboot();
|
||||
}
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#define WDT_TIMEOUT TERN(WATCHDOG_DURATION_8S, 8.0f, 4.0f) // 4 or 8 second timeout
|
||||
|
||||
void MarlinHAL::watchdog_init() {
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// We enable the watchdog timer, but only for the interrupt.
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
// Disable WDT interrupt (just in case, to avoid triggering it!)
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
|
||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// WDT defaults to trigger an interrupt
|
||||
|
||||
// Configure and enable WDT interrupt.
|
||||
NVIC_ClearPendingIRQ(WDT_IRQn);
|
||||
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
#else
|
||||
MCUI::watchdog_set_timeout_triggers_reset();
|
||||
#endif
|
||||
MCUI::watchdog_set_timeout_in_seconds(WDT_TIMEOUT);
|
||||
MCUI::watchdog_enable();
|
||||
}
|
||||
|
||||
void MarlinHAL::watchdog_refresh() {
|
||||
MCUI::watchdog_feed();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
static millis_t next_flash = millis();
|
||||
if (ELAPSED(millis(), next_flash)) {
|
||||
next_flash = millis() + 200;
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Timeout state
|
||||
bool MarlinHAL::watchdog_timed_out() { return MCUI::watchdog_has_triggered(); }
|
||||
void MarlinHAL::watchdog_clear_timeout_flag() { MCUI::watchdog_clear_timeout_flag(); }
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
// For M42/M43, scan command line for pin code
|
||||
// return index into pin map array if found and the pin is valid.
|
||||
// return dval if not found or not a valid pin.
|
||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
const uint16_t val = (uint16_t)parser.intval(code, -1), port = val / 100, pin = val % 100;
|
||||
const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2;
|
||||
return ind > -1 ? ind : dval;
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* HAL_LPC1768/HAL.h
|
||||
* Hardware Abstraction Layer for NXP LPC1768
|
||||
*/
|
||||
|
||||
#define CPU_32_BIT
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../shared/Marduino.h"
|
||||
#include "../shared/Delay.h"
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "MarlinSerial.h"
|
||||
|
||||
#include <mcu_interface.h>
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
typedef ForwardSerial1Class< decltype(MCDCSerial0) > DefaultSerial1;
|
||||
extern DefaultSerial1 USBSerial;
|
||||
|
||||
#define _MSERIAL(X) MSerial##X
|
||||
#define MSERIAL(X) _MSERIAL(X)
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
#define MYSERIAL1 USBSerial
|
||||
#elif WITHIN(SERIAL_PORT, 0, 3)
|
||||
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
|
||||
#else
|
||||
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
#if SERIAL_PORT_2 == -1
|
||||
#define MYSERIAL2 USBSerial
|
||||
#elif WITHIN(SERIAL_PORT_2, 0, 3)
|
||||
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
|
||||
#else
|
||||
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_3
|
||||
#if SERIAL_PORT_3 == -1
|
||||
#define MYSERIAL3 USBSerial
|
||||
#elif WITHIN(SERIAL_PORT_3, 0, 3)
|
||||
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
|
||||
#else
|
||||
#error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MMU2_SERIAL_PORT
|
||||
#if MMU2_SERIAL_PORT == -1
|
||||
#define MMU2_SERIAL USBSerial
|
||||
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
|
||||
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
|
||||
#else
|
||||
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LCD_SERIAL_PORT
|
||||
#if LCD_SERIAL_PORT == -1
|
||||
#define LCD_SERIAL USBSerial
|
||||
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
|
||||
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
|
||||
#else
|
||||
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#if HAS_DGUS_LCD
|
||||
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.available()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
|
||||
#define CRITICAL_SECTION_START() const bool irqon = !MCUCore::primask(); MCUCore::nvic_interrupts_disable()
|
||||
#define CRITICAL_SECTION_END() if (irqon) MCUCore::nvic_interrupts_enable()
|
||||
#define cli() noInterrupts()
|
||||
#define sei() interrupts()
|
||||
//
|
||||
// ADC
|
||||
//
|
||||
|
||||
#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
|
||||
// (ADC_MEDIAN_FILTER_SIZE + 1) / 2 sample step delay (12 samples @ 500Hz: 24ms phase shift)
|
||||
// Memory usage per ADC channel (bytes): (6 * ADC_MEDIAN_FILTER_SIZE) + 16
|
||||
// 8 * ((6 * 23) + 16 ) = 1232 Bytes for 8 channels
|
||||
|
||||
#define ADC_LOWPASS_K_VALUE (2) // Higher values increase rise time
|
||||
// Rise time sample delays for 100% signal convergence on full range step
|
||||
// (1 : 13, 2 : 32, 3 : 67, 4 : 139, 5 : 281, 6 : 565, 7 : 1135, 8 : 2273)
|
||||
// K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step
|
||||
// Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels)
|
||||
|
||||
#define HAL_ADC_VREF 3.3 // ADC voltage reference
|
||||
|
||||
#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t
|
||||
#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
|
||||
|
||||
//
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
|
||||
// Test whether the pin is valid
|
||||
constexpr bool VALID_PIN(const pin_t pin) {
|
||||
return MCUI::pin_is_valid(pin);
|
||||
}
|
||||
|
||||
// Get the analog index for a digital pin
|
||||
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) {
|
||||
return (MCUI::pin_is_valid(pin) && MCUI::pin_has_adc(pin)) ? pin : -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Misc. Functions
|
||||
//
|
||||
#ifndef analogInputToDigitalPin
|
||||
#define analogInputToDigitalPin(p) (p)
|
||||
#endif
|
||||
|
||||
|
||||
// Return the index of a pin number
|
||||
constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
|
||||
return MCUI::pin_index(pin);
|
||||
}
|
||||
|
||||
// Get the pin number at the given index
|
||||
constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
|
||||
return MCUI::pin_index(index);
|
||||
}
|
||||
|
||||
// Parse a G-code word into a pin index
|
||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
|
||||
// P0.6 thru P0.9 are for the onboard SD card
|
||||
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09,
|
||||
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
void flashFirmware(const int16_t);
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
|
||||
// Default graphical display delays
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return MCUCore::primask(); }
|
||||
static void isr_on() { MCUCore::nvic_interrupts_enable(); }
|
||||
static void isr_off() { MCUCore::nvic_interrupts_disable(); }
|
||||
|
||||
static void delay_ms(const int ms) { DELAY_US(ms * 1000); }
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; });
|
||||
static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source();
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
using FilteredADC = MCUI::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {
|
||||
// Turn on and initialise ADC in burst mode
|
||||
MCUI::adc_hardware.init();
|
||||
MCUI::adc_hardware.burst_start();
|
||||
}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const pin_t pin) {
|
||||
FilteredADC::enable_channel(pin);
|
||||
}
|
||||
|
||||
// Begin ADC sampling on the given pin. Called from Temperature::isr!
|
||||
static uint32_t adc_result;
|
||||
static void adc_start(const pin_t pin) {
|
||||
adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
|
||||
}
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return uint16_t(adc_result); }
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* Optionally invert the duty cycle [default = false]
|
||||
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
/**
|
||||
* Set the frequency of the timer corresponding to the provided pin
|
||||
* All Hardware PWM pins will run at the same frequency and
|
||||
* All Software PWM pins will run at the same frequency
|
||||
*/
|
||||
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
|
||||
};
|
||||
@@ -0,0 +1,376 @@
|
||||
// /**
|
||||
// * Marlin 3D Printer Firmware
|
||||
// * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
// *
|
||||
// * Based on Sprinter and grbl.
|
||||
// * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have received a copy of the GNU General Public License
|
||||
// * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// *
|
||||
// */
|
||||
|
||||
// /**
|
||||
// * Software SPI functions originally from Arduino Sd2Card Library
|
||||
// * Copyright (c) 2009 by William Greiman
|
||||
// */
|
||||
|
||||
// /**
|
||||
// * For TARGET_LPC4078
|
||||
// */
|
||||
|
||||
// /**
|
||||
// * Hardware SPI and Software SPI implementations are included in this file.
|
||||
// * The hardware SPI runs faster and has higher throughput but is not compatible
|
||||
// * with some LCD interfaces/adapters.
|
||||
// *
|
||||
// * Control of the slave select pin(s) is handled by the calling routines.
|
||||
// *
|
||||
// * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card
|
||||
// * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with
|
||||
// * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is
|
||||
// * active. If any of these pins are shared then the software SPI must be used.
|
||||
// *
|
||||
// * A more sophisticated hardware SPI can be found at the following link.
|
||||
// * This implementation has not been fully debugged.
|
||||
// * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
|
||||
// */
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include <SPI.h>
|
||||
|
||||
// Hardware SPI and SPIClass
|
||||
|
||||
#include "../shared/HAL_SPI.h"
|
||||
|
||||
#define LPC_SOFTWARE_SPI
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
#if ENABLED(LPC_SOFTWARE_SPI)
|
||||
#include "SoftwareSPI.h"
|
||||
|
||||
// Software SPI
|
||||
static uint8_t SPI_speed = SPI_FULL_SPEED;
|
||||
|
||||
static uint8_t spiTransfer(uint8_t b) {
|
||||
return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
|
||||
}
|
||||
|
||||
void spiBegin() {
|
||||
swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
|
||||
}
|
||||
|
||||
void spiInit(uint8_t spiRate) {
|
||||
SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN);
|
||||
}
|
||||
|
||||
uint8_t spiRec() { return spiTransfer(0xFF); }
|
||||
|
||||
void spiRead(uint8_t*buf, uint16_t nbyte) {
|
||||
for (int i = 0; i < nbyte; i++)
|
||||
buf[i] = spiTransfer(0xFF);
|
||||
}
|
||||
|
||||
void spiSend(uint8_t b) { (void)spiTransfer(b); }
|
||||
|
||||
void spiSend(const uint8_t *buf, size_t nbyte) {
|
||||
for (uint16_t i = 0; i < nbyte; i++)
|
||||
(void)spiTransfer(buf[i]);
|
||||
}
|
||||
|
||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
||||
(void)spiTransfer(token);
|
||||
for (uint16_t i = 0; i < 512; i++)
|
||||
(void)spiTransfer(buf[i]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef SD_SPI_SPEED
|
||||
#define INIT_SPI_SPEED SD_SPI_SPEED
|
||||
#else
|
||||
#define INIT_SPI_SPEED SPI_FULL_SPEED
|
||||
#endif
|
||||
|
||||
void spiBegin() { spiInit(INIT_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0
|
||||
|
||||
void spiInit(uint8_t spiRate) {
|
||||
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
|
||||
SPI.setModule(1);
|
||||
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
|
||||
SPI.setModule(2);
|
||||
#endif
|
||||
SPI.setDataSize(DATA_SIZE_8BIT);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
|
||||
SPI.setClock(SPISettings::spiRate2Clock(spiRate));
|
||||
SPI.begin();
|
||||
}
|
||||
|
||||
static uint8_t doio(uint8_t b) {
|
||||
return SPI.transfer(b & 0x00FF) & 0x00FF;
|
||||
}
|
||||
|
||||
void spiSend(uint8_t b) { doio(b); }
|
||||
|
||||
void spiSend(const uint8_t *buf, size_t nbyte) {
|
||||
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
|
||||
}
|
||||
|
||||
void spiSend(uint32_t chan, byte b) {}
|
||||
|
||||
void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {}
|
||||
|
||||
// Read single byte from SPI
|
||||
uint8_t spiRec() { return doio(0xFF); }
|
||||
|
||||
uint8_t spiRec(uint32_t chan) { return 0; }
|
||||
|
||||
// Read from SPI into buffer
|
||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
||||
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
|
||||
}
|
||||
|
||||
uint8_t spiTransfer(uint8_t b) { return doio(b); }
|
||||
|
||||
// Write from buffer to SPI
|
||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
||||
(void)spiTransfer(token);
|
||||
for (uint16_t i = 0; i < 512; i++)
|
||||
(void)spiTransfer(buf[i]);
|
||||
}
|
||||
|
||||
// Begin SPI transaction, set clock, bit order, data mode
|
||||
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
#endif // LPC_SOFTWARE_SPI
|
||||
|
||||
// /**
|
||||
// * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
|
||||
// */
|
||||
static inline void waitSpiTxEnd(void *spi_d) {
|
||||
// while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1
|
||||
// while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0
|
||||
}
|
||||
|
||||
// // Retain the pin init state of the SPI, to avoid init more than once,
|
||||
// // even if more instances of SPIClass exist
|
||||
static bool spiInitialised[BOARD_NR_SPI] = {};
|
||||
|
||||
SPIClass::SPIClass(uint8_t device) {
|
||||
// // Init things specific to each SPI device
|
||||
// // clock divider setup is a bit of hack, and needs to be improved at a later date.
|
||||
|
||||
#if BOARD_NR_SPI >= 1
|
||||
_settings[0].device_id = 0;
|
||||
_settings[0].m_config.pin_miso = BOARD_SPI1_MISO_PIN;
|
||||
_settings[0].m_config.pin_mosi = BOARD_SPI1_MOSI_PIN;
|
||||
_settings[0].m_config.pin_sck = BOARD_SPI1_SCK_PIN;
|
||||
_settings[0].m_config.pin_ssel = BOARD_SPI1_NSS_PIN;
|
||||
_settings[0].m_config.frequency = 100000;
|
||||
_settings[0].m_config.data_bits = 8;
|
||||
_settings[0].m_config.mode = 0;
|
||||
_settings[0].m_config.format = MCUI::SSP::Config::Format::SPI;
|
||||
|
||||
|
||||
// _settings[0].dataMode = SPI_MODE0;
|
||||
// _settings[0].dataSize = DATA_SIZE_8BIT;
|
||||
// _settings[0].clock = SPI_CLOCK_MAX;
|
||||
// //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
|
||||
#endif
|
||||
|
||||
#if BOARD_NR_SPI >= 2
|
||||
_settings[1].device_id = 2;
|
||||
_settings[1].m_config.pin_miso = BOARD_SPI2_MISO_PIN;
|
||||
_settings[1].m_config.pin_mosi = BOARD_SPI2_MOSI_PIN;
|
||||
_settings[1].m_config.pin_sck = BOARD_SPI2_SCK_PIN;
|
||||
_settings[1].m_config.pin_ssel = BOARD_SPI2_NSS_PIN;
|
||||
// _settings[1].dataMode = SPI_MODE0;
|
||||
// _settings[1].dataSize = DATA_SIZE_8BIT;
|
||||
// _settings[1].clock = SPI_CLOCK_MAX;
|
||||
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
|
||||
#endif
|
||||
|
||||
#if BOARD_NR_SPI >= 3
|
||||
_settings[2].device_id = 1;
|
||||
_settings[2].m_config.pin_miso = BOARD_SPI3_MISO_PIN;
|
||||
_settings[2].m_config.pin_mosi = BOARD_SPI3_MOSI_PIN;
|
||||
_settings[2].m_config.pin_sck = BOARD_SPI3_SCK_PIN;
|
||||
_settings[2].m_config.pin_ssel = BOARD_SPI3_NSS_PIN;
|
||||
// _settings[1].dataMode = SPI_MODE0;
|
||||
// _settings[1].dataSize = DATA_SIZE_8BIT;
|
||||
// _settings[1].clock = SPI_CLOCK_MAX;
|
||||
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
|
||||
#endif
|
||||
|
||||
setModule(device);
|
||||
|
||||
// // Init the GPDMA controller
|
||||
// // TODO: call once in the constructor? or each time?
|
||||
// GPDMA_Init();
|
||||
}
|
||||
|
||||
SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) {
|
||||
#if BOARD_NR_SPI >= 1
|
||||
if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 2
|
||||
if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 3
|
||||
if (mosi == BOARD_SPI3_MOSI_PIN) SPIClass(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SPIClass::begin() {
|
||||
// // Init the SPI pins in the first begin call
|
||||
if ((_currentSetting->device_id == 0 && spiInitialised[0] == false) ||
|
||||
(_currentSetting->device_id == 1 && spiInitialised[1] == false) ||
|
||||
(_currentSetting->device_id == 2 && spiInitialised[2] == false)) {
|
||||
MCUI::SSP::init(_currentSetting->device_id, _currentSetting->m_config);
|
||||
spiInitialised[_currentSetting->device_id] = true;
|
||||
}
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void SPIClass::beginTransaction(const SPISettings &cfg) {
|
||||
setBitOrder(cfg.bitOrder);
|
||||
setDataMode(cfg.dataMode);
|
||||
setDataSize(cfg.dataSize);
|
||||
//setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
|
||||
begin();
|
||||
}
|
||||
|
||||
uint8_t SPIClass::transfer(const uint16_t b) {
|
||||
uint16_t rx_word = 0;
|
||||
// clear rx fifo
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) == 1);
|
||||
MCUI::SSP::write(_currentSetting->device_id, b);
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) != 1);
|
||||
return rx_word;
|
||||
}
|
||||
|
||||
uint16_t SPIClass::transfer16(const uint16_t data) {
|
||||
return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF);
|
||||
}
|
||||
|
||||
void SPIClass::end() {
|
||||
// // Neither is needed for Marlin
|
||||
// //SSP_Cmd(_currentSetting->spi_d, DISABLE);
|
||||
// //SSP_DeInit(_currentSetting->spi_d);
|
||||
}
|
||||
|
||||
void SPIClass::send(uint8_t data) {
|
||||
MCUI::SSP::write(_currentSetting->device_id, data);
|
||||
}
|
||||
|
||||
void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
|
||||
// //TODO: LPC dma can only write 0xFFF bytes at once.
|
||||
// GPDMA_Channel_CFG_Type GPDMACfg;
|
||||
|
||||
// /* Configure GPDMA channel 0 -------------------------------------------------------------*/
|
||||
// /* DMA Channel 0 */
|
||||
// GPDMACfg.ChannelNum = 0;
|
||||
// // Source memory
|
||||
// GPDMACfg.SrcMemAddr = (uint32_t)buf;
|
||||
// // Destination memory - Not used
|
||||
// GPDMACfg.DstMemAddr = 0;
|
||||
// // Transfer size
|
||||
// GPDMACfg.TransferSize = length;
|
||||
// // Transfer width
|
||||
// GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
|
||||
// // Transfer type
|
||||
// GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
|
||||
// // Source connection - unused
|
||||
// GPDMACfg.SrcConn = 0;
|
||||
// // Destination connection
|
||||
// GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx;
|
||||
|
||||
// GPDMACfg.DMALLI = 0;
|
||||
|
||||
// // Enable dma on SPI
|
||||
// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
|
||||
|
||||
// // Only increase memory if minc is true
|
||||
// GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
|
||||
|
||||
// // Setup channel with given parameter
|
||||
// GPDMA_Setup(&GPDMACfg);
|
||||
|
||||
// // Enable DMA
|
||||
// GPDMA_ChannelCmd(0, ENABLE);
|
||||
|
||||
// // Wait for data transfer
|
||||
// while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { }
|
||||
|
||||
// // Clear err and int
|
||||
// GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
|
||||
// GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
|
||||
|
||||
// // Disable DMA
|
||||
// GPDMA_ChannelCmd(0, DISABLE);
|
||||
|
||||
// waitSpiTxEnd(_currentSetting->spi_d);
|
||||
|
||||
// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE);
|
||||
}
|
||||
|
||||
uint16_t SPIClass::read() {
|
||||
uint16_t rx_word = 0;
|
||||
MCUI::SSP::read(_currentSetting->device_id, &rx_word);
|
||||
return rx_word;
|
||||
}
|
||||
|
||||
void SPIClass::read(uint8_t *buf, uint32_t len) {
|
||||
uint16_t rx_word = 0;
|
||||
// clear rx fifo
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) == 1);
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
MCUI::SSP::write(_currentSetting->device_id, 0xFF);
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) != 1);
|
||||
buf[i] = rx_word;
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; }
|
||||
|
||||
void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed
|
||||
|
||||
void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
|
||||
|
||||
void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
|
||||
|
||||
void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
|
||||
|
||||
// /**
|
||||
// * Set up/tear down
|
||||
// */
|
||||
void SPIClass::updateSettings() {
|
||||
MCUI::SSP::configure(_currentSetting->device_id, _currentSetting->m_config);
|
||||
}
|
||||
|
||||
SPIClass SPI(1);
|
||||
|
||||
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
|
||||
SPIClass SPI(1);
|
||||
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
|
||||
SPIClass SPI(2);
|
||||
#endif
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
/**
|
||||
* Marlin currently requires 3 SPI classes:
|
||||
*
|
||||
* SPIClass:
|
||||
* This class is normally provided by frameworks and has a semi-default interface.
|
||||
* This is needed because some libraries reference it globally.
|
||||
*
|
||||
* SPISettings:
|
||||
* Container for SPI configs for SPIClass. As above, libraries may reference it globally.
|
||||
*
|
||||
* These two classes are often provided by frameworks so we cannot extend them to add
|
||||
* useful methods for Marlin.
|
||||
*
|
||||
* MarlinSPI:
|
||||
* Provides the default SPIClass interface plus some Marlin goodies such as a simplified
|
||||
* interface for SPI DMA transfer.
|
||||
*
|
||||
*/
|
||||
|
||||
using MarlinSPI = SPIClass;
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "MarlinSerial.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
MarlinCDCSerial MCDCSerial0;
|
||||
|
||||
#define MarlinSerial(ID) \
|
||||
MarlinSerial _MSerial##ID(ID); \
|
||||
MSerialT MSerial##ID(true, _MSerial##ID)
|
||||
|
||||
#if USING_HW_SERIAL0
|
||||
MarlinSerial(0);
|
||||
#endif
|
||||
#if USING_HW_SERIAL1
|
||||
MarlinSerial(1);
|
||||
#endif
|
||||
#if USING_HW_SERIAL2
|
||||
MarlinSerial(2);
|
||||
#endif
|
||||
#if USING_HW_SERIAL3
|
||||
MarlinSerial(3);
|
||||
#endif
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
|
||||
bool MarlinSerial::recv_callback(const char c) {
|
||||
// Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro)
|
||||
if (false) {}
|
||||
#if USING_HW_SERIAL0
|
||||
else if (this == &_MSerial0) emergency_parser.update(MSerial0.emergency_state, c);
|
||||
#endif
|
||||
#if USING_HW_SERIAL1
|
||||
else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c);
|
||||
#endif
|
||||
#if USING_HW_SERIAL2
|
||||
else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c);
|
||||
#endif
|
||||
#if USING_HW_SERIAL3
|
||||
else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "../../feature/e_parser.h"
|
||||
|
||||
EmergencyParser::State emergency_state;
|
||||
|
||||
bool CDC_RecvCallback(const char c) {
|
||||
emergency_parser.update(emergency_state, c);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <mcu_interface.h>
|
||||
#include <interface/uart.h>
|
||||
#include <driver/usb_cdc.h>
|
||||
|
||||
#include <UART.h>
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
#include "../../feature/e_parser.h"
|
||||
#endif
|
||||
#include "../../core/serial_hook.h"
|
||||
|
||||
#ifndef SERIAL_PORT
|
||||
#define SERIAL_PORT 0
|
||||
#endif
|
||||
#ifndef RX_BUFFER_SIZE
|
||||
#define RX_BUFFER_SIZE 128
|
||||
#endif
|
||||
#ifndef TX_BUFFER_SIZE
|
||||
#define TX_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
class MarlinCDCSerial : public HardwareSerial {
|
||||
public:
|
||||
MarlinCDCSerial() {}
|
||||
void begin(unsigned long baudrate) override {}
|
||||
void begin(unsigned long baudrate, uint16_t config) override { }
|
||||
void end() override { }
|
||||
int available() override {
|
||||
return MCUI::CDCSerial0::available();
|
||||
}
|
||||
int peek() override { char c = 0; return MCUI::CDCSerial0::peek((uint8_t*)&c)? c : -1; }
|
||||
int read() override { char c = 0; return MCUI::CDCSerial0::read((uint8_t*)&c, 1)? c : -1; }
|
||||
void flush() override {};
|
||||
size_t write(uint8_t c) override { return write(&c, 1); }
|
||||
size_t write(const uint8_t *buffer, size_t size) override { return MCUI::CDCSerial0::connected() ? MCUI::CDCSerial0::write(buffer, size) : 0; }
|
||||
using Print::write;
|
||||
operator bool() override { return true; }
|
||||
};
|
||||
extern MarlinCDCSerial MCDCSerial0;
|
||||
|
||||
class MarlinSerial : public HardwareSerial {
|
||||
public:
|
||||
MarlinSerial(const uint32_t uart_id) : uart_device(uart_id) {}
|
||||
void begin(unsigned long baudrate) override {
|
||||
uart_device.configure_pins(P0_02, P0_03);
|
||||
uart_device.init({ .baud = baudrate });
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
uart_device.set_rx_callback([this](char rx_value){ return this->recv_callback(rx_value); } );
|
||||
#endif
|
||||
}
|
||||
void begin(unsigned long baudrate, uint16_t config) override {
|
||||
begin(baudrate);
|
||||
}
|
||||
void end() override { }
|
||||
int available() override {
|
||||
return uart_device.rx_available();
|
||||
}
|
||||
int peek() override { char c = 0; return uart_device.peek(&c)? c : -1; }
|
||||
int read() override { char c = 0; return uart_device.read(&c)? c : -1; }
|
||||
void flush() override {};
|
||||
size_t write(uint8_t c) override { return write(&c, 1); }
|
||||
size_t write(const uint8_t *buffer, size_t size) override { return uart_device.write((const char *)buffer, size); }
|
||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
operator bool() override { return true; }
|
||||
|
||||
bool recv_callback(char value);
|
||||
private:
|
||||
MCUI::BufferedUARTC uart_device;
|
||||
};
|
||||
|
||||
// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads
|
||||
// of 'available' and 'read' method are not used in this multiple inheritance scenario.
|
||||
// Instead, use a ForwardSerial here that adapts the interface.
|
||||
typedef ForwardSerial1Class<MarlinSerial> MSerialT;
|
||||
extern MSerialT MSerial0;
|
||||
extern MSerialT MSerial1;
|
||||
extern MSerialT MSerial2;
|
||||
extern MSerialT MSerial3;
|
||||
|
||||
// Consequently, we can't use a RuntimeSerial either. The workaround would be to use
|
||||
// a RuntimeSerial<ForwardSerial<MarlinSerial>> type here. Ignore for now until it's actually required.
|
||||
#if ENABLED(SERIAL_RUNTIME_HOOK)
|
||||
#error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x."
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "HAL.h"
|
||||
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
|
||||
#include "../shared/MinSerial.h"
|
||||
#include <debug_frmwrk.h>
|
||||
|
||||
static void TX(char c) { _DBC(c); }
|
||||
void install_min_serial() { HAL_min_serial_out = &TX; }
|
||||
|
||||
#if DISABLED(DYNAMIC_VECTORTABLE)
|
||||
extern "C" {
|
||||
__attribute__((naked)) void JumpHandler_ASM() {
|
||||
__asm__ __volatile__ (
|
||||
"b CommonHandler_ASM\n"
|
||||
);
|
||||
}
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // POSTMORTEM_DEBUGGING
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
|
||||
* Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers -
|
||||
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
*
|
||||
* The only modification was to update/delete macros to match the LPC176x.
|
||||
*/
|
||||
|
||||
#include <Servo.h>
|
||||
|
||||
class libServo: public Servo {
|
||||
public:
|
||||
void move(const int value) {
|
||||
constexpr uint16_t servo_delay[] = SERVO_DELAY;
|
||||
static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
|
||||
|
||||
if (attach(servo_info[servoIndex].Pin.nbr) >= 0) { // try to reattach
|
||||
write(value);
|
||||
safe_delay(servo_delay[servoIndex]); // delay to allow servo to reach position
|
||||
TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach());
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class libServo;
|
||||
typedef libServo hal_servo_t;
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "SoftwareSPI.h"
|
||||
|
||||
#include <mcu_interface.h>
|
||||
|
||||
uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (spi_speed == 0) {
|
||||
MCUI::gpio_set(mosi_pin, !!(b & 0x80));
|
||||
MCUI::gpio_set(sck_pin, HIGH);
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1;
|
||||
MCUI::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
else {
|
||||
const uint8_t state = (b & 0x80) ? HIGH : LOW;
|
||||
for (uint8_t j = 0; j < spi_speed; j++)
|
||||
MCUI::gpio_set(mosi_pin, state);
|
||||
|
||||
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
|
||||
MCUI::gpio_set(sck_pin, HIGH);
|
||||
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1;
|
||||
|
||||
for (uint8_t j = 0; j < spi_speed; j++)
|
||||
MCUI::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
|
||||
pinMode(sck_pin, OUTPUT);
|
||||
if (MCUI::pin_is_valid(miso_pin)) pinMode(miso_pin, INPUT);
|
||||
pinMode(mosi_pin, OUTPUT);
|
||||
}
|
||||
|
||||
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) {
|
||||
MCUI::gpio_set(mosi_pin, HIGH);
|
||||
MCUI::gpio_set(sck_pin, LOW);
|
||||
return (SystemCoreClock == 120000000 ? 44 : 38) / std::pow(2, 6 - std::min(spiRate, (uint8_t)6));
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,5 @@
|
||||
#include <mcu_interface.h>
|
||||
|
||||
uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin);
|
||||
void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin);
|
||||
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin);
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
/**
|
||||
* Emulate EEPROM storage using Flash Memory
|
||||
*
|
||||
* Use a single 32K flash sector to store EEPROM data. To reduce the
|
||||
* number of erase operations a simple "leveling" scheme is used that
|
||||
* maintains a number of EEPROM "slots" within the larger flash sector.
|
||||
* Each slot is used in turn and the entire sector is only erased when all
|
||||
* slots have been used.
|
||||
*
|
||||
* A simple RAM image is used to hold the EEPROM data during I/O operations
|
||||
* and this is flushed to the next available slot when an update is complete.
|
||||
* If RAM usage becomes an issue we could store this image in one of the two
|
||||
* 16Kb I/O buffers (intended to hold DMA USB and Ethernet data, but currently
|
||||
* unused).
|
||||
*/
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
//#include <cstdio>
|
||||
|
||||
#ifndef MARLIN_EEPROM_SIZE
|
||||
#define MARLIN_EEPROM_SIZE 4032 // 4KB
|
||||
#endif
|
||||
|
||||
size_t PersistentStore::capacity() { return 4032; }
|
||||
|
||||
constexpr uint32_t page_size = MCUI::EEPROM::page_size;
|
||||
uint32_t buffered_page = 0;
|
||||
uint8_t page_buffer[page_size];
|
||||
bool buffered_page_dirty = false;
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
MCUI::EEPROM::init();
|
||||
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::access_finish() {
|
||||
if (buffered_page_dirty) {
|
||||
MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||
uint32_t address = pos;
|
||||
//printf("Marlin::eeprom::write(pos = %d, size = %d)\n", pos, size);
|
||||
uint32_t value_index = 0;
|
||||
for (uint32_t addr = address; addr < address + size; ++addr) {
|
||||
uint32_t page_address = addr & 0xFFFFFFC0;
|
||||
if (page_address != buffered_page) {
|
||||
//printf("Marlin::eeprom::write(@%ld):: page change new(%ld) != current(%d)\n",addr, page_address, buffered_page);
|
||||
if (buffered_page_dirty == true) MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
|
||||
buffered_page = page_address;
|
||||
buffered_page_dirty = false;
|
||||
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
|
||||
}
|
||||
page_buffer[addr & ~0xFFFFFFC0] = value[value_index++];
|
||||
buffered_page_dirty = true;
|
||||
}
|
||||
|
||||
pos += size;
|
||||
crc16(crc, value, size);
|
||||
|
||||
return false; // return true for any error
|
||||
}
|
||||
|
||||
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||
uint32_t address = pos;
|
||||
//printf("Marlin::eeprom::read(pos = %d, size = %d, writing = %d)\n", pos, size, writing);
|
||||
uint32_t value_index = 0;
|
||||
for (uint32_t addr = address; addr < address + size; ++addr) {
|
||||
uint32_t page_address = addr & 0xFFFFFFC0;
|
||||
if (page_address != buffered_page) {
|
||||
if (buffered_page_dirty) {
|
||||
MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
|
||||
buffered_page_dirty = false;
|
||||
}
|
||||
buffered_page = page_address;
|
||||
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
|
||||
}
|
||||
if (writing) value[value_index++] = page_buffer[addr & ~0xFFFFFFC0];
|
||||
else crc16(crc, &page_buffer[addr & ~0xFFFFFFC0], 1);
|
||||
}
|
||||
|
||||
if (writing) crc16(crc, value, size);
|
||||
pos += size;
|
||||
|
||||
return false; // return true for any error
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Endstop Interrupts
|
||||
*
|
||||
* Without endstop interrupts the endstop pins must be polled continually in
|
||||
* the temperature-ISR via endstops.update(), most of the time finding no change.
|
||||
* With this feature endstops.update() is called only when we know that at
|
||||
* least one endstop has changed state, saving valuable CPU cycles.
|
||||
*
|
||||
* This feature only works when all used endstop pins can generate an 'external interrupt'.
|
||||
*
|
||||
* Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'.
|
||||
* (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino)
|
||||
*/
|
||||
|
||||
#include "../../module/endstops.h"
|
||||
|
||||
// One ISR for all EXT-Interrupts
|
||||
void endstop_ISR() { endstops.update(); }
|
||||
|
||||
void setup_endstop_interrupts() {
|
||||
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
|
||||
#define LPC1768_PIN_INTERRUPT_M(pin) ((pin >> 0x5 & 0x7) == 0 || (pin >> 0x5 & 0x7) == 2)
|
||||
|
||||
#if HAS_X_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
|
||||
#error "X_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(X_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_X_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN)
|
||||
#error "X_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(X_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Y_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN)
|
||||
#error "Y_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Y_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Y_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN)
|
||||
#error "Y_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Y_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN)
|
||||
#error "Z_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN)
|
||||
#error "Z_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z2_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN)
|
||||
#error "Z2_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z2_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z2_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN)
|
||||
#error "Z2_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z2_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z3_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z3_MAX_PIN)
|
||||
#error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z3_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z3_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z3_MIN_PIN)
|
||||
#error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z3_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z4_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z4_MAX_PIN)
|
||||
#error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z4_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z4_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z4_MIN_PIN)
|
||||
#error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z4_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z_MIN_PROBE_PIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN)
|
||||
#error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z_MIN_PROBE_PIN);
|
||||
#endif
|
||||
#if HAS_I_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN)
|
||||
#error "I_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(I_MAX_PIN);
|
||||
#elif HAS_I_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(I_MIN_PIN)
|
||||
#error "I_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(I_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_J_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(J_MAX_PIN)
|
||||
#error "J_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(J_MAX_PIN);
|
||||
#elif HAS_J_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(J_MIN_PIN)
|
||||
#error "J_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(J_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_K_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(K_MAX_PIN)
|
||||
#error "K_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(K_MAX_PIN);
|
||||
#elif HAS_K_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(K_MIN_PIN)
|
||||
#error "K_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(K_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(U_MAX_PIN)
|
||||
#error "U_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(U_MAX_PIN);
|
||||
#elif HAS_U_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(U_MIN_PIN)
|
||||
#error "U_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(U_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(V_MAX_PIN)
|
||||
#error "V_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(V_MAX_PIN);
|
||||
#elif HAS_V_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(V_MIN_PIN)
|
||||
#error "V_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(V_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(W_MAX_PIN)
|
||||
#error "W_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(W_MAX_PIN);
|
||||
#elif HAS_W_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(W_MIN_PIN)
|
||||
#error "W_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(W_MIN_PIN);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include <mcu_interface.h>
|
||||
|
||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
|
||||
if (!MCUI::pin_is_valid(pin)) return;
|
||||
if (MCUI::pwm_attach_pin(pin))
|
||||
MCUI::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range
|
||||
}
|
||||
|
||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
|
||||
MCUI::pwm_set_frequency(pin, f_desired);
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Fast I/O Routines for LPC1768/9
|
||||
* Use direct port manipulation to save scads of processor time.
|
||||
* Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Description: Fast IO functions LPC1768
|
||||
*
|
||||
* For TARGET LPC1768
|
||||
*/
|
||||
|
||||
#include "../shared/Marduino.h"
|
||||
#include <mcu_interface.h>
|
||||
|
||||
#define PWM_PIN(P) true // all pins are software PWM capable
|
||||
|
||||
#define LPC_PIN(pin) MCUI::gpio_pin(pin)
|
||||
#define LPC_GPIO(port) MCUI::gpio_port(port)
|
||||
|
||||
#define SET_DIR_INPUT(IO) MCUI::gpio_set_input(IO)
|
||||
#define SET_DIR_OUTPUT(IO) MCUI::gpio_set_output(IO)
|
||||
|
||||
#define SET_MODE(IO, mode) pinMode(IO, mode)
|
||||
|
||||
#define WRITE_PIN_SET(IO) MCUI::gpio_set(IO)
|
||||
#define WRITE_PIN_CLR(IO) MCUI::gpio_clear(IO)
|
||||
|
||||
#define READ_PIN(IO) MCUI::gpio_get(IO)
|
||||
#define WRITE_PIN(IO,V) MCUI::gpio_set(IO, V)
|
||||
|
||||
/**
|
||||
* Magic I/O routines
|
||||
*
|
||||
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
|
||||
*
|
||||
* Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html
|
||||
*/
|
||||
|
||||
/// Read a pin
|
||||
#define _READ(IO) READ_PIN(IO)
|
||||
|
||||
/// Write to a pin
|
||||
#define _WRITE(IO,V) WRITE_PIN(IO,V)
|
||||
|
||||
/// toggle a pin
|
||||
#define _TOGGLE(IO) MCUI::gpio_toggle(IO)
|
||||
|
||||
/// set pin as input
|
||||
#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
|
||||
|
||||
/// set pin as output
|
||||
#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO)
|
||||
|
||||
/// set pin as input with pullup mode
|
||||
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
|
||||
|
||||
/// set pin as input with pulldown mode
|
||||
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
|
||||
|
||||
/// check if pin is an input
|
||||
#define _IS_INPUT(IO) (!MCUI::gpio_get_dir(IO))
|
||||
|
||||
/// check if pin is an output
|
||||
#define _IS_OUTPUT(IO) (MCUI::gpio_get_dir(IO))
|
||||
|
||||
/// Read a pin wrapper
|
||||
#define READ(IO) _READ(IO)
|
||||
|
||||
/// Write to a pin wrapper
|
||||
#define WRITE(IO,V) _WRITE(IO,V)
|
||||
|
||||
/// toggle a pin wrapper
|
||||
#define TOGGLE(IO) _TOGGLE(IO)
|
||||
|
||||
/// set pin as input wrapper
|
||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||
/// set pin as input with pullup wrapper
|
||||
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
|
||||
/// set pin as input with pulldown wrapper
|
||||
#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0)
|
||||
/// set pin as output wrapper - reads the pin and sets the output to that value
|
||||
#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
|
||||
// set pin as PWM
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
/// check if pin is an input wrapper
|
||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||
/// check if pin is an output wrapper
|
||||
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
||||
|
||||
// Shorthand
|
||||
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
|
||||
|
||||
// digitalRead/Write wrappers
|
||||
#define extDigitalRead(IO) digitalRead(IO)
|
||||
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if DISABLED(NO_SD_HOST_DRIVE)
|
||||
#define HAS_SD_HOST_DRIVE 1
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if USE_FALLBACK_EEPROM
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
#elif ANY(I2C_EEPROM, SPI_EEPROM)
|
||||
#define USE_SHARED_EEPROM 1
|
||||
#endif
|
||||
|
||||
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
|
||||
// TODO: Which other boards are incompatible?
|
||||
#if defined(MCU_LPC1768) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0
|
||||
#define PRINTCOUNTER_SYNC 1
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// #if PIO_PLATFORM_VERSION < 1001
|
||||
// #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically."
|
||||
// #endif
|
||||
// #if PIO_FRAMEWORK_VERSION < 2006
|
||||
// #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* Detect an old pins file by checking for old ADC pins values.
|
||||
*/
|
||||
#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && !WITHIN(_CAT(P,_PIN), TERN(LPC1768_IS_SKRV1_3, 0, 2), 3) // Include P0_00 and P0_01 for SKR V1.3 board
|
||||
#if _OLD_TEMP_PIN(TEMP_BED)
|
||||
#error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_0)
|
||||
#error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_1)
|
||||
#error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_2)
|
||||
#error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_3)
|
||||
#error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_4)
|
||||
#error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_5)
|
||||
#error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_6)
|
||||
#error "TEMP_6_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_7)
|
||||
#error "TEMP_7_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#endif
|
||||
#undef _OLD_TEMP_PIN
|
||||
|
||||
/**
|
||||
* Because PWM hardware channels all share the same frequency, along with the
|
||||
* fallback software channels, FAST_PWM_FAN is incompatible with Servos.
|
||||
*/
|
||||
static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards.");
|
||||
|
||||
#if SPINDLE_LASER_FREQUENCY
|
||||
static_assert(!NUM_SERVOS, "BLTOUCH and Servos are incompatible with SPINDLE_LASER_FREQUENCY on LPC176x boards.");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Test LPC176x-specific configuration values for errors at compile-time.
|
||||
*/
|
||||
|
||||
//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
|
||||
// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
|
||||
//#endif
|
||||
|
||||
#if MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF)
|
||||
#if IS_RRD_FG_SC && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI)
|
||||
#error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 requires TMC_USE_SW_SPI."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported on LPC176x.");
|
||||
|
||||
/**
|
||||
* Flag any serial port conflicts
|
||||
*
|
||||
* Port | TX | RX |
|
||||
* --- | --- | --- |
|
||||
* Serial | P0_02 | P0_03 |
|
||||
* Serial1 | P0_15 | P0_16 |
|
||||
* Serial2 | P0_10 | P0_11 |
|
||||
* Serial3 | P0_00 | P0_01 |
|
||||
*/
|
||||
#define ANY_TX(N,V...) DO(IS_TX##N,||,V)
|
||||
#define ANY_RX(N,V...) DO(IS_RX##N,||,V)
|
||||
|
||||
#if USING_HW_SERIAL0
|
||||
#define IS_TX0(P) (P == P0_02)
|
||||
#define IS_RX0(P) (P == P0_03)
|
||||
#if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI)
|
||||
#error "Serial port pins (0) conflict with Trinamic SPI pins!"
|
||||
#elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
|
||||
#error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!"
|
||||
#elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN))
|
||||
#error "Serial port pins (0) conflict with X/Y axis SPI pins!"
|
||||
#endif
|
||||
#undef IS_TX0
|
||||
#undef IS_RX0
|
||||
#endif
|
||||
|
||||
#if USING_HW_SERIAL1
|
||||
#define IS_TX1(P) (P == P0_15)
|
||||
#define IS_RX1(P) (P == P0_16)
|
||||
#define _IS_TX1_1 IS_TX1
|
||||
#define _IS_RX1_1 IS_RX1
|
||||
#if IS_TX1(TMC_SW_SCK)
|
||||
#error "Serial port pins (1) conflict with other pins!"
|
||||
#elif HAS_ROTARY_ENCODER
|
||||
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
|
||||
#error "Serial port pins (1) conflict with Encoder Buttons!"
|
||||
#elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \
|
||||
|| ANY_RX(1, LCD_SDSS, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
|
||||
#error "Serial port pins (1) conflict with LCD pins!"
|
||||
#endif
|
||||
#endif
|
||||
#undef IS_TX1
|
||||
#undef IS_RX1
|
||||
#undef _IS_TX1_1
|
||||
#undef _IS_RX1_1
|
||||
#endif
|
||||
|
||||
#if USING_HW_SERIAL2
|
||||
#define IS_TX2(P) (P == P0_10)
|
||||
#define IS_RX2(P) (P == P0_11)
|
||||
#define _IS_TX2_1 IS_TX2
|
||||
#define _IS_RX2_1 IS_RX2
|
||||
#if IS_TX2(X2_ENABLE_PIN) || ANY_RX(2, X2_DIR_PIN, X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with X2 pins!"
|
||||
#elif IS_TX2(Y2_ENABLE_PIN) || ANY_RX(2, Y2_DIR_PIN, Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Y2 pins!"
|
||||
#elif IS_TX2(Z2_ENABLE_PIN) || ANY_RX(2, Z2_DIR_PIN, Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Z2 pins!"
|
||||
#elif IS_TX2(Z3_ENABLE_PIN) || ANY_RX(2, Z3_DIR_PIN, Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Z3 pins!"
|
||||
#elif IS_TX2(Z4_ENABLE_PIN) || ANY_RX(2, Z4_DIR_PIN, Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Z4 pins!"
|
||||
#elif ANY_RX(2, X_DIR_PIN, Y_DIR_PIN)
|
||||
#error "Serial port pins (2) conflict with other pins!"
|
||||
#elif Y_HOME_TO_MIN && IS_TX2(Y_STOP_PIN)
|
||||
#error "Serial port pins (2) conflict with Y endstop pin!"
|
||||
#elif USES_Z_MIN_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN)
|
||||
#error "Serial port pins (2) conflict with probe pin!"
|
||||
#elif ANY_TX(2, X_ENABLE_PIN, Y_ENABLE_PIN) || ANY_RX(2, X_DIR_PIN, Y_DIR_PIN)
|
||||
#error "Serial port pins (2) conflict with X/Y stepper pins!"
|
||||
#elif HAS_MULTI_EXTRUDER && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN)))
|
||||
#error "Serial port pins (2) conflict with E1 stepper pins!"
|
||||
#elif EXTRUDERS && ANY_RX(2, E0_DIR_PIN, E0_STEP_PIN)
|
||||
#error "Serial port pins (2) conflict with E stepper pins!"
|
||||
#endif
|
||||
#undef IS_TX2
|
||||
#undef IS_RX2
|
||||
#undef _IS_TX2_1
|
||||
#undef _IS_RX2_1
|
||||
#endif
|
||||
|
||||
#if USING_HW_SERIAL3
|
||||
#define PIN_IS_TX3(P) (PIN_EXISTS(P) && P##_PIN == P0_00)
|
||||
#define PIN_IS_RX3(P) (P##_PIN == P0_01)
|
||||
#if PIN_IS_TX3(X_MIN) || PIN_IS_RX3(X_MAX)
|
||||
#error "Serial port pins (3) conflict with X endstop pins!"
|
||||
#elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX)
|
||||
#error "Serial port pins (3) conflict with X/Y axis UART pins!"
|
||||
#elif PIN_IS_TX3(X2_DIR) || PIN_IS_RX3(X2_STEP)
|
||||
#error "Serial port pins (3) conflict with X2 pins!"
|
||||
#elif PIN_IS_TX3(Y2_DIR) || PIN_IS_RX3(Y2_STEP)
|
||||
#error "Serial port pins (3) conflict with Y2 pins!"
|
||||
#elif PIN_IS_TX3(Z2_DIR) || PIN_IS_RX3(Z2_STEP)
|
||||
#error "Serial port pins (3) conflict with Z2 pins!"
|
||||
#elif PIN_IS_TX3(Z3_DIR) || PIN_IS_RX3(Z3_STEP)
|
||||
#error "Serial port pins (3) conflict with Z3 pins!"
|
||||
#elif PIN_IS_TX3(Z4_DIR) || PIN_IS_RX3(Z4_STEP)
|
||||
#error "Serial port pins (3) conflict with Z4 pins!"
|
||||
#elif HAS_MULTI_EXTRUDER && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP))
|
||||
#error "Serial port pins (3) conflict with E1 pins!"
|
||||
#endif
|
||||
#undef PIN_IS_TX3
|
||||
#undef PIN_IS_RX3
|
||||
#endif
|
||||
|
||||
#undef ANY_TX
|
||||
#undef ANY_RX
|
||||
|
||||
//
|
||||
// Flag any i2c pin conflicts
|
||||
//
|
||||
#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
|
||||
#define USEDI2CDEV_M 1 // <Arduino>/Wire.cpp
|
||||
|
||||
#if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1)
|
||||
#define PIN_IS_SDA0(P) (P##_PIN == P0_27)
|
||||
#define IS_SCL0(P) (P == P0_28)
|
||||
#if ENABLED(SDSUPPORT) && PIN_IS_SDA0(SD_DETECT)
|
||||
#error "SDA0 overlaps with SD_DETECT_PIN!"
|
||||
#elif PIN_IS_SDA0(E0_AUTO_FAN)
|
||||
#error "SDA0 overlaps with E0_AUTO_FAN_PIN!"
|
||||
#elif PIN_IS_SDA0(BEEPER)
|
||||
#error "SDA0 overlaps with BEEPER_PIN!"
|
||||
#elif IS_SCL0(BTN_ENC)
|
||||
#error "SCL0 overlaps with Encoder Button!"
|
||||
#elif IS_SCL0(SD_SS_PIN)
|
||||
#error "SCL0 overlaps with SD_SS_PIN!"
|
||||
#elif IS_SCL0(LCD_SDSS)
|
||||
#error "SCL0 overlaps with LCD_SDSS!"
|
||||
#endif
|
||||
#undef PIN_IS_SDA0
|
||||
#undef IS_SCL0
|
||||
#elif USEDI2CDEV_M == 1 // P0_00 [D20] (SCA) ............ P0_01 [D21] (SCL)
|
||||
#define PIN_IS_SDA1(P) (PIN_EXISTS(P) && P##_PIN == P0_00)
|
||||
#define PIN_IS_SCL1(P) (P##_PIN == P0_01)
|
||||
#if PIN_IS_SDA1(X_MIN) || PIN_IS_SCL1(X_MAX)
|
||||
#error "One or more i2c (1) pins overlaps with X endstop pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(X2_DIR) || PIN_IS_SCL1(X2_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with X2 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Y2_DIR) || PIN_IS_SCL1(Y2_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Y2 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Z2_DIR) || PIN_IS_SCL1(Z2_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Z2 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Z3_DIR) || PIN_IS_SCL1(Z3_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Z3 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Z4_DIR) || PIN_IS_SCL1(Z4_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Z4 pins! Disable i2c peripherals."
|
||||
#elif HAS_MULTI_EXTRUDER && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP))
|
||||
#error "One or more i2c (1) pins overlaps with E1 pins! Disable i2c peripherals."
|
||||
#endif
|
||||
#undef PIN_IS_SDA1
|
||||
#undef PIN_IS_SCL1
|
||||
#elif USEDI2CDEV_M == 2 // P0_10 [D38] (X_ENABLE_PIN) ... P0_11 [D55] (X_DIR_PIN)
|
||||
#define PIN_IS_SDA2(P) (P##_PIN == P0_10)
|
||||
#define PIN_IS_SCL2(P) (P##_PIN == P0_11)
|
||||
#if PIN_IS_SDA2(Y_STOP)
|
||||
#error "i2c SDA2 overlaps with Y endstop pin!"
|
||||
#elif USES_Z_MIN_PROBE_PIN && PIN_IS_SDA2(Z_MIN_PROBE)
|
||||
#error "i2c SDA2 overlaps with Z probe pin!"
|
||||
#elif PIN_IS_SDA2(X_ENABLE) || PIN_IS_SDA2(Y_ENABLE)
|
||||
#error "i2c SDA2 overlaps with X/Y ENABLE pin!"
|
||||
#elif AXIS_HAS_SPI(X) && PIN_IS_SDA2(X_CS)
|
||||
#error "i2c SDA2 overlaps with X CS pin!"
|
||||
#elif PIN_IS_SDA2(X2_ENABLE)
|
||||
#error "i2c SDA2 overlaps with X2 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Y2_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Y2 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Z2_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Z2 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Z3_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Z3 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Z4_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Z4 enable pin! Disable i2c peripherals."
|
||||
#elif HAS_MULTI_EXTRUDER && PIN_IS_SDA2(E1_ENABLE)
|
||||
#error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals."
|
||||
#elif HAS_MULTI_EXTRUDER && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS)
|
||||
#error "i2c SDA2 overlaps with E1 CS pin! Disable i2c peripherals."
|
||||
#elif EXTRUDERS && (PIN_IS_SDA2(E0_STEP) || PIN_IS_SDA2(E0_DIR))
|
||||
#error "i2c SCL2 overlaps with E0 STEP/DIR pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(X_DIR) || PIN_IS_SDA2(Y_DIR)
|
||||
#error "One or more i2c pins overlaps with X/Y DIR pin! Disable i2c peripherals."
|
||||
#endif
|
||||
#undef PIN_IS_SDA2
|
||||
#undef PIN_IS_SCL2
|
||||
#endif
|
||||
|
||||
#undef USEDI2CDEV_M
|
||||
#endif
|
||||
|
||||
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
|
||||
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on LPC176x."
|
||||
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
|
||||
#error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x."
|
||||
#endif
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mcu_interface.h>
|
||||
|
||||
//#define MSBFIRST 1
|
||||
|
||||
#define SPI_MODE0 0
|
||||
#define SPI_MODE1 1
|
||||
#define SPI_MODE2 2
|
||||
#define SPI_MODE3 3
|
||||
|
||||
#define SSP_CR0_DSS(n) ((uint32_t)((n-1)&0xF))
|
||||
#define SSP_DATABIT_4 SSP_CR0_DSS(4) /*!< Databit number = 4 */
|
||||
#define SSP_DATABIT_5 SSP_CR0_DSS(5) /*!< Databit number = 5 */
|
||||
#define SSP_DATABIT_6 SSP_CR0_DSS(6) /*!< Databit number = 6 */
|
||||
#define SSP_DATABIT_7 SSP_CR0_DSS(7) /*!< Databit number = 7 */
|
||||
#define SSP_DATABIT_8 SSP_CR0_DSS(8) /*!< Databit number = 8 */
|
||||
#define SSP_DATABIT_9 SSP_CR0_DSS(9) /*!< Databit number = 9 */
|
||||
#define SSP_DATABIT_10 SSP_CR0_DSS(10) /*!< Databit number = 10 */
|
||||
#define SSP_DATABIT_11 SSP_CR0_DSS(11) /*!< Databit number = 11 */
|
||||
#define SSP_DATABIT_12 SSP_CR0_DSS(12) /*!< Databit number = 12 */
|
||||
#define SSP_DATABIT_13 SSP_CR0_DSS(13) /*!< Databit number = 13 */
|
||||
#define SSP_DATABIT_14 SSP_CR0_DSS(14) /*!< Databit number = 14 */
|
||||
#define SSP_DATABIT_15 SSP_CR0_DSS(15) /*!< Databit number = 15 */
|
||||
#define SSP_DATABIT_16 SSP_CR0_DSS(16) /*!< Databit number = 16 */
|
||||
|
||||
#define DATA_SIZE_8BIT SSP_DATABIT_8
|
||||
#define DATA_SIZE_16BIT SSP_DATABIT_16
|
||||
|
||||
#define SPI_CLOCK_MAX_TFT 30000000UL
|
||||
#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
|
||||
#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
|
||||
#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
|
||||
#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
|
||||
#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
|
||||
#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
|
||||
#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
|
||||
|
||||
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
|
||||
|
||||
#define BOARD_NR_SPI 3
|
||||
|
||||
// SSP0 TMC port
|
||||
#define BOARD_SPI1_NSS_PIN P_NC
|
||||
#define BOARD_SPI1_SCK_PIN P1_20
|
||||
#define BOARD_SPI1_MISO_PIN P1_23
|
||||
#define BOARD_SPI1_MOSI_PIN P1_24
|
||||
|
||||
// SSP2 LCD SD port
|
||||
#define BOARD_SPI2_NSS_PIN P_NC
|
||||
#define BOARD_SPI2_SCK_PIN P1_00
|
||||
#define BOARD_SPI2_MISO_PIN P1_04
|
||||
#define BOARD_SPI2_MOSI_PIN P1_01
|
||||
|
||||
// SSP1 Onboard SD port
|
||||
#define BOARD_SPI3_NSS_PIN P_NC
|
||||
#define BOARD_SPI3_SCK_PIN P0_07
|
||||
#define BOARD_SPI3_MISO_PIN P0_08
|
||||
#define BOARD_SPI3_MOSI_PIN P0_09
|
||||
|
||||
class SPISettings {
|
||||
public:
|
||||
SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) {
|
||||
init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT);
|
||||
}
|
||||
SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
|
||||
if (__builtin_constant_p(inClock))
|
||||
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
|
||||
else
|
||||
init_MightInline(inClock, inBitOrder, inDataMode, inDataSize);
|
||||
}
|
||||
SPISettings() {
|
||||
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
|
||||
}
|
||||
|
||||
//uint32_t spiRate() const { return spi_speed; }
|
||||
|
||||
static uint32_t spiRate2Clock(uint32_t spiRate) {
|
||||
uint32_t Marlin_speed[7]; // CPSR is always 2
|
||||
Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
|
||||
Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
|
||||
Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
|
||||
Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
|
||||
Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
|
||||
Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
|
||||
Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
|
||||
return Marlin_speed[spiRate > 6 ? 6 : spiRate];
|
||||
}
|
||||
|
||||
private:
|
||||
void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
|
||||
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
|
||||
}
|
||||
void init_AlwaysInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) {
|
||||
clock = inClock;
|
||||
bitOrder = inBitOrder;
|
||||
dataMode = inDataMode;
|
||||
dataSize = inDataSize;
|
||||
m_config = {};
|
||||
m_config.frequency = 400000;
|
||||
}
|
||||
|
||||
MCUI::SSP::Config m_config;
|
||||
|
||||
//uint32_t spi_speed;
|
||||
uint32_t clock;
|
||||
uint32_t dataSize;
|
||||
//uint32_t clockDivider;
|
||||
uint8_t bitOrder;
|
||||
uint8_t dataMode;
|
||||
|
||||
uint8_t device_id;
|
||||
|
||||
friend class SPIClass;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Wirish SPI interface.
|
||||
*
|
||||
* This is the same interface is available across HAL
|
||||
*
|
||||
* This implementation uses software slave management, so the caller
|
||||
* is responsible for controlling the slave select line.
|
||||
*/
|
||||
class SPIClass {
|
||||
public:
|
||||
/**
|
||||
* @param spiPortNumber Number of the SPI port to manage.
|
||||
*/
|
||||
SPIClass(uint8_t spiPortNumber);
|
||||
|
||||
/**
|
||||
* Init using pins
|
||||
*/
|
||||
SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1);
|
||||
|
||||
/**
|
||||
* Select and configure the current selected SPI device to use
|
||||
*/
|
||||
void begin();
|
||||
|
||||
/**
|
||||
* Disable the current SPI device
|
||||
*/
|
||||
void end();
|
||||
|
||||
void beginTransaction(const SPISettings&);
|
||||
void endTransaction() {}
|
||||
|
||||
// Transfer using 1 "Data Size"
|
||||
uint8_t transfer(uint16_t data);
|
||||
// Transfer 2 bytes in 8 bit mode
|
||||
uint16_t transfer16(uint16_t data);
|
||||
|
||||
void send(uint8_t data);
|
||||
|
||||
uint16_t read();
|
||||
void read(uint8_t *buf, uint32_t len);
|
||||
|
||||
void dmaSend(void *buf, uint16_t length, bool minc);
|
||||
|
||||
/**
|
||||
* @brief Sets the number of the SPI peripheral to be used by
|
||||
* this HardwareSPI instance.
|
||||
*
|
||||
* @param spi_num Number of the SPI port. 1-2 in low density devices
|
||||
* or 1-3 in high density devices.
|
||||
*/
|
||||
void setModule(uint8_t device);
|
||||
|
||||
void setClock(uint32_t clock);
|
||||
void setBitOrder(uint8_t bitOrder);
|
||||
void setDataMode(uint8_t dataMode);
|
||||
void setDataSize(uint32_t ds);
|
||||
|
||||
inline uint32_t getDataSize() { return _currentSetting->dataSize; }
|
||||
|
||||
private:
|
||||
SPISettings _settings[BOARD_NR_SPI];
|
||||
SPISettings *_currentSetting;
|
||||
|
||||
void updateSettings();
|
||||
};
|
||||
|
||||
extern SPIClass SPI;
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../../core/millis_t.h"
|
||||
#include "../../sd/cardreader.h"
|
||||
|
||||
#include <mcu_interface.h>
|
||||
#include <driver/usb_device.h>
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
|
||||
|
||||
void MarlinHAL::init() {
|
||||
|
||||
MCUI::pwm_init();
|
||||
|
||||
// Init LEDs
|
||||
#if PIN_EXISTS(LED)
|
||||
SET_DIR_OUTPUT(LED_PIN);
|
||||
WRITE_PIN_CLR(LED_PIN);
|
||||
#if PIN_EXISTS(LED2)
|
||||
SET_DIR_OUTPUT(LED2_PIN);
|
||||
WRITE_PIN_CLR(LED2_PIN);
|
||||
#if PIN_EXISTS(LED3)
|
||||
SET_DIR_OUTPUT(LED3_PIN);
|
||||
WRITE_PIN_CLR(LED3_PIN);
|
||||
#if PIN_EXISTS(LED4)
|
||||
SET_DIR_OUTPUT(LED4_PIN);
|
||||
WRITE_PIN_CLR(LED4_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Flash status LED 3 times to indicate Marlin has started booting
|
||||
for(int i = 0; i < 6; ++i) {
|
||||
TOGGLE(LED_PIN);
|
||||
delay(100);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Init Servo Pins
|
||||
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
|
||||
#if HAS_SERVO_0
|
||||
INIT_SERVO(0);
|
||||
#endif
|
||||
#if HAS_SERVO_1
|
||||
INIT_SERVO(1);
|
||||
#endif
|
||||
#if HAS_SERVO_2
|
||||
INIT_SERVO(2);
|
||||
#endif
|
||||
#if HAS_SERVO_3
|
||||
INIT_SERVO(3);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(SD_SS)
|
||||
OUT_WRITE(SD_SS_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN
|
||||
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
TERN_(HAS_SD_HOST_DRIVE, MCUI::USBDevice::msc_storage_init()); // Enable USB SD card access
|
||||
MCUI::USBDevice::connect(2000, LED_PIN);
|
||||
|
||||
HAL_timer_init();
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
|
||||
}
|
||||
|
||||
// HAL idle task
|
||||
void MarlinHAL::idletask() {
|
||||
#if HAS_SHARED_MEDIA
|
||||
// If Marlin is using the SD card we need to lock it to prevent access from
|
||||
// a PC via USB.
|
||||
// Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
|
||||
// this will not reliably detect delete operations. To be safe we will lock
|
||||
// the disk if Marlin has it mounted. Unfortunately there is currently no way
|
||||
// to unmount the disk from the LCD menu.
|
||||
// if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
|
||||
if (card.isMounted())
|
||||
MCUI::USBDevice::msc_storage_lock();
|
||||
else
|
||||
MCUI::USBDevice::msc_storage_release();
|
||||
#endif
|
||||
// Perform USB stack housekeeping
|
||||
MCUI::USBDevice::msc_run_deferred_commands();
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support routines for LPC1768
|
||||
*/
|
||||
|
||||
/**
|
||||
* Translation of routines & variables used by pinsDebug.h
|
||||
*/
|
||||
|
||||
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
|
||||
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
|
||||
#define digitalRead_mod(p) extDigitalRead(p)
|
||||
#define PRINT_PORT(p)
|
||||
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
||||
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
|
||||
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), MCUI::pin_port(p), MCUI::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
|
||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), MCUI::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0)
|
||||
#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin
|
||||
|
||||
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
|
||||
#ifndef M43_NEVER_TOUCH
|
||||
#define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins
|
||||
#endif
|
||||
|
||||
bool GET_PINMODE(const pin_t pin) {
|
||||
if (!MCUI::pin_is_valid(pin) || MCUI::pin_adc_enabled(pin)) // found an invalid pin or active analog pin
|
||||
return false;
|
||||
|
||||
return MCUI::gpio_direction(pin);
|
||||
}
|
||||
|
||||
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
|
||||
|
||||
void print_port(const pin_t) {}
|
||||
void pwm_details(const pin_t) {}
|
||||
bool pwm_status(const pin_t) { return false; }
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../core/macros.h"
|
||||
|
||||
#if ALL(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
|
||||
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
|
||||
// needed due to the speed and mode required for communicating with each device being different.
|
||||
// This requirement can be removed if the SPI access to these devices is updated to use
|
||||
// spiBeginTransaction.
|
||||
#endif
|
||||
|
||||
/** onboard SD card */
|
||||
//#define SD_SCK_PIN P0_07
|
||||
//#define SD_MISO_PIN P0_08
|
||||
//#define SD_MOSI_PIN P0_09
|
||||
//#define SD_SS_PIN P0_06
|
||||
/** external */
|
||||
#ifndef SD_SCK_PIN
|
||||
#define SD_SCK_PIN P0_15
|
||||
#endif
|
||||
#ifndef SD_MISO_PIN
|
||||
#define SD_MISO_PIN P0_17
|
||||
#endif
|
||||
#ifndef SD_MOSI_PIN
|
||||
#define SD_MOSI_PIN P0_18
|
||||
#endif
|
||||
#ifndef SD_SS_PIN
|
||||
#define SD_SS_PIN P1_23
|
||||
#endif
|
||||
#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h
|
||||
#undef SDSS
|
||||
#define SDSS SD_SS_PIN
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* Timers for LPC1768
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
void HAL_timer_init() {
|
||||
SBI(MCUI::system_control.PCONP, SBIT_TIMER0); // Power ON Timer 0
|
||||
STEP_TIMER_REF.PR = (HAL_TIMER_RATE) / (STEPPER_TIMER_RATE) - 1; // Use prescaler to set frequency if needed
|
||||
|
||||
SBI(MCUI::system_control.PCONP, SBIT_TIMER1); // Power ON Timer 1
|
||||
TEMP_TIMER_REF.PR = (HAL_TIMER_RATE) / 1000000 - 1;
|
||||
}
|
||||
|
||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP:
|
||||
STEP_TIMER_REF.MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
|
||||
STEP_TIMER_REF.MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency
|
||||
STEP_TIMER_REF.TCR = _BV(SBIT_CNTEN); // Counter Enable
|
||||
|
||||
MCUCore::nvic_set_priority(MCUI::IRQNumber::TIMER0, MCUCore::nvic_encode_priority(0, 1, 0));
|
||||
MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER0);
|
||||
break;
|
||||
|
||||
case MF_TIMER_TEMP:
|
||||
TEMP_TIMER_REF.MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
|
||||
TEMP_TIMER_REF.MR0 = uint32_t(TEMP_TIMER_RATE) / frequency;
|
||||
TEMP_TIMER_REF.TCR = _BV(SBIT_CNTEN); // Counter Enable
|
||||
|
||||
MCUCore::nvic_set_priority(MCUI::IRQNumber::TIMER1, MCUCore::nvic_encode_priority(0, 2, 0));
|
||||
MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER1);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* HAL For LPC1768
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mcu_interface.h>
|
||||
|
||||
#include "../../core/macros.h"
|
||||
|
||||
#define SBIT_TIMER0 1
|
||||
#define SBIT_TIMER1 2
|
||||
|
||||
#define SBIT_CNTEN 0
|
||||
|
||||
#define SBIT_MR0I 0 // Timer 0 Interrupt when TC matches MR0
|
||||
#define SBIT_MR0R 1 // Timer 0 Reset TC on Match
|
||||
#define SBIT_MR0S 2 // Timer 0 Stop TC and PC on Match
|
||||
#define SBIT_MR1I 3
|
||||
#define SBIT_MR1R 4
|
||||
#define SBIT_MR1S 5
|
||||
#define SBIT_MR2I 6
|
||||
#define SBIT_MR2R 7
|
||||
#define SBIT_MR2S 8
|
||||
#define SBIT_MR3I 9
|
||||
#define SBIT_MR3R 10
|
||||
#define SBIT_MR3S 11
|
||||
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
#define _HAL_TIMER(T) _CAT(MCUI::timer, T)
|
||||
#define _HAL_TIMER_IRQ(T) TIMER##T##_IRQn
|
||||
#define __HAL_TIMER_ISR(T) extern "C" void TIMER##T##_IRQHandler()
|
||||
#define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T)
|
||||
|
||||
typedef uint32_t hal_timer_t;
|
||||
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
|
||||
|
||||
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
|
||||
|
||||
#ifndef MF_TIMER_STEP
|
||||
#define MF_TIMER_STEP 0 // Timer Index for Stepper
|
||||
#endif
|
||||
#ifndef MF_TIMER_PULSE
|
||||
#define MF_TIMER_PULSE MF_TIMER_STEP
|
||||
#endif
|
||||
#ifndef MF_TIMER_TEMP
|
||||
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
|
||||
#endif
|
||||
#ifndef MF_TIMER_PWM
|
||||
#define MF_TIMER_PWM 3 // Timer Index for PWM
|
||||
#endif
|
||||
|
||||
#define TEMP_TIMER_RATE 1000000
|
||||
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
|
||||
|
||||
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
|
||||
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
|
||||
|
||||
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
|
||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||
|
||||
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
|
||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
|
||||
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
|
||||
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
|
||||
|
||||
#ifndef HAL_STEP_TIMER_ISR
|
||||
#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_STEP)
|
||||
#endif
|
||||
#ifndef HAL_TEMP_TIMER_ISR
|
||||
#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_TEMP)
|
||||
#endif
|
||||
|
||||
// Timer references by index
|
||||
#define STEP_TIMER_REF _HAL_TIMER(MF_TIMER_STEP)
|
||||
#define TEMP_TIMER_REF _HAL_TIMER(MF_TIMER_TEMP)
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
void HAL_timer_init();
|
||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
|
||||
|
||||
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: STEP_TIMER_REF.MR0 = compare; break; // Stepper Timer Match Register 0
|
||||
case MF_TIMER_TEMP: TEMP_TIMER_REF.MR0 = compare; break; // Temp Timer Match Register 0
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: return STEP_TIMER_REF.MR0; // Stepper Timer Match Register 0
|
||||
case MF_TIMER_TEMP: return TEMP_TIMER_REF.MR0; // Temp Timer Match Register 0
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: return STEP_TIMER_REF.TC; // Stepper Timer Count
|
||||
case MF_TIMER_TEMP: return TEMP_TIMER_REF.TC; // Temp Timer Count
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER0); break; // Enable interrupt handler
|
||||
case MF_TIMER_TEMP: MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER1); break; // Enable interrupt handler
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: MCUCore::nvic_disable_irq(MCUI::IRQNumber::TIMER0); break; // Disable interrupt handler
|
||||
case MF_TIMER_TEMP: MCUCore::nvic_disable_irq(MCUI::IRQNumber::TIMER1); break; // Disable interrupt handler
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: return MCUCore::nvic_irq_is_enabled(MCUI::IRQNumber::TIMER0); // Check if interrupt is enabled or not
|
||||
case MF_TIMER_TEMP: return MCUCore::nvic_irq_is_enabled(MCUI::IRQNumber::TIMER1); // Check if interrupt is enabled or not
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: SBI(STEP_TIMER_REF.IR, SBIT_CNTEN); break;
|
||||
case MF_TIMER_TEMP: SBI(TEMP_TIMER_REF.IR, SBIT_CNTEN); break;
|
||||
}
|
||||
}
|
||||
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// adapted from I2C/master/master.c example
|
||||
// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html
|
||||
|
||||
#ifdef TARGET_LPC1768
|
||||
|
||||
#include "../include/i2c_util.h"
|
||||
#include "../../../core/millis_t.h"
|
||||
|
||||
extern int millis();
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define I2CDEV_S_ADDR 0x78 // From SSD1306 (actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write)
|
||||
|
||||
// Send slave address and write bit
|
||||
uint8_t u8g_i2c_start(const uint8_t sla) {
|
||||
// Sometimes TX data ACK or NAK status is returned. That mean the start state didn't
|
||||
// happen which means only the value of the slave address was send. Keep looping until
|
||||
// the slave address and write bit are actually sent.
|
||||
do{
|
||||
_I2C_Stop(I2CDEV_M); // output stop state on I2C bus
|
||||
_I2C_Start(I2CDEV_M); // output start state on I2C bus
|
||||
while ((I2C_status != I2C_I2STAT_M_TX_START)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_RESTART)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_ACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for start to be asserted
|
||||
|
||||
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_STAC; // clear start state before tansmitting slave address
|
||||
LPC_I2C1->I2DAT = I2CDEV_S_ADDR & I2C_I2DAT_BITMASK; // transmit slave address & write bit
|
||||
LPC_I2C1->I2CONSET = I2C_I2CONSET_AA;
|
||||
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
while ((I2C_status != I2C_I2STAT_M_TX_SLAW_ACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_SLAW_NACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_ACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for slaw to finish
|
||||
}while ( (I2C_status == I2C_I2STAT_M_TX_DAT_ACK) || (I2C_status == I2C_I2STAT_M_TX_DAT_NACK));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void u8g_i2c_init(const uint8_t clock_option) {
|
||||
configure_i2c(clock_option);
|
||||
u8g_i2c_start(0); // Send slave address and write bit
|
||||
}
|
||||
|
||||
uint8_t u8g_i2c_send_byte(uint8_t data) {
|
||||
#define I2C_TIMEOUT 3
|
||||
LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data
|
||||
LPC_I2C1->I2CONSET = I2C_I2CONSET_AA;
|
||||
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
const millis_t timeout = millis() + I2C_TIMEOUT;
|
||||
while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && PENDING(millis(), timeout)); // wait for xmit to finish
|
||||
// had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens
|
||||
return 1;
|
||||
}
|
||||
|
||||
void u8g_i2c_stop() {
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
void u8g_i2c_init(const uint8_t clock_options);
|
||||
//uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos);
|
||||
uint8_t u8g_i2c_start(uint8_t sla);
|
||||
uint8_t u8g_i2c_send_byte(uint8_t data);
|
||||
void u8g_i2c_stop();
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* LPC1768 LCD-specific defines
|
||||
*/
|
||||
|
||||
#ifndef U8G_HAL_LINKS
|
||||
|
||||
#define U8G_COM_SSD_I2C_HAL u8g_com_arduino_ssd_i2c_fn // See U8glib-HAL
|
||||
|
||||
#else
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
|
||||
#define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_LPC1768_sw_spi_fn
|
||||
#define U8G_COM_HAL_HW_SPI_FN u8g_com_HAL_LPC1768_hw_spi_fn
|
||||
#define U8G_COM_ST7920_HAL_SW_SPI u8g_com_HAL_LPC1768_ST7920_sw_spi_fn
|
||||
#define U8G_COM_ST7920_HAL_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn
|
||||
#define U8G_COM_SSD_I2C_HAL u8g_com_HAL_LPC1768_ssd_hw_i2c_fn
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* LCD delay routines - used by all the drivers.
|
||||
*
|
||||
* These are based on the LPC1768 routines.
|
||||
*
|
||||
* Couldn't just call exact copies because the overhead
|
||||
* results in a one microsecond delay taking about 4µS.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void U8g_delay(int msec);
|
||||
void u8g_MicroDelay();
|
||||
void u8g_10MicroDelay();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Low level pin manipulation routines - used by all the drivers.
|
||||
*
|
||||
* These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines.
|
||||
*
|
||||
* Couldn't just call exact copies because the overhead killed the LCD update speed
|
||||
* With an intermediate level the softspi was running in the 10-20kHz range which
|
||||
* resulted in using about about 25% of the CPU's time.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include <mcu_interface.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "LCD_pin_routines.h"
|
||||
|
||||
void u8g_SetPinOutput(uint8_t pin) {
|
||||
MCUI::gpio_set_output(pin);
|
||||
}
|
||||
|
||||
void u8g_SetPinInput(uint8_t pin) {
|
||||
MCUI::gpio_set_input(pin);
|
||||
}
|
||||
|
||||
void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status) {
|
||||
MCUI::gpio_set(pin, pin_status);
|
||||
}
|
||||
|
||||
uint8_t u8g_GetPinLevel(uint8_t pin) {
|
||||
return MCUI::gpio_get(pin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Low level pin manipulation routines - used by all the drivers.
|
||||
*
|
||||
* These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines.
|
||||
*
|
||||
* Couldn't just call exact copies because the overhead killed the LCD update speed
|
||||
* With an intermediate level the softspi was running in the 10-20kHz range which
|
||||
* resulted in using about about 25% of the CPU's time.
|
||||
*/
|
||||
|
||||
void u8g_SetPinOutput(uint8_t internal_pin_number);
|
||||
void u8g_SetPinInput(uint8_t internal_pin_number);
|
||||
void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status);
|
||||
uint8_t u8g_GetPinLevel(uint8_t pin);
|
||||
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_msp430_hw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#ifndef LCD_SPI_SPEED
|
||||
#ifdef SD_SPI_SPEED
|
||||
#define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD
|
||||
#else
|
||||
#define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, 1);
|
||||
u8g_SetPILevel(u8g, U8G_PI_A0, 1);
|
||||
u8g_SetPILevel(u8g, U8G_PI_RESET, 1);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_A0);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_RESET);
|
||||
u8g_Delay(5);
|
||||
spiBegin();
|
||||
spiInit(LCD_SPI_SPEED);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g_SetPILevel(u8g, U8G_PI_A0, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, (arg_val ? 0 : 1));
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
spiSend((uint8_t)arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
spiSend(*ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
spiSend(*ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_arduino_ssd_i2c.c
|
||||
*
|
||||
* COM interface for Arduino (AND ATmega) and the SSDxxxx chip (SOLOMON) variant
|
||||
* I2C protocol
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Special pin usage:
|
||||
* U8G_PI_I2C_OPTION additional options
|
||||
* U8G_PI_A0_STATE used to store the last value of the command/data register selection
|
||||
* U8G_PI_SET_A0 1: Signal request to update I2C device with new A0_STATE, 0: Do nothing, A0_STATE matches I2C device
|
||||
* U8G_PI_SCL clock line (NOT USED)
|
||||
* U8G_PI_SDA data line (NOT USED)
|
||||
*
|
||||
* U8G_PI_RESET reset line (currently disabled, see below)
|
||||
*
|
||||
* Protocol:
|
||||
* SLA, Cmd/Data Selection, Arguments
|
||||
* The command/data register is selected by a special instruction byte, which is sent after SLA
|
||||
*
|
||||
* The continue bit is always 0 so that a (re)start is equired for the change from cmd to/data mode
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC1768
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
|
||||
#define I2C_SLA (0x3C*2)
|
||||
//#define I2C_CMD_MODE 0x080
|
||||
#define I2C_CMD_MODE 0x000
|
||||
#define I2C_DATA_MODE 0x040
|
||||
|
||||
uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) {
|
||||
/* are we requested to set the a0 state? */
|
||||
if (u8g->pin_list[U8G_PI_SET_A0] == 0) return 1;
|
||||
|
||||
/* setup bus, might be a repeated start */
|
||||
if (u8g_i2c_start(I2C_SLA) == 0) return 0;
|
||||
if (u8g->pin_list[U8G_PI_A0_STATE] == 0) {
|
||||
if (u8g_i2c_send_byte(I2C_CMD_MODE) == 0) return 0;
|
||||
}
|
||||
else if (u8g_i2c_send_byte(I2C_DATA_MODE) == 0)
|
||||
return 0;
|
||||
|
||||
u8g->pin_list[U8G_PI_SET_A0] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
//u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH);
|
||||
//u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH);
|
||||
//u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: unknown mode */
|
||||
|
||||
u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]);
|
||||
u8g_com_ssd_I2C_start_sequence(u8g);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
/* Currently disabled, but it could be enable. Previous restrictions have been removed */
|
||||
/* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = 0;
|
||||
u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */
|
||||
if (arg_val == 0 ) {
|
||||
/* disable chip, send stop condition */
|
||||
u8g_i2c_stop();
|
||||
}
|
||||
else {
|
||||
/* enable, do nothing: any byte writing will trigger the i2c start */
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
//u8g->pin_list[U8G_PI_SET_A0] = 1;
|
||||
if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (u8g_i2c_send_byte(arg_val) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
// u8g_i2c_stop();
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
//u8g->pin_list[U8G_PI_SET_A0] = 1;
|
||||
if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
if (u8g_i2c_send_byte(*ptr++) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
// u8g_i2c_stop();
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
//u8g->pin_list[U8G_PI_SET_A0] = 1;
|
||||
if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
if (u8g_i2c_send_byte(u8g_pgm_read(ptr)) == 0)
|
||||
return 0;
|
||||
ptr++;
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
// u8g_i2c_stop();
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
|
||||
u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */
|
||||
break;
|
||||
|
||||
} // switch
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_LPC1768_st7920_hw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
#include "../../shared/Delay.h"
|
||||
|
||||
void spiBegin();
|
||||
void spiInit(uint8_t spiRate);
|
||||
void spiSend(uint8_t b);
|
||||
void spiSend(const uint8_t *buf, size_t n);
|
||||
|
||||
static uint8_t rs_last_state = 255;
|
||||
|
||||
static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) {
|
||||
|
||||
if (rs != rs_last_state) { // Time to send a command/data byte
|
||||
rs_last_state = rs;
|
||||
spiSend(rs ? 0x0FA : 0x0F8); // Send data or command
|
||||
DELAY_US(40); // Give the controller some time: 20 is bad, 30 is OK, 40 is safe
|
||||
}
|
||||
|
||||
spiSend(val & 0xF0);
|
||||
spiSend(val << 4);
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_Delay(5);
|
||||
spiBegin();
|
||||
spiInit(SPI_EIGHTH_SPEED); // ST7920 max speed is about 1.1 MHz
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = 0; // initial RS state: command mode
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: // Define cmd (arg_val = 0) or data mode (arg_val = 1)
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); // Note: the ST7920 has an active high chip-select
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_st7920_hw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if IS_U8GLIB_ST7920
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../SoftwareSPI.h"
|
||||
#include "../../shared/Delay.h"
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#ifndef LCD_SPI_SPEED
|
||||
#define LCD_SPI_SPEED SPI_EIGHTH_SPEED // About 1 MHz
|
||||
#endif
|
||||
|
||||
static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
|
||||
static uint8_t SPI_speed = 0;
|
||||
|
||||
static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) {
|
||||
static uint8_t rs_last_state = 255;
|
||||
if (rs != rs_last_state) {
|
||||
// Transfer Data (FA) or Command (F8)
|
||||
swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
|
||||
rs_last_state = rs;
|
||||
DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe
|
||||
}
|
||||
swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
|
||||
swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK];
|
||||
MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI];
|
||||
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_SCK);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
|
||||
u8g_Delay(5);
|
||||
|
||||
SPI_speed = swSpiInit(LCD_SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
|
||||
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
|
||||
u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
|
||||
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // IS_U8GLIB_ST7920
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_std_sw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2015, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
|
||||
|
||||
#include <SoftwareSPI.h>
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#ifndef LCD_SPI_SPEED
|
||||
#define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <algorithm>
|
||||
#include <LPC17xx.h>
|
||||
#include <gpio.h>
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
|
||||
uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) {
|
||||
|
||||
LOOP_L_N(i, 8) {
|
||||
if (spi_speed == 0) {
|
||||
LPC176x::gpio_set(mosi_pin, !!(b & 0x80));
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
else {
|
||||
const uint8_t state = (b & 0x80) ? HIGH : LOW;
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(mosi_pin, state);
|
||||
|
||||
LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
|
||||
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) {
|
||||
|
||||
LOOP_L_N(i, 8) {
|
||||
const uint8_t state = (b & 0x80) ? HIGH : LOW;
|
||||
if (spi_speed == 0) {
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
LPC176x::gpio_set(mosi_pin, state);
|
||||
LPC176x::gpio_set(mosi_pin, state); // need some setup time
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
}
|
||||
else {
|
||||
LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(mosi_pin, state);
|
||||
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
}
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static uint8_t SPI_speed = 0;
|
||||
|
||||
static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
|
||||
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864)
|
||||
swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin);
|
||||
#else
|
||||
swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPIOutput(u8g, U8G_PI_SCK);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_A0);
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET);
|
||||
SPI_speed = swSpiInit(LCD_SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
|
||||
u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
|
||||
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
|
||||
// the next chip select goes active
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, LOW);
|
||||
}
|
||||
else {
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, HIGH);
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive
|
||||
}
|
||||
#else
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr));
|
||||
ptr++;
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g_SetPILevel(u8g, U8G_PI_A0, arg_val);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -53,6 +53,7 @@
|
||||
inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
|
||||
|
||||
void _rx_complete_irq(serial_t *obj);
|
||||
FORCE_INLINE static uint8_t buffer_overruns() { return 0; } // Not implemented. Void to avoid platform-dependent code.
|
||||
|
||||
protected:
|
||||
usart_rx_callback_t _rx_callback;
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef uint32_t hal_timer_t;
|
||||
#define FTM0_TIMER_PRESCALE_BITS 0b011
|
||||
#define FTM1_TIMER_PRESCALE_BITS 0b010
|
||||
|
||||
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz
|
||||
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7.5MHz
|
||||
#define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz
|
||||
|
||||
#define HAL_TIMER_RATE (FTM0_TIMER_RATE)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/LPC1768/NAME)
|
||||
#elif defined(ARDUINO_ARCH_HC32)
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/HC32/NAME)
|
||||
#elif defined(TARGET_LPC4078)
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/LPC4078/NAME)
|
||||
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/STM32F1/NAME)
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
#include "../LPC1768/Servo.h"
|
||||
#elif defined(ARDUINO_ARCH_HC32)
|
||||
#include "../HC32/Servo.h"
|
||||
#elif defined(TARGET_LPC4078)
|
||||
#include "../LPC4078/Servo.h"
|
||||
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
|
||||
#include "../STM32F1/Servo.h"
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
|
||||
@@ -266,7 +266,7 @@ PGMSTR(M112_KILL_STR, "M112 Shutdown");
|
||||
MarlinState marlin_state = MF_INITIALIZING;
|
||||
|
||||
// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
|
||||
bool wait_for_heatup = true;
|
||||
bool wait_for_heatup = false;
|
||||
|
||||
// For M0/M1, this flag may be cleared (by M108) to exit the wait-for-user loop
|
||||
#if HAS_RESUME_CONTINUE
|
||||
@@ -474,11 +474,16 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
||||
|
||||
#if HAS_KILL
|
||||
|
||||
// Check if the kill button was pressed and wait just in case it was an accidental
|
||||
// key kill key press
|
||||
// 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.
|
||||
// -------------------------------------------------------------------------------
|
||||
#ifndef KILL_DELAY
|
||||
#define KILL_DELAY 250
|
||||
#endif
|
||||
|
||||
static int killCount = 0; // make the inactivity button a bit less responsive
|
||||
const int KILL_DELAY = 750;
|
||||
if (kill_state())
|
||||
killCount++;
|
||||
else if (killCount > 0)
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
#define BOARD_PXMALION_CORE_I3 1164 // Pxmalion Core I3
|
||||
#define BOARD_PANOWIN_CUTLASS 1165 // Panowin Cutlass (as found in the Panowin F1)
|
||||
#define BOARD_KODAMA_BARDO 1166 // Kodama Bardo V1.x (as found in the Kodama Trinus)
|
||||
#define BOARD_DAGOMA_D6 1167 // Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
|
||||
|
||||
//
|
||||
// RAMBo and derivatives
|
||||
@@ -382,9 +383,9 @@
|
||||
#define BOARD_CREALITY_V452 5050 // Creality v4.5.2 (STM32F103RC / STM32F103RE)
|
||||
#define BOARD_CREALITY_V453 5051 // Creality v4.5.3 (STM32F103RC / STM32F103RE)
|
||||
#define BOARD_CREALITY_V521 5052 // Creality v5.2.1 (STM32F103VE) as found in the SV04
|
||||
#define BOARD_CREALITY_V24S1 5053 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7
|
||||
#define BOARD_CREALITY_V24S1_301 5054 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1
|
||||
#define BOARD_CREALITY_V25S1 5055 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro
|
||||
#define BOARD_CREALITY_V24S1 5053 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) CR-FDM-v2.4.S1_v101 as found in the Ender-7
|
||||
#define BOARD_CREALITY_V24S1_301 5054 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) CR-FDM-v24S1_301 as found in the Ender-3 S1
|
||||
#define BOARD_CREALITY_V25S1 5055 // Creality v2.5.S1 (STM32F103RE) CR-FDM-v2.5.S1_100 as found in the CR-10 Smart Pro
|
||||
#define BOARD_TRIGORILLA_PRO 5056 // Trigorilla Pro (STM32F103ZE)
|
||||
#define BOARD_FLY_MINI 5057 // FLYmaker FLY MINI (STM32F103RC)
|
||||
#define BOARD_FLSUN_HISPEED 5058 // FLSUN HiSpeedV1 (STM32F103VE)
|
||||
@@ -409,6 +410,7 @@
|
||||
|
||||
#define BOARD_TEENSY31_32 5100 // Teensy3.1 and Teensy3.2
|
||||
#define BOARD_TEENSY35_36 5101 // Teensy3.5 and Teensy3.6
|
||||
#define BOARD_EBAB 5102
|
||||
|
||||
//
|
||||
// STM32 ARM Cortex-M4F
|
||||
@@ -467,6 +469,11 @@
|
||||
#define BOARD_FYSETC_CHEETAH_V30 5250 // FYSETC Cheetah V3.0 (STM32F446RC)
|
||||
#define BOARD_BLACKBEEZMINI_V1 5251 // BlackBeezMini V1 (STM32F401CCU6)
|
||||
|
||||
//
|
||||
// Other ARM Cortex-M4
|
||||
//
|
||||
#define BOARD_CREALITY_CR4NS 5300 // Creality CR4NS200320C13 (GD32F303RET6) as found in the Ender-3 V3 SE
|
||||
|
||||
//
|
||||
// ARM Cortex-M7
|
||||
//
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
#define STR_BUSY_PAUSED_FOR_USER "busy: paused for user"
|
||||
#define STR_BUSY_PAUSED_FOR_INPUT "busy: paused for input"
|
||||
#define STR_Z_MOVE_COMP "Z_move_comp"
|
||||
#define STR_LINE_NO "Line: "
|
||||
#define STR_RESEND "Resend: "
|
||||
#define STR_UNKNOWN_COMMAND "Unknown command: \""
|
||||
#define STR_ACTIVE_EXTRUDER "Active Extruder: "
|
||||
|
||||
@@ -89,7 +89,8 @@
|
||||
#define HYPOT2(x,y) (sq(x)+sq(y))
|
||||
#define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z))
|
||||
|
||||
#define CIRCLE_AREA(R) (float(M_PI) * sq(float(R)))
|
||||
#define FLOAT_SQ(I) float(sq(I))
|
||||
#define CIRCLE_AREA(R) (float(M_PI) * FLOAT_SQ(R))
|
||||
#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
|
||||
|
||||
#define SIGN(a) ({__typeof__(a) _a = (a); (_a>0)-(_a<0);})
|
||||
|
||||
@@ -143,13 +143,13 @@ public:
|
||||
|
||||
// Set with format string and arguments, like printf
|
||||
template<typename... Args>
|
||||
MString& setf_P(PGM_P const fmt, Args... more) { SNPRINTF_P(str, SIZE, fmt, more...); debug(F("setf_P")); return *this; }
|
||||
MString& setf_P(PGM_P const pfmt, Args... more) { SNPRINTF_P(str, SIZE, pfmt, more...); debug(F("setf_P")); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
MString& setf(const char *fmt, Args... more) { SNPRINTF(str, SIZE, fmt, more...); debug(F("setf")); return *this; }
|
||||
MString& setf(const char *fmt, Args... more) { SNPRINTF(str, SIZE, fmt, more...); debug(F("setf")); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
MString& setf(FSTR_P const fmt, Args... more) { return setf_P(FTOP(fmt), more...); }
|
||||
MString& setf(FSTR_P const ffmt, Args... more) { return setf_P(FTOP(ffmt), more...); }
|
||||
|
||||
// Chainable String appenders
|
||||
MString& append() { debug(F("nil")); return *this; } // for macros that might emit no output
|
||||
@@ -206,9 +206,9 @@ public:
|
||||
MString& append(const spaces_t &s) { return append(repchr_t(' ', s.count)); }
|
||||
|
||||
template<typename... Args>
|
||||
MString& appendf_P(PGM_P const fmt, Args... more) {
|
||||
MString& appendf_P(PGM_P const pfmt, Args... more) {
|
||||
int sz = length();
|
||||
if (sz < SIZE) SNPRINTF_P(str + sz, SIZE - sz, fmt, more...);
|
||||
if (sz < SIZE) SNPRINTF_P(str + sz, SIZE - sz, pfmt, more...);
|
||||
debug(F("appendf_P"));
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -271,13 +271,13 @@ public:
|
||||
SString& set() { super::set(); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
SString& setf_P(PGM_P const fmt, Args... more) { super::setf_P(fmt, more...); return *this; }
|
||||
SString& setf_P(PGM_P const pfmt, Args... more) { super::setf_P(pfmt, more...); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
SString& setf(const char *fmt, Args... more) { super::setf(fmt, more...); return *this; }
|
||||
SString& setf(const char *fmt, Args... more) { super::setf(fmt, more...); return *this; }
|
||||
|
||||
template<typename... Args>
|
||||
SString& setf(FSTR_P const fmt, Args... more) { super::setf(fmt, more...); return *this; }
|
||||
SString& setf(FSTR_P const ffmt, Args... more) { super::setf(ffmt, more...); return *this; }
|
||||
|
||||
template <typename T>
|
||||
SString& set(const T &v) { super::set(v); return *this; }
|
||||
|
||||
+12
-4
@@ -46,6 +46,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define NUM_AXIS_DECL(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W)
|
||||
#define MAIN_AXIS_NAMES_LC NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)
|
||||
#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
|
||||
#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E)
|
||||
@@ -58,17 +59,21 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
|
||||
#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
|
||||
#define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K, U, V, W)
|
||||
#define LOGICAL_AXIS_NAMES_LC LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)
|
||||
#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES)
|
||||
#define LOGICAL_AXIS_MAP_LC(F) MAP(F, LOGICAL_AXIS_NAMES_LC)
|
||||
#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
|
||||
|
||||
#if NUM_AXES
|
||||
#define NUM_AXES_SEP ,
|
||||
#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES)
|
||||
#define MAIN_AXIS_MAP_LC(F) MAP(F, MAIN_AXIS_NAMES_LC)
|
||||
#define OPTARGS_NUM(T) , NUM_AXIS_ARGS(T)
|
||||
#define OPTARGS_LOGICAL(T) , LOGICAL_AXIS_ARGS(T)
|
||||
#else
|
||||
#define NUM_AXES_SEP
|
||||
#define MAIN_AXIS_MAP(F)
|
||||
#define MAIN_AXIS_MAP_LC(F)
|
||||
#define OPTARGS_NUM(T)
|
||||
#define OPTARGS_LOGICAL(T)
|
||||
#endif
|
||||
@@ -79,6 +84,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define NUM_AXIS_ARGS_(T) NUM_AXIS_ARGS(T) NUM_AXES_SEP
|
||||
#define NUM_AXIS_ELEM_(T) NUM_AXIS_ELEM(T) NUM_AXES_SEP
|
||||
#define MAIN_AXIS_NAMES_ MAIN_AXIS_NAMES NUM_AXES_SEP
|
||||
#define MAIN_AXIS_NAMES_LC_ MAIN_AXIS_NAMES_LC NUM_AXES_SEP
|
||||
|
||||
#if LOGICAL_AXES
|
||||
#define LOGICAL_AXES_SEP ,
|
||||
@@ -92,6 +98,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
#define LOGICAL_AXIS_ARGS_(T) LOGICAL_AXIS_ARGS(T) LOGICAL_AXES_SEP
|
||||
#define LOGICAL_AXIS_ELEM_(T) LOGICAL_AXIS_ELEM(T) LOGICAL_AXES_SEP
|
||||
#define LOGICAL_AXIS_NAMES_ LOGICAL_AXIS_NAMES LOGICAL_AXES_SEP
|
||||
#define LOGICAL_AXIS_NAMES_LC_ LOGICAL_AXIS_NAMES_LC LOGICAL_AXES_SEP
|
||||
|
||||
#define SECONDARY_AXIS_GANG(V...) GANG_N(SECONDARY_AXES, V)
|
||||
#define SECONDARY_AXIS_CODE(V...) CODE_N(SECONDARY_AXES, V)
|
||||
@@ -159,7 +166,7 @@ template <class L, class R> struct IF<true, L, R> { typedef L type; };
|
||||
// General Flags for some number of states
|
||||
template<size_t N>
|
||||
struct Flags {
|
||||
typedef uvalue_t(N) flagbits_t;
|
||||
typedef bits_t(N) flagbits_t;
|
||||
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } N8;
|
||||
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1; } N16;
|
||||
typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1,
|
||||
@@ -219,7 +226,7 @@ typedef struct {
|
||||
//
|
||||
// - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space
|
||||
// - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians
|
||||
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
|
||||
// - X_HEAD, Y_HEAD, and Z_HEAD should be used for axes on Core kinematics
|
||||
//
|
||||
enum AxisEnum : uint8_t {
|
||||
|
||||
@@ -603,9 +610,9 @@ struct XYZval {
|
||||
// If any element is true then it's true
|
||||
FI constexpr operator bool() const { return 0 NUM_AXIS_GANG(|| x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
||||
// Smallest element
|
||||
FI constexpr T small() const { return TERN(HAS_X_AXIS, _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)), 0); }
|
||||
FI constexpr T small() const { return TERN0(HAS_X_AXIS, _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w))); }
|
||||
// Largest element
|
||||
FI constexpr T large() const { return TERN(HAS_X_AXIS, _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)), 0); }
|
||||
FI constexpr T large() const { return TERN0(HAS_X_AXIS, _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w))); }
|
||||
|
||||
// Explicit copy and copies with conversion
|
||||
FI constexpr XYZval<T> copy() const { XYZval<T> o = *this; return o; }
|
||||
@@ -1084,6 +1091,7 @@ public:
|
||||
FI bool toggle(const AxisEnum n) { TBI(bits, n); return TEST(bits, n); }
|
||||
FI void bset(const AxisEnum n) { SBI(bits, n); }
|
||||
FI void bclr(const AxisEnum n) { CBI(bits, n); }
|
||||
FI void bset(const AxisEnum n, const bool b) { if (b) bset(n); else bclr(n); }
|
||||
|
||||
// Accessor via an AxisEnum (or any integer) [index]
|
||||
FI bool operator[](const int n) const { return TEST(bits, n); }
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
#include "../MarlinCore.h"
|
||||
#include "../module/temperature.h"
|
||||
|
||||
#if ENABLED(MARLIN_DEV_MODE)
|
||||
MarlinError marlin_error_number; // Error Number - Marlin can beep X times periodically, display, and emit...
|
||||
#endif
|
||||
|
||||
void safe_delay(millis_t ms) {
|
||||
while (ms > 50) {
|
||||
ms -= 50;
|
||||
@@ -76,6 +80,8 @@ void safe_delay(millis_t ms) {
|
||||
TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY")
|
||||
TERN_(SOLENOID_PROBE, "SOLENOID_PROBE")
|
||||
TERN_(MAGLEV4, "MAGLEV4")
|
||||
TERN_(BIQU_MICROPROBE_V1, "BIQU_MICROPROBE_V1")
|
||||
TERN_(BIQU_MICROPROBE_V2, "BIQU_MICROPROBE_V2")
|
||||
IF_DISABLED(PROBE_SELECTED, "NONE")
|
||||
);
|
||||
|
||||
@@ -95,9 +101,9 @@ void safe_delay(millis_t ms) {
|
||||
SERIAL_ECHOPGM(" (Aligned With");
|
||||
|
||||
if (probe.offset_xy.y > 0)
|
||||
SERIAL_ECHOPGM(TERN(IS_SCARA, "-Distal", "-Back"));
|
||||
SERIAL_ECHO(F(TERN(IS_SCARA, "-Distal", "-Back")));
|
||||
else if (probe.offset_xy.y < 0)
|
||||
SERIAL_ECHOPGM(TERN(IS_SCARA, "-Proximal", "-Front"));
|
||||
SERIAL_ECHO(F(TERN(IS_SCARA, "-Proximal", "-Front")));
|
||||
else if (probe.offset_xy.x != 0)
|
||||
SERIAL_ECHOPGM("-Center");
|
||||
|
||||
@@ -105,7 +111,7 @@ void safe_delay(millis_t ms) {
|
||||
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOF(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as"));
|
||||
SERIAL_ECHO(probe.offset.z < 0 ? F("Below") : probe.offset.z > 0 ? F("Above") : F("Same Z as"));
|
||||
SERIAL_ECHOLNPGM(" Nozzle)");
|
||||
|
||||
#endif
|
||||
|
||||
@@ -46,10 +46,16 @@ BDS_Leveling bdl;
|
||||
#define DEBUG_OUT ENABLED(DEBUG_OUT_BD)
|
||||
#include "../../../core/debug_out.h"
|
||||
|
||||
// M102 S-5 Read raw Calibrate data
|
||||
// M102 S-6 Start Calibrate
|
||||
// M102 S4 Set the adjustable Z height value (e.g., 'M102 S4' means it will do adjusting while the Z height <= 0.4mm , disable with 'M102 S0'.)
|
||||
// M102 S-1 Read sensor information
|
||||
/**
|
||||
* M102 S<#> : Set adjustable Z height in 0.1mm units (10ths of a mm)
|
||||
* (e.g., 'M102 S4' enables adjusting for Z <= 0.4mm)
|
||||
* M102 S0 : Disable adjustable Z height
|
||||
*
|
||||
* M102 S-1 : Read BDsensor version
|
||||
* M102 S-2 : Read BDsensor distance value
|
||||
* M102 S-5 : Read raw Calibration data
|
||||
* M102 S-6 : Start Calibration
|
||||
*/
|
||||
|
||||
#define MAX_BD_HEIGHT 4.0f
|
||||
#define CMD_READ_VERSION 1016
|
||||
|
||||
@@ -765,7 +765,7 @@ void unified_bed_leveling::shift_mesh_height() {
|
||||
|
||||
const grid_count_t point_num = (GRID_MAX_POINTS - count) + 1;
|
||||
SERIAL_ECHOLNPGM("Probing mesh point ", point_num, "/", GRID_MAX_POINTS, ".");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), point_num, int(GRID_MAX_POINTS)));
|
||||
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
|
||||
|
||||
#if HAS_MARLINUI_MENU
|
||||
@@ -1494,7 +1494,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
||||
|
||||
for (uint8_t i = 0; i < 3; ++i) {
|
||||
SERIAL_ECHOLNPGM("Tilting mesh (", i + 1, "/3)");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_LCD_TILTING_MESH), i + 1));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_LCD_TILTING_MESH), i + 1));
|
||||
|
||||
measured_z = probe.probe_at_point(points[i], i < 2 ? PROBE_PT_RAISE : PROBE_PT_LAST_STOW, param.V_verbosity);
|
||||
if ((abort_flag = isnan(measured_z))) break;
|
||||
@@ -1550,7 +1550,7 @@ void unified_bed_leveling::smart_fill_mesh() {
|
||||
#endif
|
||||
|
||||
SERIAL_ECHOLNPGM("Tilting mesh point ", point_num, "/", total_points, "\n");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_LCD_TILTING_MESH), point_num, total_points));
|
||||
|
||||
measured_z = probe.probe_at_point(rpos, parser.seen_test('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, param.V_verbosity); // TODO: Needs error handling
|
||||
|
||||
|
||||
@@ -137,7 +137,7 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
|
||||
// Retract by moving from a faux E position back to the current E position
|
||||
current_retract[active_extruder] = base_retract;
|
||||
prepare_internal_move_to_destination( // set current from destination
|
||||
settings.retract_feedrate_mm_s * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS))
|
||||
MUL_TERN(RETRACT_SYNC_MIXING, settings.retract_feedrate_mm_s, MIXING_STEPPERS)
|
||||
);
|
||||
|
||||
// Is a Z hop set, and has the hop not yet been done?
|
||||
@@ -165,8 +165,7 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/))
|
||||
|
||||
// Recover E, set_current_to_destination
|
||||
prepare_internal_move_to_destination(
|
||||
(swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s)
|
||||
* TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS))
|
||||
MUL_TERN(RETRACT_SYNC_MIXING, swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s, MIXING_STEPPERS)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -197,7 +197,7 @@ void HostUI::action(FSTR_P const fstr, const bool eol) {
|
||||
#endif
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
if (runout.filament_ran_out) { // Disable a triggered sensor
|
||||
runout.enabled[active_extruder] = false;
|
||||
runout.enabled = false;
|
||||
runout.reset();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
}
|
||||
|
||||
// Accessors
|
||||
static uint16_t pixels() { return adaneo1.numPixels() * TERN1(NEOPIXEL2_INSERIES, 2); }
|
||||
static uint16_t pixels() { return MUL_TERN(NEOPIXEL2_INSERIES, adaneo1.numPixels(), 2); }
|
||||
|
||||
static uint32_t pixel_color(const uint16_t n) {
|
||||
#if ENABLED(NEOPIXEL2_INSERIES)
|
||||
|
||||
@@ -76,7 +76,7 @@ MMU2 mmu2;
|
||||
#define MMU2_NO_TOOL 99
|
||||
#define MMU_BAUD 115200
|
||||
|
||||
bool MMU2::_enabled, MMU2::ready, MMU2::mmu_print_saved;
|
||||
bool MMU2::_enabled, MMU2::ready;
|
||||
#if HAS_PRUSA_MMU2S
|
||||
bool MMU2::mmu2s_triggered;
|
||||
#endif
|
||||
@@ -84,7 +84,6 @@ uint8_t MMU2::cmd, MMU2::cmd_arg, MMU2::last_cmd, MMU2::extruder;
|
||||
int8_t MMU2::state = 0;
|
||||
volatile int8_t MMU2::finda = 1;
|
||||
volatile bool MMU2::finda_runout_valid;
|
||||
int16_t MMU2::version = -1, MMU2::buildnr = -1;
|
||||
millis_t MMU2::prev_request, MMU2::prev_P0_request;
|
||||
char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
|
||||
|
||||
@@ -93,14 +92,11 @@ struct E_Step {
|
||||
feedRate_t feedRate; //!< feed rate in mm/s
|
||||
};
|
||||
|
||||
static constexpr E_Step
|
||||
ramming_sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE }
|
||||
, load_to_nozzle_sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE }
|
||||
#if HAS_PRUSA_MMU2S
|
||||
, can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE }
|
||||
, can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE }
|
||||
#endif
|
||||
;
|
||||
inline void unscaled_mmu2_e_move(const float &dist, const feedRate_t fr_mm_s, const bool sync=true) {
|
||||
current_position.e += dist / planner.e_factor[active_extruder];
|
||||
line_to_current_position(fr_mm_s);
|
||||
if (sync) planner.synchronize();
|
||||
}
|
||||
|
||||
MMU2::MMU2() {
|
||||
rx_buffer[0] = '\0';
|
||||
@@ -136,12 +132,12 @@ void MMU2::reset() {
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t MMU2::get_current_tool() {
|
||||
return extruder == MMU2_NO_TOOL ? -1 : extruder;
|
||||
}
|
||||
int8_t MMU2::get_current_tool() { return extruder == MMU2_NO_TOOL ? -1 : extruder; }
|
||||
|
||||
#if EITHER(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR)
|
||||
#define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != runout.out_state())
|
||||
#if ANY(HAS_PRUSA_MMU2S, MMU_EXTRUDER_SENSOR)
|
||||
#define FILAMENT_PRESENT() (READ(FIL_RUNOUT1_PIN) != FIL_RUNOUT1_STATE)
|
||||
#else
|
||||
#define FILAMENT_PRESENT() true
|
||||
#endif
|
||||
|
||||
void mmu2_attn_buzz(const bool two=false) {
|
||||
@@ -149,6 +145,7 @@ void mmu2_attn_buzz(const bool two=false) {
|
||||
if (two) { BUZZ(10, 0); BUZZ(200, 404); }
|
||||
}
|
||||
|
||||
// Avoiding sscanf significantly reduces build size
|
||||
void MMU2::mmu_loop() {
|
||||
|
||||
switch (state) {
|
||||
@@ -163,7 +160,7 @@ void MMU2::mmu_loop() {
|
||||
MMU2_SEND("S1"); // Read Version
|
||||
state = -2;
|
||||
}
|
||||
else if (millis() > 30000) { // 30sec after reset disable MMU
|
||||
else if (ELAPSED(millis(), prev_request + 30000)) { // 30sec after reset disable MMU
|
||||
SERIAL_ECHOLNPGM("MMU not responding - DISABLED");
|
||||
state = 0;
|
||||
}
|
||||
@@ -171,7 +168,7 @@ void MMU2::mmu_loop() {
|
||||
|
||||
case -2:
|
||||
if (rx_ok()) {
|
||||
sscanf(rx_buffer, "%huok\n", &version);
|
||||
const uint16_t version = uint16_t(strtoul(rx_buffer, nullptr, 10));
|
||||
DEBUG_ECHOLNPGM("MMU => ", version, "\nMMU <= 'S2'");
|
||||
MMU2_SEND("S2"); // Read Build Number
|
||||
state = -3;
|
||||
@@ -180,17 +177,15 @@ void MMU2::mmu_loop() {
|
||||
|
||||
case -3:
|
||||
if (rx_ok()) {
|
||||
sscanf(rx_buffer, "%huok\n", &buildnr);
|
||||
|
||||
const uint16_t buildnr = uint16_t(strtoul(rx_buffer, nullptr, 10));
|
||||
DEBUG_ECHOLNPGM("MMU => ", buildnr);
|
||||
|
||||
check_version();
|
||||
check_version(buildnr);
|
||||
|
||||
#if ENABLED(MMU2_MODE_12V)
|
||||
DEBUG_ECHOLNPGM("MMU <= 'M1'");
|
||||
MMU2_SEND("M1"); // Stealth Mode
|
||||
state = -5;
|
||||
|
||||
#else
|
||||
DEBUG_ECHOLNPGM("MMU <= 'P0'");
|
||||
MMU2_SEND("P0"); // Read FINDA
|
||||
@@ -200,20 +195,21 @@ void MMU2::mmu_loop() {
|
||||
break;
|
||||
|
||||
#if ENABLED(MMU2_MODE_12V)
|
||||
case -5:
|
||||
// response to M1
|
||||
if (rx_ok()) {
|
||||
DEBUG_ECHOLNPGM("MMU => ok");
|
||||
DEBUG_ECHOLNPGM("MMU <= 'P0'");
|
||||
MMU2_SEND("P0"); // Read FINDA
|
||||
state = -4;
|
||||
}
|
||||
break;
|
||||
case -5:
|
||||
// response to M1
|
||||
if (rx_ok()) {
|
||||
DEBUG_ECHOLNPGM("MMU => ok");
|
||||
DEBUG_ECHOLNPGM("MMU <= 'P0'");
|
||||
MMU2_SEND("P0"); // Read FINDA
|
||||
state = -4;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case -4:
|
||||
if (rx_ok()) {
|
||||
sscanf(rx_buffer, "%hhuok\n", &finda);
|
||||
const uint8_t findex = uint8_t(rx_buffer[0] - '0');
|
||||
if (findex <= 1) finda = findex;
|
||||
|
||||
DEBUG_ECHOLNPGM("MMU => ", finda, "\nMMU - ENABLED");
|
||||
|
||||
@@ -286,10 +282,11 @@ void MMU2::mmu_loop() {
|
||||
|
||||
case 2: // response to command P0
|
||||
if (rx_ok()) {
|
||||
sscanf(rx_buffer, "%hhuok\n", &finda);
|
||||
const uint8_t findex = uint8_t(rx_buffer[0] - '0');
|
||||
if (findex <= 1) finda = findex;
|
||||
|
||||
// This is super annoying. Only activate if necessary
|
||||
// if (finda_runout_valid) DEBUG_ECHOLNPAIR_F("MMU <= 'P0'\nMMU => ", finda, 6);
|
||||
//if (finda_runout_valid) DEBUG_ECHOLNPGM("MMU <= 'P0'\nMMU => ", p_float_t(finda, 6));
|
||||
|
||||
if (!finda && finda_runout_valid) filament_runout();
|
||||
if (cmd == MMU_CMD_NONE) ready = true;
|
||||
@@ -406,7 +403,7 @@ void MMU2::tx_str(FSTR_P fstr) {
|
||||
void MMU2::tx_printf(FSTR_P format, int argument = -1) {
|
||||
clear_rx_buffer();
|
||||
const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument);
|
||||
LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]);
|
||||
for (uint8_t i = 0; i < len; ++i) MMU2_SERIAL.write(tx_buffer[i]);
|
||||
prev_request = millis();
|
||||
}
|
||||
|
||||
@@ -416,7 +413,7 @@ void MMU2::tx_printf(FSTR_P format, int argument = -1) {
|
||||
void MMU2::tx_printf(FSTR_P format, int argument1, int argument2) {
|
||||
clear_rx_buffer();
|
||||
const uint8_t len = sprintf_P(tx_buffer, FTOP(format), argument1, argument2);
|
||||
LOOP_L_N(i, len) MMU2_SERIAL.write(tx_buffer[i]);
|
||||
for (uint8_t i = 0; i < len; ++i) MMU2_SERIAL.write(tx_buffer[i]);
|
||||
prev_request = millis();
|
||||
}
|
||||
|
||||
@@ -442,7 +439,7 @@ bool MMU2::rx_ok() {
|
||||
/**
|
||||
* Check if MMU has compatible firmware
|
||||
*/
|
||||
void MMU2::check_version() {
|
||||
void MMU2::check_version(const uint16_t buildnr) {
|
||||
if (buildnr < MMU_REQUIRED_FW_BUILDNR) {
|
||||
SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required.");
|
||||
kill(GET_TEXT_F(MSG_KILL_MMU2_FIRMWARE));
|
||||
@@ -458,12 +455,19 @@ static void mmu2_not_responding() {
|
||||
BUZZ(100, 659);
|
||||
}
|
||||
|
||||
inline void beep_bad_cmd() { BUZZ(400, 40); }
|
||||
|
||||
#if HAS_PRUSA_MMU2S
|
||||
|
||||
/**
|
||||
* Load filament until the sensor at the gears is triggered
|
||||
* and give up after a number of attempts set with MMU2_C0_RETRY.
|
||||
* Each try has a timeout before returning a fail state.
|
||||
*/
|
||||
bool MMU2::load_to_gears() {
|
||||
command(MMU_CMD_C0);
|
||||
manage_response(true, true);
|
||||
LOOP_L_N(i, MMU2_C0_RETRY) { // Keep loading until filament reaches gears
|
||||
for (uint8_t i = 0; i < MMU2_C0_RETRY; ++i) { // Keep loading until filament reaches gears
|
||||
if (mmu2s_triggered) break;
|
||||
command(MMU_CMD_C0);
|
||||
manage_response(true, true);
|
||||
@@ -484,6 +488,11 @@ static void mmu2_not_responding() {
|
||||
set_runout_valid(false);
|
||||
|
||||
if (index != extruder) {
|
||||
if (ENABLED(MMU_IR_UNLOAD_MOVE) && FILAMENT_PRESENT()) {
|
||||
DEBUG_ECHOLNPGM("Unloading\n");
|
||||
while (FILAMENT_PRESENT()) // Filament present? Keep unloading.
|
||||
unscaled_mmu2_e_move(-0.25, MMM_TO_MMS(120)); // 0.25mm is a guessed value. Adjust to preference.
|
||||
}
|
||||
|
||||
stepper.disable_extruder();
|
||||
ui.status_printf(0, GET_TEXT_F(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
|
||||
@@ -520,9 +529,9 @@ static void mmu2_not_responding() {
|
||||
#if ENABLED(MMU2_MENUS)
|
||||
const uint8_t index = mmu2_choose_filament();
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
|
||||
load_filament_to_nozzle(index);
|
||||
load_to_nozzle(index);
|
||||
#else
|
||||
ERR_BUZZ();
|
||||
beep_bad_cmd();
|
||||
#endif
|
||||
} break;
|
||||
|
||||
@@ -541,13 +550,13 @@ static void mmu2_not_responding() {
|
||||
active_extruder = 0;
|
||||
}
|
||||
#else
|
||||
ERR_BUZZ();
|
||||
beep_bad_cmd();
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case 'c': {
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
|
||||
load_to_nozzle();
|
||||
load_to_nozzle_sequence();
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -608,9 +617,9 @@ static void mmu2_not_responding() {
|
||||
#if ENABLED(MMU2_MENUS)
|
||||
uint8_t index = mmu2_choose_filament();
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
|
||||
load_filament_to_nozzle(index);
|
||||
load_to_nozzle(index);
|
||||
#else
|
||||
ERR_BUZZ();
|
||||
beep_bad_cmd();
|
||||
#endif
|
||||
} break;
|
||||
|
||||
@@ -630,14 +639,14 @@ static void mmu2_not_responding() {
|
||||
extruder = index;
|
||||
active_extruder = 0;
|
||||
#else
|
||||
ERR_BUZZ();
|
||||
beep_bad_cmd();
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case 'c': {
|
||||
DEBUG_ECHOLNPGM("case c\n");
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
|
||||
execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
|
||||
load_to_nozzle_sequence();
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -723,9 +732,9 @@ static void mmu2_not_responding() {
|
||||
#if ENABLED(MMU2_MENUS)
|
||||
uint8_t index = mmu2_choose_filament();
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
|
||||
load_filament_to_nozzle(index);
|
||||
load_to_nozzle(index);
|
||||
#else
|
||||
ERR_BUZZ();
|
||||
beep_bad_cmd();
|
||||
#endif
|
||||
} break;
|
||||
|
||||
@@ -744,14 +753,14 @@ static void mmu2_not_responding() {
|
||||
extruder = index;
|
||||
active_extruder = 0;
|
||||
#else
|
||||
ERR_BUZZ();
|
||||
beep_bad_cmd();
|
||||
#endif
|
||||
} break;
|
||||
|
||||
case 'c': {
|
||||
DEBUG_ECHOLNPGM("case c\n");
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(100);
|
||||
execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
|
||||
load_to_nozzle_sequence();
|
||||
} break;
|
||||
}
|
||||
|
||||
@@ -792,8 +801,7 @@ bool MMU2::get_response() {
|
||||
void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||
|
||||
constexpr xyz_pos_t park_point = NOZZLE_PARK_POINT;
|
||||
bool response = false;
|
||||
mmu_print_saved = false;
|
||||
bool response = false, mmu_print_saved = false;
|
||||
xyz_pos_t resume_position;
|
||||
celsius_t resume_hotend_temp = thermalManager.degTargetHotend(active_extruder);
|
||||
|
||||
@@ -815,8 +823,7 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||
resume_hotend_temp = thermalManager.degTargetHotend(active_extruder);
|
||||
resume_position = current_position;
|
||||
|
||||
if (move_axes && all_axes_homed())
|
||||
nozzle.park(0, park_point /*= NOZZLE_PARK_POINT*/);
|
||||
if (move_axes && all_axes_homed()) nozzle.park(0, park_point);
|
||||
|
||||
if (turn_off_nozzle) thermalManager.setTargetHotend(0, active_extruder);
|
||||
|
||||
@@ -824,13 +831,12 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||
}
|
||||
}
|
||||
else if (mmu_print_saved) {
|
||||
SERIAL_ECHOLNPGM("MMU starts responding\n");
|
||||
SERIAL_ECHOLNPGM("\nMMU starts responding");
|
||||
|
||||
if (turn_off_nozzle && resume_hotend_temp) {
|
||||
thermalManager.setTargetHotend(resume_hotend_temp, active_extruder);
|
||||
LCD_MESSAGE(MSG_HEATING);
|
||||
ERR_BUZZ();
|
||||
|
||||
while (!thermalManager.wait_for_hotend(active_extruder, false)) safe_delay(1000);
|
||||
}
|
||||
|
||||
@@ -843,7 +849,6 @@ void MMU2::manage_response(const bool move_axes, const bool turn_off_nozzle) {
|
||||
if (move_axes && all_axes_homed()) {
|
||||
// Move XY to starting position, then Z
|
||||
do_blocking_move_to_xy(resume_position, feedRate_t(NOZZLE_PARK_XY_FEEDRATE));
|
||||
|
||||
// Move Z_AXIS to saved position
|
||||
do_blocking_move_to_z(resume_position.z, feedRate_t(NOZZLE_PARK_Z_FEEDRATE));
|
||||
}
|
||||
@@ -878,23 +883,24 @@ void MMU2::filament_runout() {
|
||||
}
|
||||
// Slowly spin the extruder during C0
|
||||
else {
|
||||
while (planner.movesplanned() < 3) {
|
||||
current_position.e += 0.25;
|
||||
line_to_current_position(MMM_TO_MMS(120));
|
||||
}
|
||||
while (planner.movesplanned() < 3)
|
||||
unscaled_mmu2_e_move(0.25, MMM_TO_MMS(120), false);
|
||||
}
|
||||
}
|
||||
mmu2s_triggered = present;
|
||||
}
|
||||
|
||||
bool MMU2::can_load() {
|
||||
execute_extruder_sequence((const E_Step *)can_load_sequence, COUNT(can_load_sequence));
|
||||
static const E_Step can_load_sequence[] PROGMEM = { MMU2_CAN_LOAD_SEQUENCE },
|
||||
can_load_increment_sequence[] PROGMEM = { MMU2_CAN_LOAD_INCREMENT_SEQUENCE };
|
||||
|
||||
execute_extruder_sequence(can_load_sequence, COUNT(can_load_sequence));
|
||||
|
||||
int filament_detected_count = 0;
|
||||
const int steps = (MMU2_CAN_LOAD_RETRACT) / (MMU2_CAN_LOAD_INCREMENT);
|
||||
DEBUG_ECHOLNPGM("MMU can_load:");
|
||||
LOOP_L_N(i, steps) {
|
||||
execute_extruder_sequence((const E_Step *)can_load_increment_sequence, COUNT(can_load_increment_sequence));
|
||||
for (uint8_t i = 0; i < steps; ++i) {
|
||||
execute_extruder_sequence(can_load_increment_sequence, COUNT(can_load_increment_sequence));
|
||||
check_filament(); // Don't trust the idle function
|
||||
DEBUG_CHAR(mmu2s_triggered ? 'O' : 'o');
|
||||
if (mmu2s_triggered) ++filament_detected_count;
|
||||
@@ -912,7 +918,7 @@ void MMU2::filament_runout() {
|
||||
#endif
|
||||
|
||||
// Load filament into MMU2
|
||||
void MMU2::load_filament(const uint8_t index) {
|
||||
void MMU2::load_to_feeder(const uint8_t index) {
|
||||
if (!_enabled) return;
|
||||
|
||||
command(MMU_CMD_L0 + index);
|
||||
@@ -923,8 +929,7 @@ void MMU2::load_filament(const uint8_t index) {
|
||||
/**
|
||||
* Switch material and load to nozzle
|
||||
*/
|
||||
bool MMU2::load_filament_to_nozzle(const uint8_t index) {
|
||||
|
||||
bool MMU2::load_to_nozzle(const uint8_t index) {
|
||||
if (!_enabled) return false;
|
||||
|
||||
if (thermalManager.tooColdToExtrude(active_extruder)) {
|
||||
@@ -933,6 +938,13 @@ bool MMU2::load_filament_to_nozzle(const uint8_t index) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (TERN0(MMU_IR_UNLOAD_MOVE, index != extruder) && FILAMENT_PRESENT()) {
|
||||
DEBUG_ECHOLNPGM("Unloading\n");
|
||||
ramming_sequence(); // Unloading instructions from printer side when operating LCD
|
||||
while (FILAMENT_PRESENT()) // Filament present? Keep unloading.
|
||||
unscaled_mmu2_e_move(-0.25, MMM_TO_MMS(120)); // 0.25mm is a guessed value. Adjust to preference.
|
||||
}
|
||||
|
||||
stepper.disable_extruder();
|
||||
command(MMU_CMD_T0 + index);
|
||||
manage_response(true, true);
|
||||
@@ -942,23 +954,12 @@ bool MMU2::load_filament_to_nozzle(const uint8_t index) {
|
||||
mmu_loop();
|
||||
extruder = index;
|
||||
active_extruder = 0;
|
||||
load_to_nozzle();
|
||||
load_to_nozzle_sequence();
|
||||
mmu2_attn_buzz();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load filament to nozzle of multimaterial printer
|
||||
*
|
||||
* This function is used only after T? (user select filament) and M600 (change filament).
|
||||
* It is not used after T0 .. T4 command (select filament), in such case, G-code is responsible for loading
|
||||
* filament to nozzle.
|
||||
*/
|
||||
void MMU2::load_to_nozzle() {
|
||||
execute_extruder_sequence((const E_Step *)load_to_nozzle_sequence, COUNT(load_to_nozzle_sequence));
|
||||
}
|
||||
|
||||
bool MMU2::eject_filament(const uint8_t index, const bool recover) {
|
||||
|
||||
if (!_enabled) return false;
|
||||
@@ -971,20 +972,17 @@ bool MMU2::eject_filament(const uint8_t index, const bool recover) {
|
||||
|
||||
LCD_MESSAGE(MSG_MMU2_EJECTING_FILAMENT);
|
||||
|
||||
stepper.enable_extruder();
|
||||
current_position.e -= MMU2_FILAMENTCHANGE_EJECT_FEED;
|
||||
line_to_current_position(MMM_TO_MMS(2500));
|
||||
planner.synchronize();
|
||||
unscaled_mmu2_e_move(-(MMU2_FILAMENTCHANGE_EJECT_FEED), MMM_TO_MMS(2500));
|
||||
command(MMU_CMD_E0 + index);
|
||||
manage_response(false, false);
|
||||
|
||||
if (recover) {
|
||||
LCD_MESSAGE(MSG_MMU2_EJECT_RECOVER);
|
||||
LCD_MESSAGE(MSG_MMU2_REMOVE_AND_CLICK);
|
||||
mmu2_attn_buzz();
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, F("MMU2 Eject Recover"), FPSTR(CONTINUE_STR)));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("MMU2 Eject Recover")));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_MMU2_EJECT_RECOVER)));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_MMU2_EJECT_RECOVER)));
|
||||
TERN_(HAS_RESUME_CONTINUE, wait_for_user_response());
|
||||
mmu2_attn_buzz(true);
|
||||
mmu2_attn_buzz();
|
||||
|
||||
command(MMU_CMD_R0);
|
||||
manage_response(false, false);
|
||||
@@ -1018,7 +1016,7 @@ bool MMU2::unload() {
|
||||
}
|
||||
|
||||
// Unload sequence to optimize shape of the tip of the unloaded filament
|
||||
execute_extruder_sequence((const E_Step *)ramming_sequence, sizeof(ramming_sequence) / sizeof(E_Step));
|
||||
ramming_sequence();
|
||||
|
||||
command(MMU_CMD_U0);
|
||||
manage_response(false, true);
|
||||
@@ -1033,23 +1031,26 @@ bool MMU2::unload() {
|
||||
return true;
|
||||
}
|
||||
|
||||
void MMU2::ramming_sequence() {
|
||||
static const E_Step sequence[] PROGMEM = { MMU2_RAMMING_SEQUENCE };
|
||||
execute_extruder_sequence(sequence, COUNT(sequence));
|
||||
}
|
||||
|
||||
void MMU2::load_to_nozzle_sequence() {
|
||||
static const E_Step sequence[] PROGMEM = { MMU2_LOAD_TO_NOZZLE_SEQUENCE };
|
||||
execute_extruder_sequence(sequence, COUNT(sequence));
|
||||
}
|
||||
|
||||
void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
|
||||
|
||||
planner.synchronize();
|
||||
stepper.enable_extruder();
|
||||
|
||||
const E_Step* step = sequence;
|
||||
const E_Step *step = sequence;
|
||||
|
||||
LOOP_L_N(i, steps) {
|
||||
for (uint8_t i = 0; i < steps; ++i) {
|
||||
const float es = pgm_read_float(&(step->extrude));
|
||||
const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
|
||||
|
||||
DEBUG_ECHO_MSG("E step ", es, "/", fr_mm_m);
|
||||
|
||||
current_position.e += es;
|
||||
line_to_current_position(MMM_TO_MMS(fr_mm_m));
|
||||
planner.synchronize();
|
||||
|
||||
unscaled_mmu2_e_move(es, MMM_TO_MMS(fr_mm_m));
|
||||
step++;
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
/**
|
||||
* feature/pause.cpp - Pause feature support functions
|
||||
* This may be combined with related G-codes if features are consolidated.
|
||||
*
|
||||
* Note: Calls to ui.pause_show_message are passed to either ExtUI or MarlinUI.
|
||||
*/
|
||||
|
||||
#include "../inc/MarlinConfigPre.h"
|
||||
@@ -60,8 +62,6 @@
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "../lcd/extui/ui_api.h"
|
||||
#elif ENABLED(DWIN_LCD_PROUI)
|
||||
#include "../lcd/e3v2/proui/dwin.h"
|
||||
#endif
|
||||
|
||||
#include "../lcd/marlinui.h"
|
||||
@@ -89,9 +89,11 @@ static xyze_pos_t resume_position;
|
||||
PauseMode pause_mode = PAUSE_MODE_PAUSE_PRINT;
|
||||
#endif
|
||||
|
||||
fil_change_settings_t fc_settings[EXTRUDERS];
|
||||
#if ENABLED(CONFIGURE_FILAMENT_CHANGE)
|
||||
fil_change_settings_t fc_settings[EXTRUDERS];
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if HAS_MEDIA
|
||||
#include "../sd/cardreader.h"
|
||||
#endif
|
||||
|
||||
@@ -146,7 +148,7 @@ static bool ensure_safe_temperature(const bool wait=true, const PauseMode mode=P
|
||||
thermalManager.setTargetHotend(thermalManager.extrude_min_temp, active_extruder);
|
||||
#endif
|
||||
|
||||
ui.pause_show_message(PAUSE_MESSAGE_HEATING, mode); UNUSED(mode);
|
||||
ui.pause_show_message(PAUSE_MESSAGE_HEATING, mode);
|
||||
|
||||
if (wait) return thermalManager.wait_for_hotend(active_extruder);
|
||||
|
||||
@@ -201,7 +203,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
wait_for_user = true; // LCD click or M108 will clear this
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(F("Load Filament")));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENTLOAD)));
|
||||
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, active_extruder);
|
||||
@@ -210,23 +212,14 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
||||
|
||||
while (wait_for_user) {
|
||||
impatient_beep(max_beep_count);
|
||||
#if BOTH(FILAMENT_CHANGE_RESUME_ON_INSERT, FILAMENT_RUNOUT_SENSOR)
|
||||
#if ALL(FILAMENT_CHANGE_RESUME_ON_INSERT, FILAMENT_RUNOUT_SENSOR)
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
LOOP_S_LE_N(i, 1, NUM_RUNOUT_SENSORS) {
|
||||
pin_t pin;
|
||||
switch (i) {
|
||||
default: continue;
|
||||
#define _CASE_RUNOUT(N) case N: pin = FIL_RUNOUT##N##_PIN; break;
|
||||
REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_RUNOUT)
|
||||
#undef _CASE_RUNOUT
|
||||
}
|
||||
const RunoutMode rm = runout.mode[i - 1];
|
||||
if (rm != RM_NONE && rm != RM_MOTION_SENSOR && extDigitalRead(pin) != runout.out_state(i - 1))
|
||||
wait_for_user = false;
|
||||
#define _CASE_INSERTED(N) case N-1: if (READ(FIL_RUNOUT##N##_PIN) != FIL_RUNOUT##N##_STATE) wait_for_user = false; break;
|
||||
switch (active_extruder) {
|
||||
REPEAT_1(NUM_RUNOUT_SENSORS, _CASE_INSERTED)
|
||||
}
|
||||
#else
|
||||
if (READ(FIL_RUNOUT_PIN) != runout.out_state(active_extruder))
|
||||
wait_for_user = false;
|
||||
if (READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_STATE) wait_for_user = false;
|
||||
#endif
|
||||
#endif
|
||||
idle_no_sleep();
|
||||
@@ -243,6 +236,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
||||
|
||||
TERN_(BELTPRINTER, do_blocking_move_to_xy(0.00, 50.00));
|
||||
|
||||
TERN_(MPCTEMP, MPC::e_paused = true);
|
||||
|
||||
// Slow Load filament
|
||||
if (slow_load_length) unscaled_e_move(slow_load_length, FILAMENT_CHANGE_SLOW_LOAD_FEEDRATE);
|
||||
|
||||
@@ -269,7 +264,7 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
||||
if (show_lcd) ui.pause_show_message(PAUSE_MESSAGE_PURGE);
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE)));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE), FPSTR(CONTINUE_STR)));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_FILAMENT_CHANGE_PURGE)));
|
||||
wait_for_user = true; // A click or M108 breaks the purge_length loop
|
||||
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
|
||||
unscaled_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
|
||||
@@ -293,8 +288,8 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
||||
// Show "Purge More" / "Resume" menu and wait for reply
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
wait_for_user = false;
|
||||
#if EITHER(HAS_MARLINUI_MENU, DWIN_LCD_PROUI)
|
||||
ui.pause_show_message(PAUSE_MESSAGE_OPTION); // Also sets PAUSE_RESPONSE_WAIT_FOR
|
||||
#if ANY(HAS_MARLINUI_MENU, EXTENSIBLE_UI)
|
||||
ui.pause_show_message(PAUSE_MESSAGE_OPTION); // MarlinUI and MKS UI also set PAUSE_RESPONSE_WAIT_FOR
|
||||
#else
|
||||
pause_menu_response = PAUSE_RESPONSE_WAIT_FOR;
|
||||
#endif
|
||||
@@ -306,6 +301,9 @@ bool load_filament(const_float_t slow_load_length/*=0*/, const_float_t fast_load
|
||||
} while (TERN0(M600_PURGE_MORE_RESUMABLE, pause_menu_response == PAUSE_RESPONSE_EXTRUDE_MORE));
|
||||
|
||||
#endif
|
||||
|
||||
TERN_(MPCTEMP, MPC::e_paused = false);
|
||||
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_end());
|
||||
|
||||
return true;
|
||||
@@ -335,18 +333,18 @@ inline void disable_active_extruder() {
|
||||
*/
|
||||
bool unload_filament(const_float_t unload_length, const bool show_lcd/*=false*/,
|
||||
const PauseMode mode/*=PAUSE_MODE_PAUSE_PRINT*/
|
||||
#if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
#if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
, const_float_t mix_multiplier/*=1.0*/
|
||||
#endif
|
||||
) {
|
||||
DEBUG_SECTION(uf, "unload_filament", true);
|
||||
DEBUG_ECHOLNPGM("... unloadlen:", unload_length, " showlcd:", show_lcd, " mode:", mode
|
||||
#if BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
#if ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
, " mixmult:", mix_multiplier
|
||||
#endif
|
||||
);
|
||||
|
||||
#if !BOTH(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
#if !ALL(FILAMENT_UNLOAD_ALL_EXTRUDERS, MIXING_EXTRUDER)
|
||||
constexpr float mix_multiplier = 1.0f;
|
||||
#endif
|
||||
|
||||
@@ -406,8 +404,6 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
|
||||
DEBUG_SECTION(pp, "pause_print", true);
|
||||
DEBUG_ECHOLNPGM("... park.x:", park_point.x, " y:", park_point.y, " z:", park_point.z, " unloadlen:", unload_length, " showlcd:", show_lcd DXC_SAY);
|
||||
|
||||
UNUSED(show_lcd);
|
||||
|
||||
if (did_pause_print) return false; // already paused
|
||||
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
@@ -419,13 +415,12 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
|
||||
#endif
|
||||
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_open(PROMPT_INFO, F("Pause"), FPSTR(DISMISS_STR)));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_Print_Pause());
|
||||
|
||||
// Indicate that the printer is paused
|
||||
++did_pause_print;
|
||||
|
||||
// Pause the print job and timer
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if HAS_MEDIA
|
||||
const bool was_sd_printing = IS_SD_PRINTING();
|
||||
if (was_sd_printing) {
|
||||
card.pauseSDPrint();
|
||||
@@ -450,7 +445,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
|
||||
// Wait for buffered blocks to complete
|
||||
planner.synchronize();
|
||||
|
||||
#if ENABLED(ADVANCED_PAUSE_FANS_PAUSE) && HAS_FAN
|
||||
#if ALL(ADVANCED_PAUSE_FANS_PAUSE, HAS_FAN)
|
||||
thermalManager.set_fans_paused(true);
|
||||
#endif
|
||||
|
||||
@@ -470,6 +465,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
|
||||
|
||||
// If axes don't need to home then the nozzle can park
|
||||
if (do_park) nozzle.park(0, park_point); // Park the nozzle by doing a Minimum Z Raise followed by an XY Move
|
||||
if (!do_park) LCD_MESSAGE(MSG_PARK_FAILED);
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
const int8_t saved_ext = active_extruder;
|
||||
@@ -481,9 +477,7 @@ bool pause_print(const_float_t retract, const xyz_pos_t &park_point, const bool
|
||||
if (unload_length)
|
||||
unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT);
|
||||
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
set_duplication_enabled(saved_ext_dup_mode, saved_ext);
|
||||
#endif
|
||||
TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext));
|
||||
|
||||
// Disable the Extruder for manual change
|
||||
disable_active_extruder();
|
||||
@@ -510,7 +504,7 @@ void show_continue_prompt(const bool is_reload) {
|
||||
|
||||
ui.pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING);
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOF(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n"));
|
||||
SERIAL_ECHO(is_reload ? F(_PMSG(STR_FILAMENT_CHANGE_INSERT) "\n") : F(_PMSG(STR_FILAMENT_CHANGE_WAIT) "\n"));
|
||||
}
|
||||
|
||||
void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep_count/*=0*/ DXC_ARGS) {
|
||||
@@ -536,7 +530,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
|
||||
// Wait for filament insert by user and press button
|
||||
KEEPALIVE_STATE(PAUSED_FOR_USER);
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_NOZZLE_PARKED), FPSTR(CONTINUE_STR)));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_NOZZLE_PARKED)));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_NOZZLE_PARKED)));
|
||||
wait_for_user = true; // LCD click or M108 will clear this
|
||||
while (wait_for_user) {
|
||||
@@ -554,15 +548,17 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_HEATER_TIMEOUT), GET_TEXT_F(MSG_REHEAT)));
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT)));
|
||||
#if ENABLED(TOUCH_UI_FTDI_EVE)
|
||||
ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_FTDI_HEATER_TIMEOUT));
|
||||
#elif ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_HEATER_TIMEOUT));
|
||||
#endif
|
||||
|
||||
TERN_(HAS_RESUME_CONTINUE, wait_for_user_response(0, true)); // Wait for LCD click or M108
|
||||
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_INFO, GET_TEXT_F(MSG_REHEATING)));
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onStatusChanged(GET_TEXT_F(MSG_REHEATING)));
|
||||
|
||||
TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_REHEATING));
|
||||
LCD_MESSAGE(MSG_REHEATING);
|
||||
|
||||
// Re-enable the heaters if they timed out
|
||||
HOTEND_LOOP() thermalManager.reset_hotend_idle_timer(e);
|
||||
@@ -578,9 +574,12 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
|
||||
HOTEND_LOOP() thermalManager.heater_idle[e].start(nozzle_timeout);
|
||||
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.prompt_do(PROMPT_USER_CONTINUE, GET_TEXT_F(MSG_REHEATDONE), FPSTR(CONTINUE_STR)));
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_REHEATDONE)));
|
||||
TERN_(DWIN_LCD_PROUI, LCD_MESSAGE(MSG_REHEATDONE));
|
||||
TERN_(HOST_PROMPT_SUPPORT, hostui.continue_prompt(GET_TEXT_F(MSG_REHEATDONE)));
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
ExtUI::onUserConfirmRequired(GET_TEXT_F(MSG_REHEATDONE));
|
||||
#else
|
||||
LCD_MESSAGE(MSG_REHEATDONE);
|
||||
#endif
|
||||
|
||||
IF_DISABLED(PAUSE_REHEAT_FAST_RESUME, wait_for_user = true);
|
||||
|
||||
@@ -589,9 +588,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
|
||||
}
|
||||
idle_no_sleep();
|
||||
}
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
set_duplication_enabled(saved_ext_dup_mode, saved_ext);
|
||||
#endif
|
||||
TERN_(DUAL_X_CARRIAGE, set_duplication_enabled(saved_ext_dup_mode, saved_ext));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -708,7 +705,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
|
||||
// Resume the print job timer if it was running
|
||||
if (print_job_timer.isPaused()) print_job_timer.start();
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if HAS_MEDIA
|
||||
if (did_pause_print) {
|
||||
--did_pause_print;
|
||||
card.startOrResumeFilePrinting();
|
||||
@@ -723,13 +720,8 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
|
||||
|
||||
TERN_(HAS_FILAMENT_SENSOR, runout.reset());
|
||||
|
||||
#if ENABLED(DWIN_LCD_PROUI)
|
||||
DWIN_Print_Resume();
|
||||
HMI_ReturnScreen();
|
||||
#else
|
||||
ui.reset_status();
|
||||
ui.return_to_status();
|
||||
#endif
|
||||
ui.reset_status();
|
||||
ui.return_to_status();
|
||||
}
|
||||
|
||||
#endif // ADVANCED_PAUSE_FEATURE
|
||||
|
||||
@@ -32,23 +32,28 @@
|
||||
|
||||
FilamentMonitor runout;
|
||||
|
||||
bool FilamentMonitorBase::enabled[NUM_RUNOUT_SENSORS], // Initialized by settings.load
|
||||
FilamentMonitorBase::filament_ran_out; // = false
|
||||
RunoutMode FilamentMonitorBase::mode[NUM_RUNOUT_SENSORS]; // Initialized by settings.load
|
||||
bool FilamentMonitorBase::enabled = true,
|
||||
FilamentMonitorBase::filament_ran_out; // = false
|
||||
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
bool FilamentMonitorBase::host_handling; // = false
|
||||
#endif
|
||||
|
||||
#if ENABLED(TOOLCHANGE_MIGRATION_FEATURE)
|
||||
#define DEBUG_TOOLCHANGE_MIGRATION_FEATURE
|
||||
#include "../module/tool_change.h"
|
||||
#define DEBUG_OUT ENABLED(DEBUG_TOOLCHANGE_MIGRATION_FEATURE)
|
||||
#include "../core/debug_out.h"
|
||||
#endif
|
||||
|
||||
float RunoutResponseDelayed::runout_distance_mm[NUM_RUNOUT_SENSORS]; // Initialized by settings.load
|
||||
volatile float RunoutResponseDelayed::runout_mm_countdown[NUM_RUNOUT_SENSORS];
|
||||
uint8_t FilamentSensorCore::motion_detected;
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
float RunoutResponseDelayed::runout_distance_mm = FILAMENT_RUNOUT_DISTANCE_MM;
|
||||
countdown_t RunoutResponseDelayed::mm_countdown;
|
||||
#if ENABLED(FILAMENT_MOTION_SENSOR)
|
||||
uint8_t FilamentSensorEncoder::motion_detected;
|
||||
#endif
|
||||
#else
|
||||
int8_t RunoutResponseDebounced::runout_count[NUM_RUNOUT_SENSORS]; // = 0
|
||||
#endif
|
||||
|
||||
//
|
||||
// Filament Runout event handler
|
||||
@@ -63,8 +68,6 @@ uint8_t FilamentSensorCore::motion_detected;
|
||||
|
||||
#if ENABLED(EXTENSIBLE_UI)
|
||||
#include "../lcd/extui/ui_api.h"
|
||||
#elif ENABLED(DWIN_LCD_PROUI)
|
||||
#include "../lcd/e3v2/proui/dwin.h"
|
||||
#endif
|
||||
|
||||
void event_filament_runout(const uint8_t extruder) {
|
||||
@@ -83,7 +86,6 @@ void event_filament_runout(const uint8_t extruder) {
|
||||
#endif
|
||||
|
||||
TERN_(EXTENSIBLE_UI, ExtUI::onFilamentRunout(ExtUI::getTool(extruder)));
|
||||
TERN_(DWIN_LCD_PROUI, DWIN_FilamentRunout(extruder));
|
||||
|
||||
#if ANY(HOST_PROMPT_SUPPORT, HOST_ACTION_COMMANDS, MULTI_FILAMENT_SENSOR)
|
||||
const char tool = '0' + TERN0(MULTI_FILAMENT_SENSOR, extruder);
|
||||
@@ -97,12 +99,16 @@ void event_filament_runout(const uint8_t extruder) {
|
||||
const bool run_runout_script = !runout.host_handling;
|
||||
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
if (run_runout_script
|
||||
&& ( strstr(FILAMENT_RUNOUT_SCRIPT, "M600")
|
||||
|
||||
const bool park_or_pause = (false
|
||||
#ifdef FILAMENT_RUNOUT_SCRIPT
|
||||
|| strstr(FILAMENT_RUNOUT_SCRIPT, "M600")
|
||||
|| strstr(FILAMENT_RUNOUT_SCRIPT, "M125")
|
||||
|| TERN0(ADVANCED_PAUSE_FEATURE, strstr(FILAMENT_RUNOUT_SCRIPT, "M25"))
|
||||
)
|
||||
) {
|
||||
#endif
|
||||
);
|
||||
|
||||
if (run_runout_script && park_or_pause) {
|
||||
hostui.paused(false);
|
||||
}
|
||||
else {
|
||||
@@ -119,24 +125,27 @@ void event_filament_runout(const uint8_t extruder) {
|
||||
SERIAL_ECHOPGM(" " ACTION_REASON_ON_FILAMENT_RUNOUT " ");
|
||||
SERIAL_CHAR(tool);
|
||||
SERIAL_EOL();
|
||||
|
||||
#endif // HOST_ACTION_COMMANDS
|
||||
|
||||
if (run_runout_script) {
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
char script[strlen(FILAMENT_RUNOUT_SCRIPT) + 1];
|
||||
sprintf_P(script, PSTR(FILAMENT_RUNOUT_SCRIPT), tool);
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOLNPGM("Runout Command: ", script);
|
||||
#ifdef FILAMENT_RUNOUT_SCRIPT
|
||||
if (run_runout_script) {
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
MString<strlen(FILAMENT_RUNOUT_SCRIPT)> script;
|
||||
script.setf(F(FILAMENT_RUNOUT_SCRIPT), C(tool));
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOLNPGM("Runout Command: ", &script);
|
||||
#endif
|
||||
queue.inject(&script);
|
||||
#else
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOPGM("Runout Command: ");
|
||||
SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT);
|
||||
#endif
|
||||
queue.inject(F(FILAMENT_RUNOUT_SCRIPT));
|
||||
#endif
|
||||
queue.inject(script);
|
||||
#else
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOPGM("Runout Command: ");
|
||||
SERIAL_ECHOLNPGM(FILAMENT_RUNOUT_SCRIPT);
|
||||
#endif
|
||||
queue.inject(F(FILAMENT_RUNOUT_SCRIPT));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // HAS_FILAMENT_SENSOR
|
||||
|
||||
+305
-164
@@ -30,7 +30,8 @@
|
||||
#include "../module/planner.h"
|
||||
#include "../module/stepper.h" // for block_t
|
||||
#include "../gcode/queue.h"
|
||||
#include "../feature/pause.h"
|
||||
#include "../feature/pause.h" // for did_pause_print
|
||||
#include "../MarlinCore.h" // for printingIsActive()
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
|
||||
@@ -43,41 +44,44 @@
|
||||
#define FILAMENT_RUNOUT_THRESHOLD 5
|
||||
#endif
|
||||
|
||||
#if ENABLED(FILAMENT_MOTION_SENSOR)
|
||||
#define HAS_FILAMENT_MOTION 1
|
||||
#endif
|
||||
#if DISABLED(FILAMENT_MOTION_SENSOR) || ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
#define HAS_FILAMENT_SWITCH 1
|
||||
#endif
|
||||
|
||||
typedef Flags<
|
||||
#if NUM_MOTION_SENSORS > NUM_RUNOUT_SENSORS
|
||||
NUM_MOTION_SENSORS
|
||||
#else
|
||||
NUM_RUNOUT_SENSORS
|
||||
#endif
|
||||
> runout_flags_t;
|
||||
|
||||
void event_filament_runout(const uint8_t extruder);
|
||||
inline bool should_monitor_runout() { return did_pause_print || printingIsActive(); }
|
||||
|
||||
template<class RESPONSE_T, class SENSOR_T>
|
||||
class TFilamentMonitor;
|
||||
class FilamentSensorCore;
|
||||
class FilamentSensor;
|
||||
class RunoutResponseDelayed;
|
||||
class RunoutResponseDebounced;
|
||||
|
||||
/********************************* TEMPLATE SPECIALIZATION *********************************/
|
||||
|
||||
typedef TFilamentMonitor<
|
||||
RunoutResponseDelayed,
|
||||
FilamentSensorCore
|
||||
TERN(HAS_FILAMENT_RUNOUT_DISTANCE, RunoutResponseDelayed, RunoutResponseDebounced),
|
||||
FilamentSensor
|
||||
> FilamentMonitor;
|
||||
|
||||
extern FilamentMonitor runout;
|
||||
|
||||
/*******************************************************************************************/
|
||||
|
||||
enum RunoutMode : uint8_t {
|
||||
RM_NONE,
|
||||
RM_OUT_ON_LOW,
|
||||
RM_OUT_ON_HIGH,
|
||||
RM_RESERVED3,
|
||||
RM_RESERVED4,
|
||||
RM_RESERVED5,
|
||||
RM_RESERVED6,
|
||||
RM_MOTION_SENSOR
|
||||
};
|
||||
|
||||
class FilamentMonitorBase {
|
||||
public:
|
||||
static bool enabled[NUM_RUNOUT_SENSORS], filament_ran_out;
|
||||
static RunoutMode mode[NUM_RUNOUT_SENSORS];
|
||||
|
||||
static uint8_t out_state(const uint8_t e=0) { return mode[e] == RM_OUT_ON_HIGH ? HIGH : LOW; }
|
||||
static bool enabled, filament_ran_out;
|
||||
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
static bool host_handling;
|
||||
@@ -107,14 +111,24 @@ class TFilamentMonitor : public FilamentMonitorBase {
|
||||
|
||||
// Call this method when filament is present,
|
||||
// so the response can reset its counter.
|
||||
static void filament_present(const uint8_t e) { response.filament_present(e); }
|
||||
static float& runout_distance(const uint8_t e=0) { return response.runout_distance_mm[e]; }
|
||||
static void set_runout_distance(const_float_t mm, const uint8_t e=0) { response.runout_distance_mm[e] = mm; }
|
||||
static void filament_present(const uint8_t extruder) {
|
||||
response.filament_present(extruder);
|
||||
}
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
static void filament_motion_present(const uint8_t extruder) {
|
||||
response.filament_motion_present(extruder);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
static float& runout_distance() { return response.runout_distance_mm; }
|
||||
static void set_runout_distance(const_float_t mm) { response.runout_distance_mm = mm; }
|
||||
#endif
|
||||
|
||||
// Handle a block completion. RunoutResponseDelayed uses this to
|
||||
// add up the length of filament moved while the filament is out.
|
||||
static void block_completed(const block_t * const b) {
|
||||
if (enabled[active_extruder]) {
|
||||
if (enabled) {
|
||||
response.block_completed(b);
|
||||
sensor.block_completed(b);
|
||||
}
|
||||
@@ -122,43 +136,33 @@ class TFilamentMonitor : public FilamentMonitorBase {
|
||||
|
||||
// Give the response a chance to update its counter.
|
||||
static void run() {
|
||||
if (enabled[active_extruder] && mode[active_extruder] != RM_NONE && !filament_ran_out && (printingIsActive() || did_pause_print)) {
|
||||
cli(); // Prevent RunoutResponseDelayed::block_completed from accumulating here
|
||||
if (enabled && !filament_ran_out && should_monitor_runout()) {
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, cli()); // Prevent RunoutResponseDelayed::block_completed from accumulating here
|
||||
response.run();
|
||||
sensor.run();
|
||||
const uint8_t runout_flags = response.has_run_out();
|
||||
sei();
|
||||
const runout_flags_t runout_flags = response.has_run_out();
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, sei());
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
#if ENABLED(WATCH_ALL_RUNOUT_SENSORS)
|
||||
const bool ran_out = !!runout_flags; // any sensor triggers
|
||||
const bool ran_out = bool(runout_flags); // any sensor triggers
|
||||
uint8_t extruder = 0;
|
||||
if (ran_out) {
|
||||
uint8_t bitmask = runout_flags;
|
||||
while (!(bitmask & 1)) {
|
||||
bitmask >>= 1;
|
||||
extruder++;
|
||||
}
|
||||
}
|
||||
if (ran_out) while (!runout_flags.test(extruder)) extruder++;
|
||||
#else
|
||||
const bool ran_out = TEST(runout_flags, active_extruder); // suppress non active extruders
|
||||
const bool ran_out = runout_flags[active_extruder]; // suppress non active extruders
|
||||
uint8_t extruder = active_extruder;
|
||||
#endif
|
||||
#else
|
||||
const bool ran_out = !!runout_flags;
|
||||
const bool ran_out = bool(runout_flags);
|
||||
uint8_t extruder = active_extruder;
|
||||
#endif
|
||||
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
if (runout_flags) {
|
||||
SERIAL_ECHOPGM("Runout Sensors: ");
|
||||
LOOP_L_N(i, 8) SERIAL_ECHO('0' + TEST(runout_flags, i));
|
||||
SERIAL_ECHOPGM(" -> ", extruder);
|
||||
if (ran_out) SERIAL_ECHOPGM(" RUN OUT");
|
||||
SERIAL_EOL();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ran_out) {
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
SERIAL_ECHOPGM("Runout Sensors: ");
|
||||
for (uint8_t i = 0; i < 8; ++i) SERIAL_CHAR('0' + char(runout_flags[i]));
|
||||
SERIAL_ECHOLNPGM(" -> ", extruder, " RUN OUT");
|
||||
#endif
|
||||
|
||||
filament_ran_out = true;
|
||||
event_filament_runout(extruder);
|
||||
planner.synchronize();
|
||||
@@ -178,39 +182,26 @@ class FilamentSensorBase {
|
||||
static void filament_present(const uint8_t extruder) {
|
||||
runout.filament_present(extruder); // ...which calls response.filament_present(extruder)
|
||||
}
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
static void filament_motion_present(const uint8_t extruder) {
|
||||
runout.filament_motion_present(extruder); // ...which calls response.filament_motion_present(extruder)
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
static void setup() {
|
||||
#define _INIT_RUNOUT_PIN(P,S,U,D) do{ if (ENABLED(U)) SET_INPUT_PULLUP(P); else if (ENABLED(D)) SET_INPUT_PULLDOWN(P); else SET_INPUT(P); }while(0)
|
||||
#define INIT_RUNOUT_PIN(N) _INIT_RUNOUT_PIN(FIL_RUNOUT##N##_PIN, FIL_RUNOUT##N##_STATE, FIL_RUNOUT##N##_PULLUP, FIL_RUNOUT##N##_PULLDOWN)
|
||||
#if NUM_RUNOUT_SENSORS >= 1
|
||||
INIT_RUNOUT_PIN(1);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 2
|
||||
INIT_RUNOUT_PIN(2);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 3
|
||||
INIT_RUNOUT_PIN(3);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 4
|
||||
INIT_RUNOUT_PIN(4);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 5
|
||||
INIT_RUNOUT_PIN(5);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 6
|
||||
INIT_RUNOUT_PIN(6);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 7
|
||||
INIT_RUNOUT_PIN(7);
|
||||
#endif
|
||||
#if NUM_RUNOUT_SENSORS >= 8
|
||||
INIT_RUNOUT_PIN(8);
|
||||
#define _INIT_RUNOUT_PIN(P,S,U,D) do{ if (ENABLED(U)) SET_INPUT_PULLUP(P); else if (ENABLED(D)) SET_INPUT_PULLDOWN(P); else SET_INPUT(P); }while(0);
|
||||
#define INIT_RUNOUT_PIN(N) _INIT_RUNOUT_PIN(FIL_RUNOUT##N##_PIN, FIL_RUNOUT##N##_STATE, FIL_RUNOUT##N##_PULLUP, FIL_RUNOUT##N##_PULLDOWN);
|
||||
REPEAT_1(NUM_RUNOUT_SENSORS, INIT_RUNOUT_PIN)
|
||||
#undef INIT_RUNOUT_PIN
|
||||
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
#define INIT_MOTION_PIN(N) _INIT_RUNOUT_PIN(FIL_MOTION##N##_PIN, FIL_MOTION##N##_STATE, FIL_MOTION##N##_PULLUP, FIL_MOTION##N##_PULLDOWN);
|
||||
REPEAT_1(NUM_MOTION_SENSORS, INIT_MOTION_PIN)
|
||||
#undef INIT_MOTION_PIN
|
||||
#endif
|
||||
#undef _INIT_RUNOUT_PIN
|
||||
#undef INIT_RUNOUT_PIN
|
||||
}
|
||||
|
||||
|
||||
// Return a bitmask of runout pin states
|
||||
static uint8_t poll_runout_pins() {
|
||||
@@ -221,125 +212,275 @@ class FilamentSensorBase {
|
||||
|
||||
// Return a bitmask of runout flag states (1 bits always indicates runout)
|
||||
static uint8_t poll_runout_states() {
|
||||
#define _OR_INVERT(N) | (runout.out_state(N-1) ? 0 : _BV(N-1))
|
||||
return poll_runout_pins() ^ uint8_t(0 REPEAT_1(NUM_RUNOUT_SENSORS, _OR_INVERT));
|
||||
#undef _OR_INVERT
|
||||
#define _INVERT_BIT(N) | (FIL_RUNOUT##N##_STATE ? 0 : _BV(N - 1))
|
||||
return poll_runout_pins() ^ uint8_t(0 REPEAT_1(NUM_RUNOUT_SENSORS, _INVERT_BIT));
|
||||
#undef _INVERT_BIT
|
||||
}
|
||||
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
// Return a bitmask of motion pin states
|
||||
static uint8_t poll_motion_pins() {
|
||||
#define _OR_MOTION(N) | (READ(FIL_MOTION##N##_PIN) ? _BV((N) - 1) : 0)
|
||||
return (0 REPEAT_1(NUM_MOTION_SENSORS, _OR_MOTION));
|
||||
#undef _OR_MOTION
|
||||
}
|
||||
|
||||
// Return a bitmask of motion flag states (1 bits always indicates runout)
|
||||
static uint8_t poll_motion_states() {
|
||||
#define _OR_MOTION(N) | (FIL_MOTION##N##_STATE ? 0 : _BV(N - 1))
|
||||
return poll_motion_pins() ^ uint8_t(0 REPEAT_1(NUM_MOTION_SENSORS, _OR_MOTION));
|
||||
#undef _OR_MOTION
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
class FilamentSensorCore : public FilamentSensorBase {
|
||||
private:
|
||||
static uint8_t motion_detected;
|
||||
#if HAS_FILAMENT_MOTION
|
||||
|
||||
static bool poll_runout_state(const uint8_t extruder) {
|
||||
const uint8_t runout_states = poll_runout_states();
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating())
|
||||
&& !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled)
|
||||
) return TEST(runout_states, extruder); // A specific extruder ran out
|
||||
#else
|
||||
UNUSED(extruder);
|
||||
#endif
|
||||
return !!runout_states; // Any extruder ran out
|
||||
}
|
||||
/**
|
||||
* This sensor uses a magnetic encoder disc and a Hall effect
|
||||
* sensor (or a slotted disc and optical sensor). The state
|
||||
* will toggle between 0 and 1 on filament movement. It can detect
|
||||
* filament runout and stripouts or jams.
|
||||
*/
|
||||
class FilamentSensorEncoder : public FilamentSensorBase {
|
||||
private:
|
||||
static uint8_t motion_detected;
|
||||
|
||||
static void poll_motion_sensor() {
|
||||
static uint8_t old_state;
|
||||
const uint8_t new_state = poll_runout_pins(),
|
||||
change = old_state ^ new_state;
|
||||
old_state = new_state;
|
||||
static void poll_motion_sensor() {
|
||||
static uint8_t old_state;
|
||||
const uint8_t new_state = TERN(FILAMENT_SWITCH_AND_MOTION, poll_motion_pins, poll_runout_pins)(),
|
||||
change = old_state ^ new_state;
|
||||
old_state = new_state;
|
||||
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
if (change) {
|
||||
SERIAL_ECHOPGM("Motion detected:");
|
||||
LOOP_L_N(e, NUM_RUNOUT_SENSORS)
|
||||
if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
#endif
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
if (change) {
|
||||
SERIAL_ECHOPGM("Motion detected:");
|
||||
for (uint8_t e = 0; e < TERN(FILAMENT_SWITCH_AND_MOTION, NUM_MOTION_SENSORS, NUM_RUNOUT_SENSORS); ++e)
|
||||
if (TEST(change, e)) SERIAL_CHAR(' ', '0' + e);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
#endif
|
||||
|
||||
motion_detected |= change;
|
||||
}
|
||||
|
||||
public:
|
||||
static void block_completed(const block_t * const b) {
|
||||
if (runout.mode[active_extruder] != RM_MOTION_SENSOR) return;
|
||||
|
||||
// If the sensor wheel has moved since the last call to
|
||||
// this method reset the runout counter for the extruder.
|
||||
if (TEST(motion_detected, b->extruder))
|
||||
filament_present(b->extruder);
|
||||
|
||||
// Clear motion triggers for next block
|
||||
motion_detected = 0;
|
||||
}
|
||||
|
||||
static void run() {
|
||||
if (runout.mode[active_extruder] == RM_MOTION_SENSOR) {
|
||||
poll_motion_sensor();
|
||||
motion_detected |= change;
|
||||
}
|
||||
else if (runout.mode[active_extruder] != RM_NONE) {
|
||||
LOOP_L_N(s, NUM_RUNOUT_SENSORS) {
|
||||
|
||||
public:
|
||||
static void block_completed(const block_t * const b) {
|
||||
// If the sensor wheel has moved since the last call to
|
||||
// this method reset the runout counter for the extruder.
|
||||
if (TEST(motion_detected, b->extruder))
|
||||
TERN(FILAMENT_SWITCH_AND_MOTION, filament_motion_present, filament_present)(b->extruder);
|
||||
|
||||
// Clear motion triggers for next block
|
||||
motion_detected = 0;
|
||||
}
|
||||
|
||||
static void run() { poll_motion_sensor(); }
|
||||
};
|
||||
|
||||
#endif // HAS_FILAMENT_MOTION
|
||||
|
||||
#if HAS_FILAMENT_SWITCH
|
||||
|
||||
/**
|
||||
* This is a simple endstop switch in the path of the filament.
|
||||
* It can detect filament runout, but not stripouts or jams.
|
||||
*/
|
||||
class FilamentSensorSwitch : public FilamentSensorBase {
|
||||
private:
|
||||
static bool poll_runout_state(const uint8_t extruder) {
|
||||
const uint8_t runout_states = poll_runout_states();
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
if ( !TERN0(DUAL_X_CARRIAGE, idex_is_duplicating())
|
||||
&& !TERN0(MULTI_NOZZLE_DUPLICATION, extruder_duplication_enabled)
|
||||
) return TEST(runout_states, extruder); // A specific extruder ran out
|
||||
#else
|
||||
UNUSED(extruder);
|
||||
#endif
|
||||
return !!runout_states; // Any extruder ran out
|
||||
}
|
||||
|
||||
public:
|
||||
static void block_completed(const block_t * const) {}
|
||||
|
||||
static void run() {
|
||||
for (uint8_t s = 0; s < NUM_RUNOUT_SENSORS; ++s) {
|
||||
const bool out = poll_runout_state(s);
|
||||
if (!out) filament_present(s);
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
static uint8_t was_out; // = 0
|
||||
if (out != TEST(was_out, s)) {
|
||||
TBI(was_out, s);
|
||||
SERIAL_ECHOLNF(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN"));
|
||||
SERIAL_ECHOLN(F("Filament Sensor "), AS_DIGIT(s), out ? F(" OUT") : F(" IN"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#endif // HAS_FILAMENT_SWITCH
|
||||
|
||||
/**
|
||||
* This is a simple endstop switch in the path of the filament.
|
||||
* It can detect filament runout, but not stripouts or jams.
|
||||
*/
|
||||
class FilamentSensor : public FilamentSensorBase {
|
||||
private:
|
||||
TERN_(HAS_FILAMENT_MOTION, static FilamentSensorEncoder encoder_sensor);
|
||||
TERN_(HAS_FILAMENT_SWITCH, static FilamentSensorSwitch switch_sensor);
|
||||
|
||||
public:
|
||||
static void block_completed(const block_t * const b) {
|
||||
TERN_(HAS_FILAMENT_MOTION, encoder_sensor.block_completed(b));
|
||||
TERN_(HAS_FILAMENT_SWITCH, switch_sensor.block_completed(b));
|
||||
}
|
||||
|
||||
static void run() {
|
||||
TERN_(HAS_FILAMENT_MOTION, encoder_sensor.run());
|
||||
TERN_(HAS_FILAMENT_SWITCH, switch_sensor.run());
|
||||
}
|
||||
};
|
||||
|
||||
/********************************* RESPONSE TYPE *********************************/
|
||||
|
||||
// RunoutResponseDelayed triggers a runout event only if the length
|
||||
// of filament specified by FIL_RUNOUT_DISTANCE_MM has been fed
|
||||
// during a runout condition.
|
||||
class RunoutResponseDelayed {
|
||||
private:
|
||||
static volatile float runout_mm_countdown[NUM_RUNOUT_SENSORS];
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
|
||||
public:
|
||||
static float runout_distance_mm[NUM_RUNOUT_SENSORS];
|
||||
typedef struct {
|
||||
float runout[NUM_RUNOUT_SENSORS];
|
||||
Flags<NUM_RUNOUT_SENSORS> runout_reset; // Reset runout later
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
float motion[NUM_MOTION_SENSORS];
|
||||
Flags<NUM_MOTION_SENSORS> motion_reset; // Reset motion later
|
||||
#endif
|
||||
} countdown_t;
|
||||
|
||||
static void reset() {
|
||||
LOOP_L_N(i, NUM_RUNOUT_SENSORS) filament_present(i);
|
||||
}
|
||||
// RunoutResponseDelayed triggers a runout event only if the length
|
||||
// of filament specified by FILAMENT_RUNOUT_DISTANCE_MM has been fed
|
||||
// during a runout condition.
|
||||
class RunoutResponseDelayed {
|
||||
private:
|
||||
static countdown_t mm_countdown;
|
||||
|
||||
static void run() {
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
static millis_t t = 0;
|
||||
const millis_t ms = millis();
|
||||
if (ELAPSED(ms, t)) {
|
||||
t = millis() + 1000UL;
|
||||
LOOP_L_N(i, NUM_RUNOUT_SENSORS)
|
||||
SERIAL_ECHOF(i ? F(", ") : F("Remaining mm: "), runout_mm_countdown[i]);
|
||||
SERIAL_EOL();
|
||||
public:
|
||||
static float runout_distance_mm;
|
||||
|
||||
static void reset() {
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i);
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) filament_motion_present(i);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void run() {
|
||||
#if ENABLED(FILAMENT_RUNOUT_SENSOR_DEBUG)
|
||||
static millis_t t = 0;
|
||||
const millis_t ms = millis();
|
||||
if (ELAPSED(ms, t)) {
|
||||
t = millis() + 1000UL;
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i)
|
||||
SERIAL_ECHO(i ? F(", ") : F("Runout remaining mm: "), mm_countdown.runout[i]);
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i)
|
||||
SERIAL_ECHO(i ? F(", ") : F("Motion remaining mm: "), mm_countdown.motion[i]);
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static runout_flags_t has_run_out() {
|
||||
runout_flags_t runout_flags{0};
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (mm_countdown.runout[i] < 0) runout_flags.set(i);
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
for (uint8_t i = 0; i < NUM_MOTION_SENSORS; ++i) if (mm_countdown.motion[i] < 0) runout_flags.set(i);
|
||||
#endif
|
||||
return runout_flags;
|
||||
}
|
||||
|
||||
static void filament_present(const uint8_t extruder) {
|
||||
if (mm_countdown.runout[extruder] < runout_distance_mm || did_pause_print) {
|
||||
// Reset runout only if it is smaller than runout_distance or printing is paused.
|
||||
// On Bowden systems retract may be larger than runout_distance_mm, so if retract
|
||||
// was added leave it in place, or the following unretract will cause runout event.
|
||||
mm_countdown.runout[extruder] = runout_distance_mm;
|
||||
mm_countdown.runout_reset.clear(extruder);
|
||||
}
|
||||
else {
|
||||
// If runout is larger than runout distance, we cannot reset right now, as Bowden and retract
|
||||
// distance larger than runout_distance_mm leads to negative runout right after unretract.
|
||||
// But we cannot ignore filament_present event. After unretract, runout will become smaller
|
||||
// than runout_distance_mm and should be reset after that. So activate delayed reset.
|
||||
mm_countdown.runout_reset.set(extruder);
|
||||
}
|
||||
}
|
||||
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
static void filament_motion_present(const uint8_t extruder) {
|
||||
// Same logic as filament_present
|
||||
if (mm_countdown.motion[extruder] < runout_distance_mm || did_pause_print) {
|
||||
mm_countdown.motion[extruder] = runout_distance_mm;
|
||||
mm_countdown.motion_reset.clear(extruder);
|
||||
}
|
||||
else
|
||||
mm_countdown.motion_reset.set(extruder);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static uint8_t has_run_out() {
|
||||
uint8_t runout_flags = 0;
|
||||
LOOP_L_N(i, NUM_RUNOUT_SENSORS) if (runout_mm_countdown[i] < 0) SBI(runout_flags, i);
|
||||
return runout_flags;
|
||||
}
|
||||
static void block_completed(const block_t * const b) {
|
||||
const int32_t esteps = b->steps.e;
|
||||
if (!esteps) return;
|
||||
|
||||
static void filament_present(const uint8_t extruder) {
|
||||
runout_mm_countdown[extruder] = runout_distance_mm[extruder];
|
||||
}
|
||||
// No calculation unless paused or printing
|
||||
if (!should_monitor_runout()) return;
|
||||
|
||||
static void block_completed(const block_t * const b) {
|
||||
if (b->steps.x || b->steps.y || b->steps.z || did_pause_print) { // Allow pause purge move to re-trigger runout state
|
||||
// Only trigger on extrusion with XYZ movement to allow filament change and retract/recover.
|
||||
// No need to ignore retract/unretract movement since they complement each other
|
||||
const uint8_t e = b->extruder;
|
||||
const int32_t steps = b->steps.e;
|
||||
runout_mm_countdown[e] -= (TEST(b->direction_bits, E_AXIS) ? -steps : steps) * planner.mm_per_step[E_AXIS_N(e)];
|
||||
const float mm = (b->direction_bits.e ? esteps : -esteps) * planner.mm_per_step[E_AXIS_N(e)];
|
||||
|
||||
if (e < NUM_RUNOUT_SENSORS) {
|
||||
mm_countdown.runout[e] -= mm;
|
||||
if (mm_countdown.runout_reset[e]) filament_present(e); // Reset pending. Try to reset.
|
||||
}
|
||||
|
||||
#if ENABLED(FILAMENT_SWITCH_AND_MOTION)
|
||||
if (e < NUM_MOTION_SENSORS) {
|
||||
mm_countdown.motion[e] -= mm;
|
||||
if (mm_countdown.motion_reset[e]) filament_motion_present(e); // Reset pending. Try to reset.
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#else // !HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
|
||||
// RunoutResponseDebounced triggers a runout event after a runout
|
||||
// condition has been detected runout_threshold times in a row.
|
||||
|
||||
class RunoutResponseDebounced {
|
||||
private:
|
||||
static constexpr int8_t runout_threshold = FILAMENT_RUNOUT_THRESHOLD;
|
||||
static int8_t runout_count[NUM_RUNOUT_SENSORS];
|
||||
|
||||
public:
|
||||
static void reset() {
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) filament_present(i);
|
||||
}
|
||||
|
||||
static void run() {
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (runout_count[i] >= 0) runout_count[i]--;
|
||||
}
|
||||
|
||||
static runout_flags_t has_run_out() {
|
||||
runout_flags_t runout_flags{0};
|
||||
for (uint8_t i = 0; i < NUM_RUNOUT_SENSORS; ++i) if (runout_count[i] < 0) runout_flags.set(i);
|
||||
return runout_flags;
|
||||
}
|
||||
|
||||
static void block_completed(const block_t * const) { }
|
||||
|
||||
static void filament_present(const uint8_t extruder) {
|
||||
runout_count[extruder] = runout_threshold;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // !HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
|
||||
@@ -31,7 +31,7 @@ static uint32_t axis_plug_backward = 0;
|
||||
void stepper_driver_backward_error(FSTR_P const fstr) {
|
||||
SERIAL_ERROR_START();
|
||||
SERIAL_ECHOLN(fstr, F(" driver is backward!"));
|
||||
ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT(MSG_DRIVER_BACKWARD));
|
||||
ui.status_printf(2, F(S_FMT S_FMT), FTOP(fstr), GET_TEXT_F(MSG_DRIVER_BACKWARD));
|
||||
}
|
||||
|
||||
void stepper_driver_backward_check() {
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
|
||||
/**
|
||||
* G42: Move X & Y axes to mesh coordinates (I & J)
|
||||
*
|
||||
* Parameters:
|
||||
* F<feedrate> : Feedrate in mm/min
|
||||
* I<index> : X axis point index
|
||||
* J<index> : Y axis point index
|
||||
* P<bool> : Flag to put the prove at the given point
|
||||
*/
|
||||
void GcodeSuite::G42() {
|
||||
if (MOTION_CONDITIONS) {
|
||||
|
||||
@@ -683,7 +683,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
if (TERN0(IS_KINEMATIC, !probe.can_reach(abl.probePos))) continue;
|
||||
|
||||
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing mesh point ", pt_index, "/", abl.abl_points, ".");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), int(pt_index), int(abl.abl_points)));
|
||||
|
||||
#if ENABLED(BD_SENSOR_PROBE_NO_STOP)
|
||||
if (PR_INNER_VAR == inStart) {
|
||||
@@ -782,7 +782,7 @@ G29_TYPE GcodeSuite::G29() {
|
||||
|
||||
for (uint8_t i = 0; i < 3; ++i) {
|
||||
if (abl.verbose_level) SERIAL_ECHOLNPGM("Probing point ", i + 1, "/3.");
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT(MSG_PROBING_POINT), int(i + 1)));
|
||||
TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/3"), GET_TEXT_F(MSG_PROBING_POINT), int(i + 1)));
|
||||
|
||||
// Retain the last probe position
|
||||
abl.probePos = xy_pos_t(points[i]);
|
||||
|
||||
@@ -253,7 +253,7 @@ void GcodeSuite::G29() {
|
||||
|
||||
if (state == MeshNext) {
|
||||
SERIAL_ECHOLNPGM("MBL G29 point ", _MIN(mbl_probe_index, GRID_MAX_POINTS), " of ", GRID_MAX_POINTS);
|
||||
if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
|
||||
if (mbl_probe_index > 0) TERN_(HAS_STATUS_MESSAGE, ui.status_printf(0, F(S_FMT " %i/%i"), GET_TEXT_F(MSG_PROBING_POINT), _MIN(mbl_probe_index, GRID_MAX_POINTS), int(GRID_MAX_POINTS)));
|
||||
}
|
||||
|
||||
report_current_position();
|
||||
|
||||
@@ -149,7 +149,7 @@ void GcodeSuite::M48() {
|
||||
for (uint8_t n = 0; n < n_samples; ++n) {
|
||||
#if HAS_STATUS_MESSAGE
|
||||
// Display M48 progress in the status bar
|
||||
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
ui.status_printf(0, F(S_FMT ": %d/%d"), GET_TEXT_F(MSG_M48_POINT), int(n + 1), int(n_samples));
|
||||
#endif
|
||||
|
||||
// When there are "legs" of movement move around the point before probing
|
||||
|
||||
@@ -20,6 +20,11 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* gcode/control/M10_M11.cpp
|
||||
* Air Evacuation
|
||||
*/
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(AIR_EVACUATION)
|
||||
@@ -68,7 +68,7 @@ void GcodeSuite::M907() {
|
||||
#define HAS_X_Y_XY_I_J_K_U_V_W 1
|
||||
#endif
|
||||
|
||||
#if HAS_X_Y_XY_I_J_K_U_V_W || ANY_PIN(MOTOR_CURRENT_PWM_E, MOTOR_CURRENT_PWM_Z)
|
||||
#if HAS_X_Y_XY_I_J_K_U_V_W || HAS_MOTOR_CURRENT_PWM_E || PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
|
||||
if (!parser.seen("S"
|
||||
#if HAS_X_Y_XY_I_J_K_U_V_W
|
||||
@@ -77,7 +77,7 @@ void GcodeSuite::M907() {
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
"Z"
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
"E"
|
||||
#endif
|
||||
)) return M907_report();
|
||||
@@ -94,7 +94,7 @@ void GcodeSuite::M907() {
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
||||
if (parser.seenval('Z')) stepper.set_digipot_current(1, parser.value_int());
|
||||
#endif
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
if (parser.seenval('E')) stepper.set_digipot_current(2, parser.value_int());
|
||||
#endif
|
||||
|
||||
@@ -133,7 +133,7 @@ void GcodeSuite::M907() {
|
||||
SERIAL_ECHOLNPGM_P( // PWM-based has 3 values:
|
||||
PSTR(" M907 X"), stepper.motor_current_setting[0] // X, Y, (I, J, K, U, V, W)
|
||||
, SP_Z_STR, stepper.motor_current_setting[1] // Z
|
||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
||||
#if HAS_MOTOR_CURRENT_PWM_E
|
||||
, SP_E_STR, stepper.motor_current_setting[2] // E
|
||||
#endif
|
||||
);
|
||||
|
||||
@@ -44,6 +44,15 @@ void GcodeSuite::M593_report(const bool forReplay/*=true*/) {
|
||||
" D", stepper.get_shaping_damping_ratio(Y_AXIS)
|
||||
);
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y)
|
||||
report_echo_start(forReplay);
|
||||
#endif
|
||||
SERIAL_ECHOLNPGM(" M593 Z"
|
||||
" F", stepper.get_shaping_frequency(Z_AXIS),
|
||||
" D", stepper.get_shaping_damping_ratio(Z_AXIS)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,14 +68,17 @@ void GcodeSuite::M593() {
|
||||
|
||||
const bool seen_X = TERN0(INPUT_SHAPING_X, parser.seen_test('X')),
|
||||
seen_Y = TERN0(INPUT_SHAPING_Y, parser.seen_test('Y')),
|
||||
for_X = seen_X || TERN0(INPUT_SHAPING_X, (!seen_X && !seen_Y)),
|
||||
for_Y = seen_Y || TERN0(INPUT_SHAPING_Y, (!seen_X && !seen_Y));
|
||||
seen_Z = TERN0(INPUT_SHAPING_Z, parser.seen_test('Z')),
|
||||
for_X = seen_X || TERN0(INPUT_SHAPING_X, (!seen_X && !seen_Y && !seen_Z)),
|
||||
for_Y = seen_Y || TERN0(INPUT_SHAPING_Y, (!seen_X && !seen_Y && !seen_Z)),
|
||||
for_Z = seen_Z || TERN0(INPUT_SHAPING_Z, (!seen_X && !seen_Y && !seen_Z));
|
||||
|
||||
if (parser.seen('D')) {
|
||||
const float zeta = parser.value_float();
|
||||
if (WITHIN(zeta, 0, 1)) {
|
||||
if (for_X) stepper.set_shaping_damping_ratio(X_AXIS, zeta);
|
||||
if (for_Y) stepper.set_shaping_damping_ratio(Y_AXIS, zeta);
|
||||
if (for_Z) stepper.set_shaping_damping_ratio(Z_AXIS, zeta);
|
||||
}
|
||||
else
|
||||
SERIAL_ECHO_MSG("?Zeta (D) value out of range (0-1)");
|
||||
@@ -78,6 +90,7 @@ void GcodeSuite::M593() {
|
||||
if (freq == 0.0f || freq > min_freq) {
|
||||
if (for_X) stepper.set_shaping_frequency(X_AXIS, freq);
|
||||
if (for_Y) stepper.set_shaping_frequency(Y_AXIS, freq);
|
||||
if (for_Z) stepper.set_shaping_frequency(Z_AXIS, freq);
|
||||
}
|
||||
else
|
||||
SERIAL_ECHOLNPGM(GCODE_ERR_MSG("Frequency (F) must be greater than ", min_freq, " or 0 to disable"));
|
||||
|
||||
@@ -94,7 +94,7 @@ void GcodeSuite::M600() {
|
||||
// In this case, for duplicating modes set DXC_ext to the extruder that ran out.
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
if (idex_is_duplicating())
|
||||
DXC_ext = (READ(FIL_RUNOUT2_PIN) == runout.out_state(1)) ? 1 : 0;
|
||||
DXC_ext = (READ(FIL_RUNOUT2_PIN) == FIL_RUNOUT2_STATE) ? 1 : 0;
|
||||
#else
|
||||
DXC_ext = active_extruder;
|
||||
#endif
|
||||
|
||||
@@ -72,6 +72,7 @@ void GcodeSuite::M413_report(const bool forReplay/*=true*/) {
|
||||
, " B", recovery.bed_temp_threshold
|
||||
#endif
|
||||
);
|
||||
SERIAL_ECHO(" ; ");
|
||||
serialprintln_onoff(recovery.enabled);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
|
||||
#include "../../gcode.h"
|
||||
#include "../../../feature/runout.h"
|
||||
|
||||
/**
|
||||
* M412: Enable / Disable filament runout detection
|
||||
*
|
||||
* Parameters
|
||||
* R : Reset the runout sensor
|
||||
* S<bool> : Reset and enable/disable the runout sensor
|
||||
* H<bool> : Enable/disable host handling of filament runout
|
||||
* D<linear> : Extra distance to continue after runout is triggered
|
||||
*/
|
||||
void GcodeSuite::M412() {
|
||||
if (parser.seen("RS"
|
||||
TERN_(HAS_FILAMENT_RUNOUT_DISTANCE, "D")
|
||||
TERN_(HOST_ACTION_COMMANDS, "H")
|
||||
)) {
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
if (parser.seen('H')) runout.host_handling = parser.value_bool();
|
||||
#endif
|
||||
const bool seenR = parser.seen_test('R'), seenS = parser.seen('S');
|
||||
if (seenR || seenS) runout.reset();
|
||||
if (seenS) runout.enabled = parser.value_bool();
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
if (parser.seenval('D')) runout.set_runout_distance(parser.value_linear_units());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPGM("Filament runout ");
|
||||
serialprint_onoff(runout.enabled);
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
SERIAL_ECHOPGM(" ; Distance ", runout.runout_distance(), "mm");
|
||||
#endif
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
SERIAL_ECHOPGM(" ; Host handling ");
|
||||
serialprint_onoff(runout.host_handling);
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
}
|
||||
}
|
||||
|
||||
void GcodeSuite::M412_report(const bool forReplay/*=true*/) {
|
||||
TERN_(MARLIN_SMALL_BUILD, return);
|
||||
|
||||
report_heading_etc(forReplay, F(STR_FILAMENT_RUNOUT_SENSOR));
|
||||
SERIAL_ECHOPGM(
|
||||
" M412 S", runout.enabled
|
||||
#if HAS_FILAMENT_RUNOUT_DISTANCE
|
||||
, " D", LINEAR_UNIT(runout.runout_distance())
|
||||
#endif
|
||||
, " ; Sensor "
|
||||
);
|
||||
serialprintln_onoff(runout.enabled);
|
||||
}
|
||||
|
||||
#endif // HAS_FILAMENT_SENSOR
|
||||
@@ -1,97 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "../../../inc/MarlinConfig.h"
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
|
||||
#include "../../gcode.h"
|
||||
#include "../../../feature/runout.h"
|
||||
|
||||
/**
|
||||
* M591: Configure filament runout detection
|
||||
*
|
||||
* Parameters
|
||||
* R : Reset the runout sensor
|
||||
* S<bool> : Reset and enable/disable the runout sensor
|
||||
* H<bool> : Enable/disable host handling of filament runout
|
||||
* L<linear> : Extra distance to continue after runout is triggered or motion interval
|
||||
* D<linear> : Alias for L
|
||||
* P<index> : Mode 0 = NONE
|
||||
* 1 = Switch NO (HIGH = filament present)
|
||||
* 2 = Switch NC (LOW = filament present)
|
||||
* 3 = Encoder / Motion Sensor
|
||||
*/
|
||||
void GcodeSuite::M591() {
|
||||
if (parser.seen("RSDP" TERN_(HOST_ACTION_COMMANDS, "H"))) {
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
if (parser.seen('H')) runout.host_handling = parser.value_bool();
|
||||
#endif
|
||||
const bool seenR = parser.seen_test('R'), seenS = parser.seen('S');
|
||||
if (seenR || seenS) runout.reset();
|
||||
const uint8_t tool = TERN0(MULTI_FILAMENT_SENSOR, parser.ushortval('E', active_extruder));
|
||||
if (seenS) runout.enabled[tool] = parser.value_bool();
|
||||
if (parser.seen('D') || parser.seen('L')) runout.set_runout_distance(parser.value_linear_units(), tool);
|
||||
if (parser.seen('P')) {
|
||||
const RunoutMode tmp_mode = (RunoutMode)parser.value_int();
|
||||
switch (tmp_mode) {
|
||||
case RM_NONE ... RM_OUT_ON_HIGH:
|
||||
case RM_MOTION_SENSOR:
|
||||
runout.mode[tool] = tmp_mode;
|
||||
runout.setup();
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
#if DISABLED(SLIM_LCD_MENUS)
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPGM("Filament runout ");
|
||||
serialprint_onoff(runout.enabled[active_extruder]);
|
||||
SERIAL_ECHOPGM(" ; Distance ", runout.runout_distance(active_extruder), "mm");
|
||||
SERIAL_ECHOPGM(" ; Mode ", runout.mode[active_extruder]);
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
SERIAL_ECHOPGM(" ; Host handling ");
|
||||
serialprint_onoff(runout.host_handling);
|
||||
#endif
|
||||
SERIAL_EOL();
|
||||
#else
|
||||
M591_report(false);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GcodeSuite::M591_report(const bool forReplay/*=true*/) {
|
||||
report_heading_etc(forReplay, F(STR_FILAMENT_RUNOUT_SENSOR));
|
||||
LOOP_S_L_N(e, 1, NUM_RUNOUT_SENSORS)
|
||||
SERIAL_ECHOLNPGM(
|
||||
" M591"
|
||||
#if MULTI_FILAMENT_SENSOR
|
||||
" E", e,
|
||||
#endif
|
||||
" S", runout.enabled[e]
|
||||
, " D", LINEAR_UNIT(runout.runout_distance(e))
|
||||
, " P", runout.mode[e]
|
||||
);
|
||||
}
|
||||
|
||||
#endif // HAS_FILAMENT_SENSOR
|
||||
+84
-60
@@ -75,26 +75,14 @@ GcodeSuite gcode;
|
||||
millis_t GcodeSuite::previous_move_ms = 0,
|
||||
GcodeSuite::max_inactive_time = 0;
|
||||
|
||||
#if HAS_DISABLE_INACTIVE_AXIS
|
||||
millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME);
|
||||
#if HAS_DISABLE_IDLE_AXES
|
||||
millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_TIMEOUT_SEC);
|
||||
#endif
|
||||
|
||||
// Relative motion mode for each logical axis
|
||||
static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES;
|
||||
axis_bits_t GcodeSuite::axis_relative = 0 LOGICAL_AXIS_GANG(
|
||||
| (ar_init.e << REL_E),
|
||||
| (ar_init.x << REL_X),
|
||||
| (ar_init.y << REL_Y),
|
||||
| (ar_init.z << REL_Z),
|
||||
| (ar_init.i << REL_I),
|
||||
| (ar_init.j << REL_J),
|
||||
| (ar_init.k << REL_K),
|
||||
| (ar_init.u << REL_U),
|
||||
| (ar_init.v << REL_V),
|
||||
| (ar_init.w << REL_W)
|
||||
);
|
||||
relative_t GcodeSuite::axis_relative; // Init in constructor
|
||||
|
||||
#if EITHER(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
|
||||
#if ANY(HAS_AUTO_REPORTING, HOST_KEEPALIVE_FEATURE)
|
||||
bool GcodeSuite::autoreport_paused; // = false
|
||||
#endif
|
||||
|
||||
@@ -117,8 +105,7 @@ void GcodeSuite::report_heading(const bool forReplay, FSTR_P const fstr, const b
|
||||
if (forReplay) return;
|
||||
if (fstr) {
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_ECHOPGM("; ");
|
||||
SERIAL_ECHOF(fstr);
|
||||
SERIAL_ECHO(F("; "), fstr);
|
||||
}
|
||||
if (eol) { SERIAL_CHAR(':'); SERIAL_EOL(); }
|
||||
}
|
||||
@@ -135,14 +122,16 @@ void GcodeSuite::say_units() {
|
||||
* Return -1 if the T parameter is out of range
|
||||
*/
|
||||
int8_t GcodeSuite::get_target_extruder_from_command() {
|
||||
if (parser.seenval('T')) {
|
||||
const int8_t e = parser.value_byte();
|
||||
if (e < EXTRUDERS) return e;
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
|
||||
SERIAL_ECHOLNPGM(" " STR_INVALID_EXTRUDER " ", e);
|
||||
return -1;
|
||||
}
|
||||
#if HAS_TOOLCHANGE
|
||||
if (parser.seenval('T')) {
|
||||
const int8_t e = parser.value_byte();
|
||||
if (e < EXTRUDERS) return e;
|
||||
SERIAL_ECHO_START();
|
||||
SERIAL_CHAR('M'); SERIAL_ECHO(parser.codenum);
|
||||
SERIAL_ECHOLNPGM(" " STR_INVALID_EXTRUDER " ", e);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return active_extruder;
|
||||
}
|
||||
|
||||
@@ -166,7 +155,7 @@ int8_t GcodeSuite::get_target_e_stepper_from_command(const int8_t dval/*=-1*/) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set XYZ...E destination and feedrate from the current GCode command
|
||||
* Set XYZ...E destination and feedrate from the current G-Code command
|
||||
*
|
||||
* - Set destination from included axis codes
|
||||
* - Set to current for missing axis codes
|
||||
@@ -216,13 +205,13 @@ void GcodeSuite::get_destination_from_command() {
|
||||
TERN_(LASER_FEATURE, cutter.feedrate_mm_m = MMS_TO_MMM(feedrate_mm_s));
|
||||
}
|
||||
|
||||
#if BOTH(PRINTCOUNTER, HAS_EXTRUDERS)
|
||||
#if ALL(PRINTCOUNTER, HAS_EXTRUDERS)
|
||||
if (!DEBUGGING(DRYRUN) && !skip_move)
|
||||
print_job_timer.incFilamentUsed(destination.e - current_position.e);
|
||||
#endif
|
||||
|
||||
// Get ABCDHI mixing factors
|
||||
#if BOTH(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1)
|
||||
#if ALL(MIXING_EXTRUDER, DIRECT_MIXING_IN_G1)
|
||||
M165();
|
||||
#endif
|
||||
|
||||
@@ -454,7 +443,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 61: G61(); break; // G61: Apply/restore saved coordinates.
|
||||
#endif
|
||||
|
||||
#if BOTH(PTC_PROBE, PTC_BED)
|
||||
#if ALL(PTC_PROBE, PTC_BED)
|
||||
case 76: G76(); break; // G76: Calibrate first layer compensation values
|
||||
#endif
|
||||
|
||||
@@ -472,7 +461,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
#endif
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
case 800: parser.debug(); break; // G800: GCode Parser Test for G
|
||||
case 800: parser.debug(); break; // G800: G-Code Parser Test for G
|
||||
#endif
|
||||
|
||||
default: parser.unknown_command_warning(); break;
|
||||
@@ -496,11 +485,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 7: M7(); break; // M7: Coolant Mist ON
|
||||
#endif
|
||||
|
||||
#if EITHER(AIR_ASSIST, COOLANT_FLOOD)
|
||||
#if ANY(AIR_ASSIST, COOLANT_FLOOD)
|
||||
case 8: M8(); break; // M8: Air Assist / Coolant Flood ON
|
||||
#endif
|
||||
|
||||
#if EITHER(AIR_ASSIST, COOLANT_CONTROL)
|
||||
#if ANY(AIR_ASSIST, COOLANT_CONTROL)
|
||||
case 9: M9(); break; // M9: Air Assist / Coolant OFF
|
||||
#endif
|
||||
|
||||
@@ -519,7 +508,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
|
||||
case 17: M17(); break; // M17: Enable all stepper motors
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if HAS_MEDIA
|
||||
case 20: M20(); break; // M20: List SD card
|
||||
case 21: M21(); break; // M21: Init SD card
|
||||
case 22: M22(); break; // M22: Release SD card
|
||||
@@ -540,12 +529,12 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 33: M33(); break; // M33: Get the long full path to a file or folder
|
||||
#endif
|
||||
|
||||
#if BOTH(SDCARD_SORT_ALPHA, SDSORT_GCODE)
|
||||
#if ALL(SDCARD_SORT_ALPHA, SDSORT_GCODE)
|
||||
case 34: M34(); break; // M34: Set SD card sorting options
|
||||
#endif
|
||||
|
||||
case 928: M928(); break; // M928: Start SD write
|
||||
#endif // SDSUPPORT
|
||||
#endif // HAS_MEDIA
|
||||
|
||||
case 31: M31(); break; // M31: Report time since the start of SD print or last M109
|
||||
|
||||
@@ -581,7 +570,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 102: M102(); break; // M102: Configure Bed Distance Sensor
|
||||
#endif
|
||||
|
||||
#if HAS_EXTRUDERS
|
||||
#if HAS_HOTEND
|
||||
case 104: M104(); break; // M104: Set hot end temperature
|
||||
case 109: M109(); break; // M109: Wait for hotend temperature to reach target
|
||||
#endif
|
||||
@@ -640,7 +629,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 154: M154(); break; // M154: Set position auto-report interval
|
||||
#endif
|
||||
|
||||
#if BOTH(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
|
||||
#if ALL(AUTO_REPORT_TEMPERATURES, HAS_TEMP_SENSOR)
|
||||
case 155: M155(); break; // M155: Set temperature auto-report interval
|
||||
#endif
|
||||
|
||||
@@ -671,11 +660,24 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 82: M82(); break; // M82: Set E axis normal mode (same as other axes)
|
||||
case 83: M83(); break; // M83: Set E axis relative mode
|
||||
#endif
|
||||
|
||||
case 18: case 84: M18_M84(); break; // M18/M84: Disable Steppers / Set Timeout
|
||||
case 85: M85(); break; // M85: Set inactivity stepper shutdown timeout
|
||||
case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes
|
||||
|
||||
#if ENABLED(HOTEND_IDLE_TIMEOUT)
|
||||
case 86: M86(); break; // M86: Set Hotend Idle Timeout
|
||||
case 87: M87(); break; // M87: Cancel Hotend Idle Timeout
|
||||
#endif
|
||||
|
||||
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
|
||||
case 92: M92(); break; // M92: Set the steps-per-unit for one or more axes
|
||||
#endif
|
||||
|
||||
case 114: M114(); break; // M114: Report current position
|
||||
case 115: M115(); break; // M115: Report capabilities
|
||||
|
||||
#if ENABLED(CAPABILITIES_REPORT)
|
||||
case 115: M115(); break; // M115: Report capabilities
|
||||
#endif
|
||||
|
||||
case 117: TERN_(HAS_STATUS_MESSAGE, M117()); break; // M117: Set LCD message text, if possible
|
||||
|
||||
@@ -721,7 +723,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 204: M204(); break; // M204: Set acceleration
|
||||
case 205: M205(); break; // M205: Set advanced settings
|
||||
|
||||
#if HAS_M206_COMMAND
|
||||
#if HAS_HOME_OFFSET
|
||||
case 206: M206(); break; // M206: Set home offsets
|
||||
#endif
|
||||
|
||||
@@ -769,6 +771,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
case 290: M290(); break; // M290: Babystepping
|
||||
#if ENABLED(EP_BABYSTEPPING)
|
||||
case 293: IF_DISABLED(EMERGENCY_PARSER, M293()); break; // M293: Babystep up
|
||||
case 294: IF_DISABLED(EMERGENCY_PARSER, M294()); break; // M294: Babystep down
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_SOUND
|
||||
@@ -795,7 +801,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 250: M250(); break; // M250: Set LCD contrast
|
||||
#endif
|
||||
|
||||
#if HAS_GCODE_M255
|
||||
#if ENABLED(EDITABLE_DISPLAY_TIMEOUT)
|
||||
case 255: M255(); break; // M255: Set LCD Sleep/Backlight Timeout (Minutes)
|
||||
#endif
|
||||
|
||||
@@ -836,7 +842,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 364: if (M364()) return; break; // M364: SCARA Psi pos3 (90 deg to Theta)
|
||||
#endif
|
||||
|
||||
#if EITHER(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
|
||||
#if ANY(EXT_SOLENOID, MANUAL_SOLENOID_CONTROL)
|
||||
case 380: M380(); break; // M380: Activate solenoid on active (or specified) extruder
|
||||
case 381: M381(); break; // M381: Disable all solenoids or, if MANUAL_SOLENOID_CONTROL, active (or specified) solenoid
|
||||
#endif
|
||||
@@ -859,6 +865,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 407: M407(); break; // M407: Display measured filament diameter
|
||||
#endif
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
case 412: M412(); break; // M412: Enable/Disable filament runout detection
|
||||
#endif
|
||||
|
||||
#if HAS_MULTI_LANGUAGE
|
||||
case 414: M414(); break; // M414: Select multi language menu
|
||||
#endif
|
||||
@@ -879,7 +889,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 425: M425(); break; // M425: Tune backlash compensation
|
||||
#endif
|
||||
|
||||
#if HAS_M206_COMMAND
|
||||
#if HAS_HOME_OFFSET
|
||||
case 428: M428(); break; // M428: Apply current_position to home_offset
|
||||
#endif
|
||||
|
||||
@@ -891,6 +901,10 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 486: M486(); break; // M486: Identify and cancel objects
|
||||
#endif
|
||||
|
||||
#if ENABLED(FT_MOTION)
|
||||
case 493: M493(); break; // M493: Fixed-Time Motion control
|
||||
#endif
|
||||
|
||||
case 500: M500(); break; // M500: Store settings in EEPROM
|
||||
case 501: M501(); break; // M501: Read settings from EEPROM
|
||||
case 502: M502(); break; // M502: Revert to default settings
|
||||
@@ -911,7 +925,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if HAS_MEDIA
|
||||
case 524: M524(); break; // M524: Abort the current SD print job
|
||||
#endif
|
||||
|
||||
@@ -929,14 +943,19 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 575: M575(); break; // M575: Set serial baudrate
|
||||
#endif
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
case 412: M412(); break; // Alias to M591
|
||||
case 591: M591(); break; // M591 Configure filament runout detection
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
case 592: M592(); break; // M592: Nonlinear Extrusion control
|
||||
#endif
|
||||
|
||||
#if HAS_ZV_SHAPING
|
||||
case 593: M593(); break; // M593: Input Shaping control
|
||||
#endif
|
||||
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
case 600: M600(); break; // M600: Pause for Filament Change
|
||||
case 603: M603(); break; // M603: Configure Filament Change
|
||||
#if ENABLED(CONFIGURE_FILAMENT_CHANGE)
|
||||
case 603: M603(); break; // M603: Configure Filament Change
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_DUPLICATION_MODE
|
||||
@@ -947,7 +966,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 665: M665(); break; // M665: Set Kinematics parameters
|
||||
#endif
|
||||
|
||||
#if ENABLED(DELTA) || HAS_EXTRA_ENDSTOPS
|
||||
#if ANY(DELTA, HAS_EXTRA_ENDSTOPS)
|
||||
case 666: M666(); break; // M666: Set delta or multiple endstop adjustment
|
||||
#endif
|
||||
|
||||
@@ -988,7 +1007,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
|
||||
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_PWM, HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC)
|
||||
case 907: M907(); break; // M907: Set digital trimpot motor current using axis codes.
|
||||
#if EITHER(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
|
||||
#if ANY(HAS_MOTOR_CURRENT_SPI, HAS_MOTOR_CURRENT_DAC)
|
||||
case 908: M908(); break; // M908: Control digital trimpot directly.
|
||||
#if HAS_MOTOR_CURRENT_DAC
|
||||
case 909: M909(); break; // M909: Print digipot/DAC current value
|
||||
@@ -1026,7 +1045,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
#endif
|
||||
|
||||
#if ENABLED(DEBUG_GCODE_PARSER)
|
||||
case 800: parser.debug(); break; // M800: GCode Parser Test for M
|
||||
case 800: parser.debug(); break; // M800: G-Code Parser Test for M
|
||||
#endif
|
||||
|
||||
#if ENABLED(GCODE_REPEAT_MARKERS)
|
||||
@@ -1054,7 +1073,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 422: M422(); break; // M422: Set Z Stepper automatic alignment position using probe
|
||||
#endif
|
||||
|
||||
#if ALL(SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE)
|
||||
#if ENABLED(OTA_FIRMWARE_UPDATE)
|
||||
case 936: M936(); break; // M936: OTA update firmware.
|
||||
#endif
|
||||
|
||||
#if SPI_FLASH_BACKUP
|
||||
case 993: M993(); break; // M993: Backup SPI Flash to SD
|
||||
case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash
|
||||
#endif
|
||||
@@ -1074,14 +1097,18 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
case 1000: M1000(); break; // M1000: [INTERNAL] Resume from power-loss
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if HAS_MEDIA
|
||||
case 1001: M1001(); break; // M1001: [INTERNAL] Handle SD completion
|
||||
#endif
|
||||
|
||||
#if ENABLED(DGUS_LCD_UI_MKS)
|
||||
#if DGUS_LCD_UI_MKS
|
||||
case 1002: M1002(); break; // M1002: [INTERNAL] Tool-change and Relative E Move
|
||||
#endif
|
||||
|
||||
#if ENABLED(ONE_CLICK_PRINT)
|
||||
case 1003: M1003(); break; // M1003: [INTERNAL] Set the current dir to /
|
||||
#endif
|
||||
|
||||
#if ENABLED(UBL_MESH_WIZARD)
|
||||
case 1004: M1004(); break; // M1004: UBL Mesh Wizard
|
||||
#endif
|
||||
@@ -1117,7 +1144,7 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
|
||||
|
||||
if (!no_ok) queue.ok_to_send();
|
||||
|
||||
SERIAL_OUT(msgDone); // Call the msgDone serial hook to signal command processing done
|
||||
SERIAL_IMPL.msgDone(); // Call the msgDone serial hook to signal command processing done
|
||||
}
|
||||
|
||||
#if ENABLED(M100_FREE_MEMORY_DUMPER)
|
||||
@@ -1164,10 +1191,7 @@ void GcodeSuite::process_subcommands_now(FSTR_P fgcode) {
|
||||
for (;;) {
|
||||
PGM_P const delim = strchr_P(pgcode, '\n'); // Get address of next newline
|
||||
const size_t len = delim ? delim - pgcode : strlen_P(pgcode); // Get the command length
|
||||
char cmd[len + 1]; // Allocate a stack buffer
|
||||
strncpy_P(cmd, pgcode, len); // Copy the command to the stack
|
||||
cmd[len] = '\0'; // End with a nul
|
||||
parser.parse(cmd); // Parse the command
|
||||
parser.parse(MString<MAX_CMD_SIZE>().setn_P(pgcode, len)); // Parse the command
|
||||
process_parsed_command(true); // Process it (no "ok")
|
||||
if (!delim) break; // Last command?
|
||||
pgcode = delim + 1; // Get the next command
|
||||
|
||||
@@ -143,7 +143,7 @@
|
||||
* R<temp> Wait for extruder current temp to reach target temp. ** Wait for heating or cooling. **
|
||||
* If AUTOTEMP is enabled, S<mintemp> B<maxtemp> F<factor>. Exit autotemp by any M109 without F
|
||||
*
|
||||
* M110 - Set the current line number. (Used by host printing)
|
||||
* M110 - Get or set the current line number. (Used by host printing)
|
||||
* M111 - Set debug flags: "M111 S<flagbits>". See flag bits defined in enum.h.
|
||||
* M112 - Full Shutdown.
|
||||
*
|
||||
@@ -234,6 +234,7 @@
|
||||
* M406 - Disable Filament Sensor flow control. (Requires FILAMENT_WIDTH_SENSOR)
|
||||
* M407 - Display measured filament diameter in millimeters. (Requires FILAMENT_WIDTH_SENSOR)
|
||||
* M410 - Quickstop. Abort all planned moves.
|
||||
* M412 - Enable / Disable Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR)
|
||||
* M413 - Enable / Disable Power-Loss Recovery. (Requires POWER_LOSS_RECOVERY)
|
||||
* M414 - Set language by index. (Requires LCD_LANGUAGE_2...)
|
||||
* M420 - Enable/Disable Leveling (with current values) S1=enable S0=disable (Requires MESH_BED_LEVELING or ABL)
|
||||
@@ -260,7 +261,6 @@
|
||||
* M575 - Change the serial baud rate. (Requires BAUD_RATE_GCODE)
|
||||
* M592 - Get or set nonlinear extrusion parameters. (Requires NONLINEAR_EXTRUSION)
|
||||
* M593 - Get or set input shaping parameters. (Requires INPUT_SHAPING_[XY])
|
||||
* M591 - Configure Filament Runout Detection. (Requires FILAMENT_RUNOUT_SENSOR)
|
||||
* M600 - Pause for filament change: "M600 X<pos> Y<pos> Z<raise> E<first_retract> L<later_retract>". (Requires ADVANCED_PAUSE_FEATURE)
|
||||
* M603 - Configure filament change: "M603 T<tool> U<unload_length> L<load_length>". (Requires ADVANCED_PAUSE_FEATURE)
|
||||
* M605 - Set Dual X-Carriage movement mode: "M605 S<mode> [X<x_offset>] [R<temp_offset>]". (Requires DUAL_X_CARRIAGE)
|
||||
@@ -1035,9 +1035,8 @@ private:
|
||||
#endif
|
||||
|
||||
#if HAS_FILAMENT_SENSOR
|
||||
static void M412() { M591(); }
|
||||
static void M591();
|
||||
static void M591_report(const bool forReplay=true);
|
||||
static void M412();
|
||||
static void M412_report(const bool forReplay=true);
|
||||
#endif
|
||||
|
||||
#if HAS_MULTI_LANGUAGE
|
||||
@@ -1277,6 +1276,10 @@ private:
|
||||
static void M1002();
|
||||
#endif
|
||||
|
||||
#if ENABLED(ONE_CLICK_PRINT)
|
||||
static void M1003();
|
||||
#endif
|
||||
|
||||
#if ENABLED(UBL_MESH_WIZARD)
|
||||
static void M1004();
|
||||
#endif
|
||||
|
||||
@@ -24,11 +24,19 @@
|
||||
#include "../queue.h" // for last_N
|
||||
|
||||
/**
|
||||
* M110: Set Current Line Number
|
||||
* M110: Get or set Current Line Number
|
||||
*
|
||||
* Parameters:
|
||||
* N<int> Number to set as last-processed command
|
||||
*
|
||||
* Without parameters:
|
||||
* Report the last-processed (not last-received or last-enqueued) command
|
||||
* (To purge the queue and resume from this line, the host should use 'M999' instead.)
|
||||
*/
|
||||
void GcodeSuite::M110() {
|
||||
|
||||
if (parser.seenval('N'))
|
||||
queue.set_current_line_number(parser.value_long());
|
||||
|
||||
else
|
||||
SERIAL_ECHOLNPGM(STR_LINE_NO, queue.get_current_line_number());
|
||||
}
|
||||
|
||||
@@ -154,7 +154,7 @@ void GcodeSuite::M115() {
|
||||
// AUTOLEVEL (G29)
|
||||
cap_line(F("AUTOLEVEL"), ENABLED(HAS_AUTOLEVEL));
|
||||
|
||||
// RUNOUT (M591, M600)
|
||||
// RUNOUT (M412, M600)
|
||||
cap_line(F("RUNOUT"), ENABLED(FILAMENT_RUNOUT_SENSOR));
|
||||
|
||||
// Z_PROBE (G30)
|
||||
|
||||
@@ -55,7 +55,7 @@ inline bool G38_run_probe() {
|
||||
}
|
||||
#endif
|
||||
|
||||
planner.synchronize(); // wait until the machine is idle
|
||||
planner.synchronize(); // Wait until the machine is idle
|
||||
|
||||
// Move flag value
|
||||
#if ENABLED(G38_PROBE_AWAY)
|
||||
|
||||
@@ -54,6 +54,21 @@ void mpe_settings_init() {
|
||||
mpe_settings_report();
|
||||
}
|
||||
|
||||
/**
|
||||
* M951: Magnetic Parking Extruder
|
||||
*
|
||||
* Parameters:
|
||||
* L<linear> : Set X[0] position
|
||||
* R<linear> : Set X[1] position
|
||||
* I<linear> : Set grab distance
|
||||
* J<feedrate> : Set slow feedrate
|
||||
* H<feedrate> : Set fast feedrate
|
||||
* D<feedrate> : Set travel feedrate
|
||||
* C<factor> : Set compensation factor
|
||||
*
|
||||
* With no parameters report the current settings.
|
||||
*
|
||||
*/
|
||||
void GcodeSuite::M951() {
|
||||
if (parser.seenval('L')) mpe_settings.parking_xpos[0] = parser.value_linear_units();
|
||||
if (parser.seenval('R')) mpe_settings.parking_xpos[1] = parser.value_linear_units();
|
||||
|
||||
@@ -212,6 +212,11 @@ public:
|
||||
*/
|
||||
static void set_current_line_number(long n) { serial_state[ring_buffer.command_port().index].last_N = n; }
|
||||
|
||||
/**
|
||||
* Get the current line number for the last received command
|
||||
*/
|
||||
static long get_current_line_number() { return serial_state[ring_buffer.command_port().index].last_N; }
|
||||
|
||||
#if ENABLED(BUFFER_MONITORING)
|
||||
|
||||
private:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user