diff --git a/.editorconfig b/.editorconfig
index a0fa3eff170e..b8f6ef7f8e32 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -4,10 +4,10 @@ root = true
[{*.patch,syntax_test_*}]
trim_trailing_whitespace = false
-[{*.c,*.cpp,*.h}]
+[{*.c,*.cpp,*.h,*.ino}]
charset = utf-8
-[{*.c,*.cpp,*.h,Makefile}]
+[{*.c,*.cpp,*.h,*.ino,Makefile}]
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
diff --git a/.gitattributes b/.gitattributes
index 2588229e0544..83897cba6ed3 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -17,3 +17,5 @@
*.png binary
*.jpg binary
*.fon binary
+*.bin binary
+*.woff binary
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 6e735974a921..000000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-name: Bug report
-about: Report a bug in Marlin
-title: "[BUG] (short description)"
-labels: ''
-assignees: ''
-
----
-
-
-
-### Bug Description
-
-
-
-### Configuration Files
-
-**Required:** Include a ZIP file containing `Configuration.h` and `Configuration_adv.h`.
-
-If you've made any other modifications describe them in detail here.
-
-### Steps to Reproduce
-
-
-
-1. [First Step]
-2. [Second Step]
-3. [and so on...]
-
-**Expected behavior:**
-
-
-
-**Actual behavior:**
-
-
-
-#### Additional Information
-
-* Provide pictures or links to videos that clearly demonstrate the issue.
-* See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/2.0.x/.github/contributing.md) for additional guidelines.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000000..0e6028a31df7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,169 @@
+name: 🪲 Report a bug
+description: Create a bug report to help improve Marlin Firmware
+title: "[BUG] (bug summary)"
+body:
+ - type: markdown
+ attributes:
+ value: >
+ Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose).
+
+ - type: markdown
+ attributes:
+ value: |
+ **Thank you for reporting a bug in Marlin Firmware!**
+
+ ## Before Reporting a Bug
+
+ - Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
+
+ - Test with the [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see whether the issue still exists.
+
+ ## Instructions
+
+ Please follow the instructions below. Failure to do so may result in your issue being closed. See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/2.0.x/.github/contributing.md) for additional guidelines.
+
+ 1. Provide a good title starting with [BUG].
+ 2. Fill out all sections of this bug report form.
+ 3. Always attach configuration files so we can build and test your setup.
+
+ - type: dropdown
+ attributes:
+ label: Did you test the latest `bugfix-2.0.x` code?
+ description: >-
+ Always try the latest code to make sure the issue you are reporting is not already fixed. To download
+ the latest code just [click this link](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip).
+ options:
+ - Yes, and the problem still exists.
+ - No, but I will test it now!
+ validations:
+ required: true
+
+ - type: markdown
+ attributes:
+ value: |
+ # Bug Details
+
+ - type: textarea
+ attributes:
+ label: Bug Description
+ description: >-
+ Describe the bug in this section. Tell us what you were trying to do and what
+ happened that you did not expect. Provide a clear and concise description of the
+ problem and include as many details as possible.
+ placeholder: |
+ Marlin doesn't work.
+ validations:
+ required: true
+
+ - type: input
+ attributes:
+ label: Bug Timeline
+ description: Is this a new bug or an old issue? When did it first start?
+
+ - type: textarea
+ attributes:
+ label: Expected behavior
+ description: >-
+ What did you expect to happen?
+ placeholder: I expected it to move left.
+
+ - type: textarea
+ attributes:
+ label: Actual behavior
+ description: What actually happened instead?
+ placeholder: It moved right instead of left.
+
+ - type: textarea
+ attributes:
+ label: Steps to Reproduce
+ description: >-
+ Please describe the steps needed to reproduce the issue.
+ placeholder: |
+ 1. [First Step] ...
+ 2. [Second Step] ...
+ 3. [and so on] ...
+
+ - type: markdown
+ attributes:
+ value: |
+ # Your Setup
+
+ - type: input
+ attributes:
+ label: Version of Marlin Firmware
+ description: "See the About Menu on the LCD or the output of `M115`. NOTE: For older releases we only patch critical bugs."
+ validations:
+ required: true
+
+ - type: input
+ attributes:
+ label: Printer model
+ description: Creality Ender 3, Prusa mini, or Kossel Delta?
+
+ - type: input
+ attributes:
+ label: Electronics
+ description: Stock electronics, upgrade board, or something else?
+
+ - type: input
+ attributes:
+ label: Add-ons
+ description: Please list any hardware add-ons that could be involved.
+
+ - type: dropdown
+ attributes:
+ label: Bed Leveling
+ description: What kind of bed leveling compensation are you using?
+ options:
+ - UBL Bilinear mesh
+ - ABL Bilinear mesh
+ - ABL Linear grid
+ - ABL 3-point
+ - MBL Manual Bed Leveling
+ - No Bed Leveling
+
+ - type: dropdown
+ attributes:
+ label: Your Slicer
+ description: Do you use Slic3r, Prusa Slicer, Simplify3D, IdeaMaker...?
+ options:
+ - Slic3r
+ - Simplify3D
+ - Prusa Slicer
+ - IdeaMaker
+ - Cura
+ - Other (explain below)
+
+ - type: dropdown
+ attributes:
+ label: Host Software
+ description: Do you use OctoPrint, Repetier Host, Pronterface...?
+ options:
+ - SD Card (headless)
+ - Repetier Host
+ - OctoPrint
+ - Pronterface
+ - Cura
+ - Same as my slicer
+ - Other (explain below)
+
+ - type: markdown
+ attributes:
+ value: >-
+ ## Other things to include
+
+ Please also be sure to include these items to help with troubleshooting:
+
+ * **A ZIP file** containing your `Configuration.h` and `Configuration_adv.h`.
+ (Please don't paste lengthy configuration text here.)
+ * **Log output** from the host. (`M111 S247` for maximum logging.)
+ * **Images or videos** demonstrating the problem, if it helps to make it clear.
+ * **A G-Code file** that exposes the problem, if not affecting _all_ G-code.
+
+ If you've made any other modifications to the firmware, please describe them in detail in the space provided.
+
+ When pasting formatted text into the box below don't forget to put ` ``` ` (on its own line) before and after to make it readable.
+
+ - type: textarea
+ attributes:
+ label: Additional information & file uploads
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index 4b283d26005c..3f5d6fe5517d 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,17 +1,20 @@
blank_issues_enabled: false
contact_links:
- - name: Marlin Documentation
+ - name: 📖 Marlin Documentation
url: http://marlinfw.org/
about: Lots of documentation on installing and using Marlin.
- - name: MarlinFirmware Facebook group
+ - name: 👤 MarlinFirmware Facebook group
url: https://www.facebook.com/groups/1049718498464482
about: Please ask and answer questions here.
- - name: Marlin on Discord
+ - name: 🕹 Marlin on Discord
url: https://discord.gg/n5NJ59y
about: Join the Discord server for support and discussion.
- - name: Marlin Discussion Forum
+ - name: 🔗 Marlin Discussion Forum
url: http://forums.reprap.org/list.php?415
about: A searchable web forum hosted by RepRap dot org.
- - name: Marlin Videos on YouTube
+ - name: 📺 Marlin Videos on YouTube
url: https://www.youtube.com/results?search_query=marlin+firmware
about: Tutorials and more from Marlin users all around the world. Great for new users!
+ - name: 💸 Want to donate?
+ url: https://www.thinkyhead.com/donate-to-marlin
+ about: Please take a look at the various options to support Marlin Firmware's development financially!
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index 24de8d01419b..000000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-name: Feature request
-about: Request a Feature
-title: "[FR] (feature request title)"
-labels: 'T: Feature Request'
-assignees: ''
-
----
-
-
-
-### Description
-
-
-
-### Feature Workflow
-
-
-
-1. [First Action]
-2. [Second Action]
-3. [and so on...]
-
-#### Additional Information
-
-* Provide pictures or links that demonstrate a similar feature or concept.
-* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
new file mode 100644
index 000000000000..df1938ccd84a
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -0,0 +1,44 @@
+name: ✨ Request a feature
+description: Request a new Marlin Firmware feature
+title: "[FR] (feature summary)"
+labels: 'T: Feature Request'
+body:
+ - type: markdown
+ attributes:
+ value: >
+ Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose).
+
+ - type: markdown
+ attributes:
+ value: >
+ **Thank you for requesting a new Marlin Firmware feature!**
+
+ ## Before Requesting a Feature
+
+ - Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
+
+ - Check the latest [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see if the feature already exists.
+
+ - Before you proceed with your request, please consider if it is necessary to make it into a firmware feature, or if it may be better suited for a slicer or host feature.
+
+ - type: textarea
+ attributes:
+ label: Is your feature request related to a problem? Please describe.
+ description: A clear description of the problem (e.g., "I need X but Marlin can't do it [...]").
+
+ - type: textarea
+ attributes:
+ label: Are you looking for hardware support?
+ description: Tell us the printer, board, or peripheral that needs support.
+
+ - type: textarea
+ attributes:
+ label: Describe the feature you want
+ description: A clear description of the feature and how you think it should work.
+ validations:
+ required: true
+
+ - type: textarea
+ attributes:
+ label: Additional context
+ description: Add any other context or screenshots about the feature request here.
diff --git a/.github/issue_template.md b/.github/issue_template.md
index a211ca5e2715..6cb34b8f588a 100644
--- a/.github/issue_template.md
+++ b/.github/issue_template.md
@@ -1,11 +1,35 @@
-# NO SUPPORT REQUESTS PLEASE
+
+
+### Description
+
+
+
+### Steps to Reproduce
+
+
+
+1. [First Step]
+2. [Second Step]
+3. [and so on...]
+
+**Expected behavior:** [What you expect to happen]
+
+**Actual behavior:** [What actually happens]
+
+#### Additional Information
+
+* Include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files.
+* Provide pictures or links to videos that clearly demonstrate the issue.
+* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index d82fb0f9e37b..cd5158b3ce8c 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,23 +1,33 @@
-### Requirements
+
### Description
+### Requirements
+
+
+
### Benefits
-
+
### Configurations
-
+
### Related Issues
-
+
diff --git a/.github/workflows/bump-date.yml b/.github/workflows/bump-date.yml
index 54902da8c908..a1942777d1ae 100644
--- a/.github/workflows/bump-date.yml
+++ b/.github/workflows/bump-date.yml
@@ -28,6 +28,7 @@ jobs:
# Inline Bump Script
DIST=$( date +"%Y-%m-%d" )
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/src/inc/Version.h" && \
+ eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/Version.h" && \
git config user.name "${GITHUB_ACTOR}" && \
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
git add . && \
diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml
index aa4a2c59c9a4..b30513f7ccb0 100644
--- a/.github/workflows/check-pr.yml
+++ b/.github/workflows/check-pr.yml
@@ -20,9 +20,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- - uses: peter-evans/close-pull@v1
+ - uses: superbrothers/close-pull-request@v3
with:
- delete-branch: false
comment: >
Thanks for your contribution! Unfortunately we can't accept PRs directed at release branches. We make patches to the bugfix branches and only later do we push them out as releases.
diff --git a/.github/workflows/clean-closed.yml b/.github/workflows/clean-closed.yml
new file mode 100644
index 000000000000..befec4498f25
--- /dev/null
+++ b/.github/workflows/clean-closed.yml
@@ -0,0 +1,39 @@
+#
+# clean-closed.yml
+# Remove obsolete labels when an Issue or PR is closed
+#
+
+name: Clean Closed
+
+on:
+ pull_request:
+ types: [closed]
+ issues:
+ types: [closed]
+
+jobs:
+ remove_label:
+ runs-on: ubuntu-latest
+
+ strategy:
+ matrix:
+ label:
+ - "S: Don't Merge"
+ - "S: Hold for 2.1"
+ - "S: Please Merge"
+ - "S: Please Test"
+ - "help wanted"
+ - "Needs: Discussion"
+ - "Needs: Documentation"
+ - "Needs: More Data"
+ - "Needs: Patch"
+ - "Needs: Testing"
+ - "Needs: Work"
+
+ steps:
+ - uses: actions/checkout@v2
+ - name: Remove Labels
+ uses: actions-ecosystem/action-remove-labels@v1
+ with:
+ github_token: ${{ github.token }}
+ labels: ${{ matrix.label }}
diff --git a/.github/workflows/close-stale.yml b/.github/workflows/close-stale.yml
index 89d5d65351d9..f017907d2934 100644
--- a/.github/workflows/close-stale.yml
+++ b/.github/workflows/close-stale.yml
@@ -20,8 +20,9 @@ jobs:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
- stale-issue-message: 'This issue has had no activity in the last 30 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 7 days.'
- days-before-stale: 30
- days-before-close: 7
+ stale-issue-message: 'This issue has had no activity in the last 60 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 10 days.'
+ days-before-stale: 60
+ days-before-close: 10
stale-issue-label: 'stale-closing-soon'
- exempt-issue-labels: 'T: Feature Request'
+ exempt-all-assignees: true
+ exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: Discussion,Needs: Documentation,Needs: More Data,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking'
diff --git a/.github/workflows/lock-closed.yml b/.github/workflows/lock-closed.yml
index 8cdcd7a8369e..81145688288b 100644
--- a/.github/workflows/lock-closed.yml
+++ b/.github/workflows/lock-closed.yml
@@ -22,7 +22,7 @@ jobs:
github-token: ${{ github.token }}
process-only: 'issues'
issue-lock-inactive-days: '60'
- issue-exclude-created-before: ''
+ issue-exclude-created-before: '2017-07-01T00:00:00Z'
issue-exclude-labels: 'no-locking'
issue-lock-labels: ''
issue-lock-comment: >
diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
index b2287837998b..c6afaffebf7a 100644
--- a/.github/workflows/test-builds.yml
+++ b/.github/workflows/test-builds.yml
@@ -36,9 +36,11 @@ jobs:
# Base Environments
- DUE
+ - DUE_archim
- esp32
- linux_native
- mega2560
+ - at90usb1286_dfu
- teensy31
- teensy35
- teensy41
@@ -46,21 +48,34 @@ jobs:
# Extended AVR Environments
- - FYSETC_F6_13
+ - FYSETC_F6
- mega1280
- rambo
- sanguino1284p
- sanguino644p
- # Extended STM32 Environments
+ # STM32F1 (Maple) Environments
+
+ #- STM32F103RC_btt_maple
+ - STM32F103RC_btt_USB_maple
+ - STM32F103RC_fysetc_maple
+ - STM32F103RC_meeb
+ - jgaurora_a5s_a1_maple
+ - STM32F103VE_longer_maple
+ #- mks_robin_maple
+ - mks_robin_lite_maple
+ - mks_robin_pro_maple
+ #- mks_robin_nano35_maple
+ #- STM32F103RET6_creality_maple
+ - STM32F103VE_ZM3E4V2_USB_maple
+
+ # STM32 (ST) Environments
- STM32F103RC_btt
- - STM32F103RC_btt_USB
+ #- STM32F103RC_btt_USB
- STM32F103RE_btt
- STM32F103RE_btt_USB
- - STM32F103RC_fysetc
- - STM32F103RC_meeb
- - jgaurora_a5s_a1
+ - STM32F103RET6_creality
- STM32F103VE_longer
- STM32F407VE_black
- STM32F401VE_STEVAL
@@ -68,40 +83,53 @@ jobs:
- BIGTREE_SKR_PRO
- BIGTREE_GTR_V1_0
- mks_robin
- - mks_robin_stm32
- ARMED
- FYSETC_S6
- STM32F070CB_malyan
- STM32F070RB_malyan
- malyan_M300
- - mks_robin_lite
- FLYF407ZG
- rumba32
- - mks_robin_pro
- - STM32F103RET6_creality
- LERDGEX
+ - LERDGEK
- mks_robin_nano35
+ - NUCLEO_F767ZI
+ - REMRAM_V1
+ - BTT_SKR_SE_BX
+ - chitu_f103
# Put lengthy tests last
- LPC1768
- LPC1769
- # STM32 with non-STM framework. both broken for now. they should use HAL_STM32 which is working.
-
- #- STM32F4
- #- STM32F7
-
# Non-working environment tests
#- at90usb1286_cdc
- #- at90usb1286_dfu
#- STM32F103CB_malyan
+ #- STM32F103RE
#- mks_robin_mini
steps:
+ - name: Check out the PR
+ uses: actions/checkout@v2
+
+ - name: Cache pip
+ uses: actions/cache@v2
+ with:
+ path: ~/.cache/pip
+ key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
+ restore-keys: |
+ ${{ runner.os }}-pip-
+
+ - name: Cache PlatformIO
+ uses: actions/cache@v2
+ with:
+ path: ~/.platformio
+ key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
+
- name: Select Python 3.7
- uses: actions/setup-python@v1
+ uses: actions/setup-python@v2
with:
python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
@@ -111,13 +139,6 @@ jobs:
pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
platformio update
- - name: Check out the PR
- uses: actions/checkout@v2
-
- name: Run ${{ matrix.test-platform }} Tests
run: |
- # Inline tests script
- chmod +x buildroot/bin/*
- chmod +x buildroot/tests/*
- export PATH=./buildroot/bin/:./buildroot/tests/:${PATH}
- run_tests . ${{ matrix.test-platform }}
+ make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
diff --git a/.gitignore b/.gitignore
index c163d339dff3..bc603ba38b0d 100755
--- a/.gitignore
+++ b/.gitignore
@@ -19,9 +19,9 @@
# along with this program. If not, see .
#
-# Our automatic versioning scheme generates the following file
-# NEVER put it in the repository
+# Generated files
_Version.h
+bdf2u8g
#
# OS
@@ -77,7 +77,6 @@ tags
*.out
*.app
-
#
# C
#
@@ -123,33 +122,10 @@ tags
.gcc-flags.json
/lib/
-# Workaround for Deviot+platformio quirks
-Marlin/lib
-Marlin/platformio.ini
-Marlin/*/platformio.ini
-Marlin/*/*/platformio.ini
-Marlin/*/*/*/platformio.ini
-Marlin/*/*/*/*/platformio.ini
-Marlin/.travis.yml
-Marlin/*/.travis.yml
-Marlin/*/*/.travis.yml
-Marlin/*/*/*/.travis.yml
-Marlin/*/*/*/*/.travis.yml
-Marlin/.gitignore
-Marlin/*/.gitignore
-Marlin/*/*/.gitignore
-Marlin/*/*/*/.gitignore
-Marlin/*/*/*/*/.gitignore
-Marlin/readme.txt
-Marlin/*/readme.txt
-Marlin/*/*/readme.txt
-Marlin/*/*/*/readme.txt
-Marlin/*/*/*/*/readme.txt
-
# Secure Credentials
Configuration_Secure.h
-#Visual Studio
+# Visual Studio
*.sln
*.vcxproj
*.vcxproj.user
@@ -160,27 +136,38 @@ __vm/
.vs/
vc-fileutils.settings
-#Visual Studio Code
+# Visual Studio Code
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/*.db
+#Simulation
+imgui.ini
+eeprom.dat
+
#cmake
CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
-#CLion
+# CLion
cmake-build-*
-#Eclipse
+# Eclipse
.project
.cproject
.pydevproject
.settings
.classpath
-#Python
+# Python
__pycache__
+
+# IOLogger logs
+*_log.csv
+
+# Simulation / Native
+eeprom.dat
+imgui.ini
diff --git a/Makefile b/Makefile
new file mode 100644
index 000000000000..ebcdf25e2d6a
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,52 @@
+help:
+ @echo "Tasks for local development:"
+ @echo "* tests-single-ci: Run a single test from inside the CI"
+ @echo "* tests-single-local: Run a single test locally"
+ @echo "* tests-single-local-docker: Run a single test locally, using docker-compose"
+ @echo "* tests-all-local: Run all tests locally"
+ @echo "* tests-all-local-docker: Run all tests locally, using docker-compose"
+ @echo "* setup-local-docker: Setup local docker-compose"
+ @echo ""
+ @echo "Options for testing:"
+ @echo " TEST_TARGET Set when running tests-single-*, to select the"
+ @echo " test. If you set it to ALL it will run all "
+ @echo " tests, but some of them are broken: use "
+ @echo " tests-all-* instead to run only the ones that "
+ @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 " 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!"
+.PHONY: help
+
+tests-single-ci:
+ export GIT_RESET_HARD=true
+ $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET)
+.PHONY: tests-single-ci
+
+tests-single-local:
+ @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET= or use make tests-all-local" ; return 1; fi
+ export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
+ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
+ && run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
+.PHONY: tests-single-local
+
+tests-single-local-docker:
+ @if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET= or use make tests-all-local-docker" ; return 1; fi
+ docker-compose run --rm marlin $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
+.PHONY: tests-single-local-docker
+
+tests-all-local:
+ export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
+ && export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
+ && for TEST_TARGET in $$(./get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
+.PHONY: tests-all-local
+
+tests-all-local-docker:
+ docker-compose run --rm marlin $(MAKE) tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
+.PHONY: tests-all-local-docker
+
+setup-local-docker:
+ docker-compose build
+.PHONY: setup-local-docker
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index cc45fd2fe2cb..6daf93a376d9 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -35,37 +35,36 @@
*
* Advanced settings can be found in Configuration_adv.h
*/
-#define CONFIGURATION_H_VERSION 020008
+#define CONFIGURATION_H_VERSION 02000901
//===========================================================================
//============================= Getting Started =============================
//===========================================================================
/**
- * Here are some standard links for getting your machine calibrated:
+ * Here are some useful links to help get your machine configured and calibrated:
*
- * https://reprap.org/wiki/Calibration
- * https://youtu.be/wAL9d7FgInk
- * http://calculator.josefprusa.cz
- * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
- * https://www.thingiverse.com/thing:5573
- * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
- * https://www.thingiverse.com/thing:298812
+ * Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all
+ *
+ * Průša Calculator: https://blog.prusaprinters.org/calculator_3416/
+ *
+ * Calibration Guides: https://reprap.org/wiki/Calibration
+ * https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
+ * https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
+ * https://youtu.be/wAL9d7FgInk
+ *
+ * Calibration Objects: https://www.thingiverse.com/thing:5573
+ * https://www.thingiverse.com/thing:1278865
*/
//===========================================================================
-//============================= DELTA Printer ===============================
+//========================== DELTA / SCARA / TPARA ==========================
//===========================================================================
-// For a Delta printer start with one of the configuration files in the
-// config/examples/delta directory and customize for your machine.
//
-
-//===========================================================================
-//============================= SCARA Printer ===============================
-//===========================================================================
-// For a SCARA printer start with the configuration files in
-// config/examples/SCARA and customize for your machine.
+// Download configurations from the link above and customize for your machine.
+// Examples are located in config/examples/delta, .../SCARA, and .../TPARA.
//
+//===========================================================================
// @section info
@@ -106,14 +105,9 @@
#define SERIAL_PORT 0
/**
- * Select a secondary serial port on the board to use for communication with the host.
- * Currently Ethernet (-2) is only supported on Teensy 4.1 boards.
- * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
- */
-//#define SERIAL_PORT_2 -1
-
-/**
- * This setting determines the communication speed of the printer.
+ * Serial Port Baud Rate
+ * This is the default communication speed for all serial ports.
+ * Set the baud rate defaults for additional serial ports below.
*
* 250000 works in most cases, but you might try a lower speed if
* you commonly experience drop-outs during host printing.
@@ -122,6 +116,23 @@
* :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
*/
#define BAUDRATE 250000
+//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate
+
+/**
+ * Select a secondary serial port on the board to use for communication with the host.
+ * Currently Ethernet (-2) is only supported on Teensy 4.1 boards.
+ * :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
+ */
+//#define SERIAL_PORT_2 -1
+//#define BAUDRATE_2 250000 // Enable to override BAUDRATE
+
+/**
+ * Select a third serial port on the board to use for communication with the host.
+ * Currently only supported for AVR, DUE, LPC1768/9 and STM32/STM32F1
+ * :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
+ */
+//#define SERIAL_PORT_3 1
+//#define BAUDRATE_3 250000 // Enable to override BAUDRATE
// Enable the Bluetooth serial interface on AT90USB devices
//#define BLUETOOTH
@@ -138,6 +149,45 @@
// Choose your own or use a service like https://www.uuidgenerator.net/version4
//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
+/**
+ * Define the number of coordinated linear axes.
+ * See https://github.com/DerAndere1/Marlin/wiki
+ * Each linear axis gets its own stepper control and endstop:
+ *
+ * Steppers: *_STEP_PIN, *_ENABLE_PIN, *_DIR_PIN, *_ENABLE_ON
+ * Endstops: *_STOP_PIN, USE_*MIN_PLUG, USE_*MAX_PLUG
+ * Axes: *_MIN_POS, *_MAX_POS, INVERT_*_DIR
+ * Planner: DEFAULT_AXIS_STEPS_PER_UNIT, DEFAULT_MAX_FEEDRATE
+ * DEFAULT_MAX_ACCELERATION, AXIS_RELATIVE_MODES,
+ * MICROSTEP_MODES, MANUAL_FEEDRATE
+ *
+ * :[3, 4, 5, 6]
+ */
+//#define LINEAR_AXES 3
+
+/**
+ * Axis codes for additional axes:
+ * This defines the axis code that is used in G-code commands to
+ * reference a specific axis.
+ * 'A' for rotational axis parallel to X
+ * 'B' for rotational axis parallel to Y
+ * 'C' for rotational axis parallel to Z
+ * 'U' for secondary linear axis parallel to X
+ * 'V' for secondary linear axis parallel to Y
+ * 'W' for secondary linear axis parallel to Z
+ * Regardless of the settings, firmware-internal axis IDs are
+ * I (AXIS4), J (AXIS5), K (AXIS6).
+ */
+#if LINEAR_AXES >= 4
+ #define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W']
+#endif
+#if LINEAR_AXES >= 5
+ #define AXIS5_NAME 'B' // :['A', 'B', 'C', 'U', 'V', 'W']
+#endif
+#if LINEAR_AXES >= 6
+ #define AXIS6_NAME 'C' // :['A', 'B', 'C', 'U', 'V', 'W']
+#endif
+
// @section extruder
// This defines the number of extruders
@@ -158,33 +208,19 @@
#endif
/**
- * Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants.
+ * Multi-Material Unit
+ * Set to one of these predefined models:
*
- * This device allows one stepper driver on a control board to drive
- * two to eight stepper motors, one at a time, in a manner suitable
- * for extruders.
- *
- * This option only allows the multiplexer to switch on tool-change.
- * Additional options to configure custom E moves are pending.
- */
-//#define MK2_MULTIPLEXER
-#if ENABLED(MK2_MULTIPLEXER)
- // Override the default DIO selector pins here, if needed.
- // Some pins files may provide defaults for these pins.
- //#define E_MUX0_PIN 40 // Always Required
- //#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs
- //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs
-#endif
-
-/**
- * Průša Multi-Material Unit v2
+ * PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version)
+ * PRUSA_MMU2 : Průša MMU2
+ * PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5)
+ * EXTENDABLE_EMU_MMU2 : MMU with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware)
+ * EXTENDABLE_EMU_MMU2S : MMUS with configurable number of filaments (ERCF, SMuFF or similar with Průša MMU2 compatible firmware)
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
- * Requires EXTRUDERS = 5
- *
- * For additional configuration see Configuration_adv.h
+ * See additional options in Configuration_adv.h.
*/
-//#define PRUSA_MMU2
+//#define MMU_MODEL PRUSA_MMU2
// A dual extruder that uses a single stepper motor
//#define SWITCHING_EXTRUDER
@@ -344,8 +380,10 @@
#define AUTO_POWER_E_FANS
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
+ #define AUTO_POWER_COOLER_FAN
//#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
+ //#define AUTO_POWER_COOLER_TEMP 26 // (°C) Turn on PSU if the cooler is over this temperature
#define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
//#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
@@ -357,68 +395,92 @@
// @section temperature
/**
- * --NORMAL IS 4.7kohm PULLUP!-- 1kohm pullup can be used on hotend sensor, using correct resistor and table
+ * --NORMAL IS 4.7kΩ PULLUP!-- 1kΩ pullup can be used on hotend sensor, using correct resistor and table
*
* Temperature sensors available:
*
- * -5 : PT100 / PT1000 with MAX31865 (only for sensors 0-1)
- * -3 : thermocouple with MAX31855 (only for sensors 0-1)
- * -2 : thermocouple with MAX6675 (only for sensors 0-1)
- * -4 : thermocouple with AD8495
- * -1 : thermocouple with AD595
+ * SPI RTD/Thermocouple Boards - IMPORTANT: Read the NOTE below!
+ * -------
+ * -5 : MAX31865 with Pt100/Pt1000, 2, 3, or 4-wire (only for sensors 0-1)
+ * NOTE: You must uncomment/set the MAX31865_*_OHMS_n defines below.
+ * -3 : MAX31855 with Thermocouple, -200°C to +700°C (only for sensors 0-1)
+ * -2 : MAX6675 with Thermocouple, 0°C to +700°C (only for sensors 0-1)
+ *
+ * NOTE: Ensure TEMP_n_CS_PIN is set in your pins file for each TEMP_SENSOR_n using an SPI Thermocouple. By default,
+ * Hardware SPI on the default serial bus is used. If you have also set TEMP_n_SCK_PIN and TEMP_n_MISO_PIN,
+ * Software SPI will be used on those ports instead. You can force Hardware SPI on the default bus in the
+ * Configuration_adv.h file. At this time, separate Hardware SPI buses for sensors are not supported.
+ *
+ * Analog Themocouple Boards
+ * -------
+ * -4 : AD8495 with Thermocouple
+ * -1 : AD595 with Thermocouple
+ *
+ * Analog Thermistors - 4.7kΩ pullup - Normal
+ * -------
+ * 1 : 100kΩ EPCOS - Best choice for EPCOS thermistors
+ * 331 : 100kΩ Same as #1, but 3.3V scaled for MEGA
+ * 332 : 100kΩ Same as #1, but 3.3V scaled for DUE
+ * 2 : 200kΩ ATC Semitec 204GT-2
+ * 202 : 200kΩ Copymaster 3D
+ * 3 : ???Ω Mendel-parts thermistor
+ * 4 : 10kΩ Generic Thermistor !! DO NOT use for a hotend - it gives bad resolution at high temp. !!
+ * 5 : 100kΩ ATC Semitec 104GT-2/104NT-4-R025H42G - Used in ParCan, J-Head, and E3D, SliceEngineering 300°C
+ * 501 : 100kΩ Zonestar - Tronxy X3A
+ * 502 : 100kΩ Zonestar - used by hot bed in Zonestar Průša P802M
+ * 512 : 100kΩ RPW-Ultra hotend
+ * 6 : 100kΩ EPCOS - Not as accurate as table #1 (created using a fluke thermocouple)
+ * 7 : 100kΩ Honeywell 135-104LAG-J01
+ * 71 : 100kΩ Honeywell 135-104LAF-J01
+ * 8 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT
+ * 9 : 100kΩ GE Sensing AL03006-58.2K-97-G1
+ * 10 : 100kΩ RS PRO 198-961
+ * 11 : 100kΩ Keenovo AC silicone mats, most Wanhao i3 machines - beta 3950, 1%
+ * 12 : 100kΩ Vishay 0603 SMD NTCS0603E3104FXT (#8) - calibrated for Makibox hot bed
+ * 13 : 100kΩ Hisens up to 300°C - for "Simple ONE" & "All In ONE" hotend - beta 3950, 1%
+ * 15 : 100kΩ Calibrated for JGAurora A5 hotend
+ * 18 : 200kΩ ATC Semitec 204GT-2 Dagoma.Fr - MKS_Base_DKU001327
+ * 22 : 100kΩ GTM32 Pro vB - hotend - 4.7kΩ pullup to 3.3V and 220Ω to analog input
+ * 23 : 100kΩ GTM32 Pro vB - bed - 4.7kΩ pullup to 3.3v and 220Ω to analog input
+ * 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950
+ * 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950
+ * 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
+ * 66 : 4.7MΩ Dyze Design High Temperature Thermistor
+ * 67 : 500kΩ SliceEngineering 450°C Thermistor
+ * 70 : 100kΩ bq Hephestos 2
+ * 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32
+ *
+ * Analog Thermistors - 1kΩ pullup - Atypical, and requires changing out the 4.7kΩ pullup for 1kΩ.
+ * ------- (but gives greater accuracy and more stable PID)
+ * 51 : 100kΩ EPCOS (1kΩ pullup)
+ * 52 : 200kΩ ATC Semitec 204GT-2 (1kΩ pullup)
+ * 55 : 100kΩ ATC Semitec 104GT-2 - Used in ParCan & J-Head (1kΩ pullup)
+ *
+ * Analog Thermistors - 10kΩ pullup - Atypical
+ * -------
+ * 99 : 100kΩ Found on some Wanhao i3 machines with a 10kΩ pull-up resistor
+ *
+ * Analog RTDs (Pt100/Pt1000)
+ * -------
+ * 110 : Pt100 with 1kΩ pullup (atypical)
+ * 147 : Pt100 with 4.7kΩ pullup
+ * 1010 : Pt1000 with 1kΩ pullup (atypical)
+ * 1047 : Pt1000 with 4.7kΩ pullup (E3D)
+ * 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
+ * NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
+ * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply.
+ * NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C.
+ * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x
+ *
+ * Custom/Dummy/Other Thermos
+ * ------
* 0 : not used
- * 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
- * 331 : (3.3V scaled thermistor 1 table for MEGA)
- * 332 : (3.3V scaled thermistor 1 table for DUE)
- * 2 : 200k thermistor - ATC Semitec 204GT-2 (4.7k pullup)
- * 202 : 200k thermistor - Copymaster 3D
- * 3 : Mendel-parts thermistor (4.7k pullup)
- * 4 : 10k thermistor !! do not use it for a hotend. It gives bad resolution at high temp. !!
- * 5 : 100K thermistor - ATC Semitec 104GT-2/104NT-4-R025H42G (Used in ParCan, J-Head, and E3D) (4.7k pullup)
- * 501 : 100K Zonestar (Tronxy X3A) Thermistor
- * 502 : 100K Zonestar Thermistor used by hot bed in Zonestar Průša P802M
- * 512 : 100k RPW-Ultra hotend thermistor (4.7k pullup)
- * 6 : 100k EPCOS - Not as accurate as table 1 (created using a fluke thermocouple) (4.7k pullup)
- * 7 : 100k Honeywell thermistor 135-104LAG-J01 (4.7k pullup)
- * 71 : 100k Honeywell thermistor 135-104LAF-J01 (4.7k pullup)
- * 8 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup)
- * 9 : 100k GE Sensing AL03006-58.2K-97-G1 (4.7k pullup)
- * 10 : 100k RS thermistor 198-961 (4.7k pullup)
- * 11 : 100k beta 3950 1% thermistor (Used in Keenovo AC silicone mats and most Wanhao i3 machines) (4.7k pullup)
- * 12 : 100k 0603 SMD Vishay NTCS0603E3104FXT (4.7k pullup) (calibrated for Makibox hot bed)
- * 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
- * 15 : 100k thermistor calibration for JGAurora A5 hotend
- * 18 : ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327
- * 20 : Pt100 with circuit in the Ultimainboard V2.x with 5v excitation (AVR)
- * 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v excitation (STM32 \ LPC176x....)
- * 22 : 100k (hotend) with 4.7k pullup to 3.3V and 220R to analog input (as in GTM32 Pro vB)
- * 23 : 100k (bed) with 4.7k pullup to 3.3v and 220R to analog input (as in GTM32 Pro vB)
- * 30 : Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K / B3950 (4.7k pullup)
- * 201 : Pt100 with circuit in Overlord, similar to Ultimainboard V2.x
- * 60 : 100k Maker's Tool Works Kapton Bed Thermistor beta=3950
- * 61 : 100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup
- * 66 : 4.7M High Temperature thermistor from Dyze Design
- * 67 : 450C thermistor from SliceEngineering
- * 70 : the 100K thermistor found in the bq Hephestos 2
- * 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor
- * 99 : 100k thermistor with a 10K pull-up resistor (found on some Wanhao i3 machines)
- *
- * 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k.
- * (but gives greater accuracy and more stable PID)
- * 51 : 100k thermistor - EPCOS (1k pullup)
- * 52 : 200k thermistor - ATC Semitec 204GT-2 (1k pullup)
- * 55 : 100k thermistor - ATC Semitec 104GT-2 (Used in ParCan & J-Head) (1k pullup)
- *
- * 1047 : Pt1000 with 4k7 pullup (E3D)
- * 1010 : Pt1000 with 1k pullup (non standard)
- * 147 : Pt100 with 4k7 pullup
- * 110 : Pt100 with 1k pullup (non standard)
- *
* 1000 : Custom - Specify parameters in Configuration_adv.h
*
- * Use these for Testing or Development purposes. NEVER for production machine.
+ * !!! Use these for Testing or Development purposes. NEVER for production machine. !!!
* 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
* 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
+ *
*/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
@@ -431,29 +493,52 @@
#define TEMP_SENSOR_BED 1
#define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 0
+#define TEMP_SENSOR_COOLER 0
+#define TEMP_SENSOR_REDUNDANT 0
// Dummy thermistor constant temperature readings, for use with 998 and 999
-#define DUMMY_THERMISTOR_998_VALUE 25
+#define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_999_VALUE 100
-// Resistor values when using a MAX31865 (sensor -5)
-// Sensor value is typically 100 (PT100) or 1000 (PT1000)
-// Calibration value is typically 430 ohm for AdaFruit PT100 modules and 4300 ohm for AdaFruit PT1000 modules.
-//#define MAX31865_SENSOR_OHMS 100
-//#define MAX31865_CALIBRATION_OHMS 430
+// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1
+//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
+//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000
+//#define MAX31865_SENSOR_OHMS_1 100
+//#define MAX31865_CALIBRATION_OHMS_1 430
-// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings
-// from the two sensors differ too much the print will be aborted.
-//#define TEMP_SENSOR_1_AS_REDUNDANT
-#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10
+#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
+#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
+#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
-#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
-#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
-#define TEMP_HYSTERESIS 5 // (°C) Temperature proximity considered "close enough" to the target
+#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
+#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
+#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
-#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
-#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
-#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
+#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
+#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
+#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
+
+/**
+ * Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT)
+ *
+ * Use a temp sensor as a redundant sensor for another reading. Select an unused temperature sensor, and another
+ * sensor you'd like it to be redundant for. If the two thermistors differ by TEMP_SENSOR_REDUNDANT_MAX_DIFF (°C),
+ * the print will be aborted. Whichever sensor is selected will have its normal functions disabled; i.e. selecting
+ * the Bed sensor (-1) will disable bed heating/monitoring.
+ *
+ * Use the following to select temp sensors:
+ * -5 : Cooler
+ * -4 : Probe
+ * -3 : not used
+ * -2 : Chamber
+ * -1 : Bed
+ * 0-7 : E0 through E7
+ */
+#if TEMP_SENSOR_REDUNDANT
+ #define TEMP_SENSOR_REDUNDANT_SOURCE 1 // The sensor that will provide the redundant reading.
+ #define TEMP_SENSOR_REDUNDANT_TARGET 0 // The sensor that we are providing a redundant reading for.
+ #define TEMP_SENSOR_REDUNDANT_MAX_DIFF 10 // (°C) Temperature difference that will trigger a print abort.
+#endif
// Below this temperature the heater will be switched off
// because it probably indicates a broken thermistor wire.
@@ -466,6 +551,7 @@
#define HEATER_6_MINTEMP 5
#define HEATER_7_MINTEMP 5
#define BED_MINTEMP 5
+#define CHAMBER_MINTEMP 5
// Above this temperature the heater will be switched off.
// This can protect components from overheating, but NOT from shorts and failures.
@@ -479,6 +565,17 @@
#define HEATER_6_MAXTEMP 275
#define HEATER_7_MAXTEMP 275
#define BED_MAXTEMP 150
+#define CHAMBER_MAXTEMP 60
+
+/**
+ * Thermal Overshoot
+ * During heatup (and printing) the temperature can often "overshoot" the target by many degrees
+ * (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees
+ * a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP.
+ */
+#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
+#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
+#define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT
//===========================================================================
//============================= PID Settings ================================
@@ -552,7 +649,51 @@
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
-#if EITHER(PIDTEMP, PIDTEMPBED)
+//===========================================================================
+//==================== PID > Chamber Temperature Control ====================
+//===========================================================================
+
+/**
+ * PID Chamber Heating
+ *
+ * If this option is enabled set PID constants below.
+ * If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable
+ * hysteresis.
+ *
+ * The PID frequency will be the same as the extruder PWM.
+ * If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz,
+ * which is fine for driving a square wave into a resistive load and does not significantly
+ * impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W
+ * heater. If your configuration is significantly different than this and you don't understand
+ * the issues involved, don't use chamber PID until someone else verifies that your hardware works.
+ */
+//#define PIDTEMPCHAMBER
+//#define CHAMBER_LIMIT_SWITCHING
+
+/**
+ * Max Chamber Power
+ * Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis).
+ * When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider
+ * so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER)
+ */
+#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current
+
+#if ENABLED(PIDTEMPCHAMBER)
+ #define MIN_CHAMBER_POWER 0
+ //#define PID_CHAMBER_DEBUG // Sends debug data to the serial port.
+
+ // Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
+ // and placed inside the small Creality printer enclosure tent.
+ //
+ #define DEFAULT_chamberKp 37.04
+ #define DEFAULT_chamberKi 1.40
+ #define DEFAULT_chamberKd 655.17
+ // M309 P37.04 I1.04 D655.17
+
+ // FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles.
+#endif // PIDTEMPCHAMBER
+
+#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
@@ -599,6 +740,7 @@
#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders
#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed
#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber
+#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling
//===========================================================================
//============================= Mechanical Settings =========================
@@ -628,9 +770,15 @@
#define USE_XMIN_PLUG
#define USE_YMIN_PLUG
#define USE_ZMIN_PLUG
+//#define USE_IMIN_PLUG
+//#define USE_JMIN_PLUG
+//#define USE_KMIN_PLUG
//#define USE_XMAX_PLUG
//#define USE_YMAX_PLUG
//#define USE_ZMAX_PLUG
+//#define USE_IMAX_PLUG
+//#define USE_JMAX_PLUG
+//#define USE_KMAX_PLUG
// Enable pullup for all endstops to prevent a floating state
#define ENDSTOPPULLUPS
@@ -639,9 +787,15 @@
//#define ENDSTOPPULLUP_XMAX
//#define ENDSTOPPULLUP_YMAX
//#define ENDSTOPPULLUP_ZMAX
+ //#define ENDSTOPPULLUP_IMAX
+ //#define ENDSTOPPULLUP_JMAX
+ //#define ENDSTOPPULLUP_KMAX
//#define ENDSTOPPULLUP_XMIN
//#define ENDSTOPPULLUP_YMIN
//#define ENDSTOPPULLUP_ZMIN
+ //#define ENDSTOPPULLUP_IMIN
+ //#define ENDSTOPPULLUP_JMIN
+ //#define ENDSTOPPULLUP_KMIN
//#define ENDSTOPPULLUP_ZMIN_PROBE
#endif
@@ -652,9 +806,15 @@
//#define ENDSTOPPULLDOWN_XMAX
//#define ENDSTOPPULLDOWN_YMAX
//#define ENDSTOPPULLDOWN_ZMAX
+ //#define ENDSTOPPULLDOWN_IMAX
+ //#define ENDSTOPPULLDOWN_JMAX
+ //#define ENDSTOPPULLDOWN_KMAX
//#define ENDSTOPPULLDOWN_XMIN
//#define ENDSTOPPULLDOWN_YMIN
//#define ENDSTOPPULLDOWN_ZMIN
+ //#define ENDSTOPPULLDOWN_IMIN
+ //#define ENDSTOPPULLDOWN_JMIN
+ //#define ENDSTOPPULLDOWN_KMIN
//#define ENDSTOPPULLDOWN_ZMIN_PROBE
#endif
@@ -662,9 +822,15 @@
#define X_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
+#define I_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
+#define J_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
+#define K_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
+#define I_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
+#define J_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
+#define K_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe.
/**
@@ -693,6 +859,9 @@
#define Z2_DRIVER_TYPE TMC2100
//#define Z3_DRIVER_TYPE A4988
//#define Z4_DRIVER_TYPE A4988
+//#define I_DRIVER_TYPE A4988
+//#define J_DRIVER_TYPE A4988
+//#define K_DRIVER_TYPE A4988
#define E0_DRIVER_TYPE TMC2100
//#define E1_DRIVER_TYPE A4988
//#define E2_DRIVER_TYPE A4988
@@ -746,7 +915,7 @@
/**
* Default Axis Steps Per Unit (steps/mm)
* Override with M92
- * X, Y, Z, E0 [, E1[, E2...]]
+ * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80.121, 80.121, 399.778, 414.26 }
// default config was E445, calibrated via https://teachingtechyt.github.io/calibration.html#esteps
@@ -754,7 +923,7 @@
/**
* Default Max Feed Rate (mm/s)
* Override with M203
- * X, Y, Z, E0 [, E1[, E2...]]
+ * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_FEEDRATE { 300, 300, 50, 40 }
@@ -767,7 +936,7 @@
* Default Max Acceleration (change/s) change = mm/s
* (Maximum start speed for accelerated moves)
* Override with M201
- * X, Y, Z, E0 [, E1[, E2...]]
+ * X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_ACCELERATION { 2000, 2000, 100, 10000 }
@@ -801,6 +970,9 @@
#define DEFAULT_XJERK 8.0
#define DEFAULT_YJERK 8.0
#define DEFAULT_ZJERK 0.3
+ //#define DEFAULT_IJERK 0.3
+ //#define DEFAULT_JJERK 0.3
+ //#define DEFAULT_KJERK 0.3
//#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves
@@ -884,7 +1056,6 @@
* or (with LCD_BED_LEVELING) the LCD controller.
*/
//#define PROBE_MANUALLY
-//#define MANUAL_PROBE_START_Z 0.2
/**
* A Fix-Mounted Probe either doesn't deploy or needs manual deployment.
@@ -909,11 +1080,6 @@
*/
//#define BLTOUCH
-/**
- * Pressure sensor with a BLTouch-like interface
- */
-//#define CREALITY_TOUCH
-
/**
* Touch-MI Probe by hotends.fr
*
@@ -946,7 +1112,7 @@
#endif
// Duet Smart Effector (for delta printers) - https://bit.ly/2ul5U7J
-// When the pin is defined you can use M672 to set/reset the probe sensivity.
+// When the pin is defined you can use M672 to set/reset the probe sensitivity.
//#define DUET_SMART_EFFECTOR
#if ENABLED(DUET_SMART_EFFECTOR)
#define SMART_EFFECTOR_MOD_PIN -1 // Connect a GPIO pin to the Smart Effector MOD pin
@@ -967,10 +1133,20 @@
/**
* Nozzle-to-Probe offsets { X, Y, Z }
*
- * - Use a caliper or ruler to measure the distance from the tip of
+ * X and Y offset
+ * Use a caliper or ruler to measure the distance from the tip of
* the Nozzle to the center-point of the Probe in the X and Y axes.
+ *
+ * Z offset
* - For the Z offset use your best known value and adjust at runtime.
- * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc.
+ * - Common probes trigger below the nozzle and have negative values for Z offset.
+ * - Probes triggering above the nozzle height are uncommon but do exist. When using
+ * probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES
+ * to avoid collisions during probing.
+ *
+ * Tune and Adjust
+ * - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc.
+ * - PROBE_OFFSET_WIZARD (configuration_adv.h) can be used for setting the Z offset.
*
* Assuming the typical work area orientation:
* - Probe to RIGHT of the Nozzle has a Positive X offset
@@ -1001,13 +1177,40 @@
#define PROBING_MARGIN 10
// X and Y axis travel speed (mm/min) between probes
-#define XY_PROBE_SPEED (133*60)
+#define XY_PROBE_FEEDRATE (133*60)
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
-#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
+#define Z_PROBE_FEEDRATE_FAST (4*60)
// Feedrate (mm/min) for the "accurate" probe of each point
-#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)
+#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 2)
+
+/**
+ * Probe Activation Switch
+ * A switch indicating proper deployment, or an optical
+ * switch triggered when the carriage is near the bed.
+ */
+//#define PROBE_ACTIVATION_SWITCH
+#if ENABLED(PROBE_ACTIVATION_SWITCH)
+ #define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active
+ //#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin
+#endif
+
+/**
+ * Tare Probe (determine zero-point) prior to each probe.
+ * Useful for a strain gauge or piezo sensor that needs to factor out
+ * elements such as cables pulling on the carriage.
+ */
+//#define PROBE_TARE
+#if ENABLED(PROBE_TARE)
+ #define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin
+ #define PROBE_TARE_DELAY 200 // (ms) Delay after tare before
+ #define PROBE_TARE_STATE HIGH // State to write pin for tare
+ //#define PROBE_TARE_PIN PA5 // Override default pin
+ #if ENABLED(PROBE_ACTIVATION_SWITCH)
+ //#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active
+ #endif
+#endif
/**
* Multiple Probing
@@ -1065,23 +1268,38 @@
//#define PROBING_HEATERS_OFF // Turn heaters off when probing
#if ENABLED(PROBING_HEATERS_OFF)
//#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy)
+ //#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude)
#endif
//#define PROBING_FANS_OFF // Turn fans off when probing
-//#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing
+//#define PROBING_ESTEPPERS_OFF // Turn all extruder steppers off when probing
+//#define PROBING_STEPPERS_OFF // Turn all steppers off (unless needed to hold position) when probing (including extruders)
//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors
+// Require minimum nozzle and/or bed temperature for probing
+//#define PREHEAT_BEFORE_PROBING
+#if ENABLED(PREHEAT_BEFORE_PROBING)
+ #define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
+ #define PROBING_BED_TEMP 50
+#endif
+
// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
// :{ 0:'Low', 1:'High' }
#define X_ENABLE_ON 0
#define Y_ENABLE_ON 0
#define Z_ENABLE_ON 0
#define E_ENABLE_ON 0 // For all extruders
+//#define I_ENABLE_ON 0
+//#define J_ENABLE_ON 0
+//#define K_ENABLE_ON 0
// Disable axis steppers immediately when they're not being stepped.
// WARNING: When motors turn off there is a chance of losing position accuracy!
#define DISABLE_X false
#define DISABLE_Y false
#define DISABLE_Z false
+//#define DISABLE_I false
+//#define DISABLE_J false
+//#define DISABLE_K false
// Turn off the display blinking that warns about possible accuracy reduction
//#define DISABLE_REDUCED_ACCURACY_WARNING
@@ -1097,6 +1315,9 @@
#define INVERT_X_DIR false
#define INVERT_Y_DIR false
#define INVERT_Z_DIR true
+//#define INVERT_I_DIR false
+//#define INVERT_J_DIR false
+//#define INVERT_K_DIR false
// @section extruder
@@ -1112,9 +1333,15 @@
// @section homing
-//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed
+//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety.
+//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety.
-//#define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off.
+/**
+ * Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled.
+ * - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed.
+ * - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle.
+ */
+//#define Z_IDLE_HEIGHT Z_HOME_POS
//#define Z_HOMING_HEIGHT 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
// Be sure to have this much clearance over your Z_MAX_POS to prevent grinding.
@@ -1126,10 +1353,13 @@
#define X_HOME_DIR -1
#define Y_HOME_DIR -1
#define Z_HOME_DIR -1
+//#define I_HOME_DIR -1
+//#define J_HOME_DIR -1
+//#define K_HOME_DIR -1
// @section machine
-// The size of the print bed
+// The size of the printable area
#define X_BED_SIZE 220
#define Y_BED_SIZE 230
@@ -1140,6 +1370,12 @@
#define X_MAX_POS X_BED_SIZE
#define Y_MAX_POS Y_BED_SIZE
#define Z_MAX_POS 250
+//#define I_MIN_POS 0
+//#define I_MAX_POS 50
+//#define J_MIN_POS 0
+//#define J_MAX_POS 50
+//#define K_MIN_POS 0
+//#define K_MAX_POS 50
/**
* Software Endstops
@@ -1156,6 +1392,9 @@
#define MIN_SOFTWARE_ENDSTOP_X
#define MIN_SOFTWARE_ENDSTOP_Y
#define MIN_SOFTWARE_ENDSTOP_Z
+ #define MIN_SOFTWARE_ENDSTOP_I
+ #define MIN_SOFTWARE_ENDSTOP_J
+ #define MIN_SOFTWARE_ENDSTOP_K
#endif
// Max software endstops constrain movement within maximum coordinate bounds
@@ -1164,6 +1403,9 @@
#define MAX_SOFTWARE_ENDSTOP_X
#define MAX_SOFTWARE_ENDSTOP_Y
#define MAX_SOFTWARE_ENDSTOP_Z
+ #define MAX_SOFTWARE_ENDSTOP_I
+ #define MAX_SOFTWARE_ENDSTOP_J
+ #define MAX_SOFTWARE_ENDSTOP_K
#endif
#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
@@ -1189,28 +1431,47 @@
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
- #define FIL_RUNOUT_PULL // Use internal pullup / pulldown for filament runout pins.
+ #define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
+ //#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
+ //#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder.
+ // This is automatically enabled for MIXING_EXTRUDERs.
// Override individually if the runout sensors vary
//#define FIL_RUNOUT1_STATE LOW
- //#define FIL_RUNOUT1_PULL
+ //#define FIL_RUNOUT1_PULLUP
+ //#define FIL_RUNOUT1_PULLDOWN
+
//#define FIL_RUNOUT2_STATE LOW
- //#define FIL_RUNOUT2_PULL
+ //#define FIL_RUNOUT2_PULLUP
+ //#define FIL_RUNOUT2_PULLDOWN
+
//#define FIL_RUNOUT3_STATE LOW
- //#define FIL_RUNOUT3_PULL
+ //#define FIL_RUNOUT3_PULLUP
+ //#define FIL_RUNOUT3_PULLDOWN
+
//#define FIL_RUNOUT4_STATE LOW
- //#define FIL_RUNOUT4_PULL
+ //#define FIL_RUNOUT4_PULLUP
+ //#define FIL_RUNOUT4_PULLDOWN
+
//#define FIL_RUNOUT5_STATE LOW
- //#define FIL_RUNOUT5_PULL
+ //#define FIL_RUNOUT5_PULLUP
+ //#define FIL_RUNOUT5_PULLDOWN
+
//#define FIL_RUNOUT6_STATE LOW
- //#define FIL_RUNOUT6_PULL
+ //#define FIL_RUNOUT6_PULLUP
+ //#define FIL_RUNOUT6_PULLDOWN
+
//#define FIL_RUNOUT7_STATE LOW
- //#define FIL_RUNOUT7_PULL
+ //#define FIL_RUNOUT7_PULLUP
+ //#define FIL_RUNOUT7_PULLDOWN
+
//#define FIL_RUNOUT8_STATE LOW
- //#define FIL_RUNOUT8_PULL
+ //#define FIL_RUNOUT8_PULLUP
+ //#define FIL_RUNOUT8_PULLDOWN
- // Set one or more commands to execute on filament runout.
- // (After 'M412 H' Marlin will ask the host to handle the process.)
+ // Commands to execute on filament runout.
+ // With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c")
+ // NOTE: After 'M412 H1' the host handles filament runout and this script does not apply.
#define FILAMENT_RUNOUT_SCRIPT "M600"
// After a runout is detected, continue printing this length of filament
@@ -1271,10 +1532,21 @@
//#define MESH_BED_LEVELING
/**
- * Normally G28 leaves leveling disabled on completion. Enable
- * this option to have G28 restore the prior leveling state.
+ * Normally G28 leaves leveling disabled on completion. Enable one of
+ * these options to restore the prior leveling state or to always enable
+ * leveling immediately after G28.
*/
//#define RESTORE_LEVELING_AFTER_G28
+//#define ENABLE_LEVELING_AFTER_G28
+
+/**
+ * Auto-leveling needs preheating
+ */
+//#define PREHEAT_BEFORE_LEVELING
+#if ENABLED(PREHEAT_BEFORE_LEVELING)
+ #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
+ #define LEVELING_BED_TEMP 50
+#endif
/**
* Enable detailed logging of G28, G29, M48, etc.
@@ -1283,11 +1555,19 @@
*/
//#define DEBUG_LEVELING_FEATURE
+#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_UBL, PROBE_MANUALLY)
+ // Set a height for the start of manual adjustment
+ #define MANUAL_PROBE_START_Z 0.2 // (mm) Comment out to use the last-measured height
+#endif
+
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL)
// Gradually reduce leveling correction until a set height is reached,
// at which point movement will be level to the machine's XY plane.
// The height can be set with M420 Z
#define ENABLE_LEVELING_FADE_HEIGHT
+ #if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
+ #define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height.
+ #endif
// For Cartesian machines, instead of dividing moves on mesh boundaries,
// split up moves into short segments like a Delta. This follows the
@@ -1301,10 +1581,11 @@
//#define G26_MESH_VALIDATION
#if ENABLED(G26_MESH_VALIDATION)
#define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle.
- #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for the G26 Mesh Validation Tool.
- #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool.
- #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for the G26 Mesh Validation Tool.
- #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for XY Moves for the G26 Mesh Validation Tool.
+ #define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26.
+ #define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26.
+ #define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26.
+ #define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves.
+ #define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves.
#define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements.
#endif
@@ -1349,12 +1630,16 @@
#define GRID_MAX_POINTS_X 10 // Don't use more than 15 points per axis, implementation limited.
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
+ //#define UBL_HILBERT_CURVE // Use Hilbert distribution for less travel when probing multiple points
+
#define UBL_MESH_EDIT_MOVES_Z // Sophisticated users prefer no movement of nozzle
#define UBL_SAVE_ACTIVE_ON_M500 // Save the currently active mesh in the current slot on M500
//#define UBL_Z_RAISE_WHEN_OFF_MESH 2.5 // When the nozzle is off the mesh, this value is used
// as the Z-Height correction value.
+ //#define UBL_MESH_WIZARD // Run several commands in a row to get a complete mesh
+
#elif ENABLED(MESH_BED_LEVELING)
//===========================================================================
@@ -1389,6 +1674,31 @@
#define LEVEL_CORNERS_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
#define LEVEL_CORNERS_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
//#define LEVEL_CENTER_TOO // Move to the center after the last corner
+ //#define LEVEL_CORNERS_USE_PROBE
+ #if ENABLED(LEVEL_CORNERS_USE_PROBE)
+ #define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
+ #define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
+ //#define LEVEL_CORNERS_AUDIO_FEEDBACK
+ #endif
+
+ /**
+ * Corner Leveling Order
+ *
+ * Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge.
+ *
+ * LF Left-Front RF Right-Front
+ * LB Left-Back RB Right-Back
+ *
+ * Examples:
+ *
+ * Default {LF,RB,LB,RF} {LF,RF} {LB,LF}
+ * LB --------- RB LB --------- RB LB --------- RB LB --------- RB
+ * | 4 3 | | 3 2 | | <3> | | 1 |
+ * | | | | | | | <3>|
+ * | 1 2 | | 1 4 | | 1 2 | | 2 |
+ * LF --------- RF LF --------- RF LF --------- RF LF --------- RF
+ */
+ #define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, RB, LB }
#endif
/**
@@ -1407,16 +1717,17 @@
//#define MANUAL_X_HOME_POS 0
//#define MANUAL_Y_HOME_POS 0
//#define MANUAL_Z_HOME_POS 0
+//#define MANUAL_I_HOME_POS 0
+//#define MANUAL_J_HOME_POS 0
+//#define MANUAL_K_HOME_POS 0
-// Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area.
-//
-// With this feature enabled:
-//
-// - Allow Z homing only after X and Y homing AND stepper drivers still enabled.
-// - If stepper drivers time out, it will need X and Y homing again before Z homing.
-// - Move the Z probe (or nozzle) to a defined XY point before Z Homing.
-// - Prevent Z homing when the Z probe is outside bed area.
-//
+/**
+ * Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area.
+ *
+ * - Moves the Z probe (or nozzle) to a defined XY point before Z homing.
+ * - Allows Z homing only when XY positions are known and trusted.
+ * - If stepper drivers sleep, XY homing may be required again before Z homing.
+ */
//#define Z_SAFE_HOMING
#if ENABLED(Z_SAFE_HOMING)
@@ -1425,8 +1736,7 @@
#endif
// Homing speeds (mm/min)
-#define HOMING_FEEDRATE_XY (80*60)
-#define HOMING_FEEDRATE_Z (20*60)
+#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) } // had XY 80*60, Z 20*60
// Validate that endstops are triggered on homing moves
#define VALIDATE_HOMING_ENDSTOPS
@@ -1533,15 +1843,19 @@
// @section temperature
-// Preheat Constants
+//
+// Preheat Constants - Up to 5 are supported without changes
+//
#define PREHEAT_1_LABEL "PLA"
#define PREHEAT_1_TEMP_HOTEND 180
#define PREHEAT_1_TEMP_BED 70
+#define PREHEAT_1_TEMP_CHAMBER 35
#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255
#define PREHEAT_2_LABEL "ABS"
#define PREHEAT_2_TEMP_HOTEND 240
#define PREHEAT_2_TEMP_BED 110
+#define PREHEAT_2_TEMP_CHAMBER 35
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
/**
@@ -1634,6 +1948,10 @@
// For a purge/clean station mounted on the X axis
//#define NOZZLE_CLEAN_NO_Y
+ // Require a minimum hotend temperature for cleaning
+ #define NOZZLE_CLEAN_MIN_TEMP 170
+ //#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe
+
// Explicit wipe G-code script applies to a G12 with no arguments.
//#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0"
@@ -1642,11 +1960,20 @@
/**
* Print Job Timer
*
- * Automatically start and stop the print job timer on M104/M109/M190.
+ * Automatically start and stop the print job timer on M104/M109/M140/M190/M141/M191.
+ * The print job timer will only be stopped if the bed/chamber target temp is
+ * below BED_MINTEMP/CHAMBER_MINTEMP.
*
- * M104 (hotend, no wait) - high temp = none, low temp = stop timer
- * M109 (hotend, wait) - high temp = start timer, low temp = stop timer
- * M190 (bed, wait) - high temp = start timer, low temp = none
+ * M104 (hotend, no wait) - high temp = none, low temp = stop timer
+ * M109 (hotend, wait) - high temp = start timer, low temp = stop timer
+ * M140 (bed, no wait) - high temp = none, low temp = stop timer
+ * M190 (bed, wait) - high temp = start timer, low temp = none
+ * M141 (chamber, no wait) - high temp = none, low temp = stop timer
+ * M191 (chamber, wait) - high temp = start timer, low temp = none
+ *
+ * For M104/M109, high temp is anything over EXTRUDE_MINTEMP / 2.
+ * For M140/M190, high temp is anything over BED_MINTEMP.
+ * For M141/M191, high temp is anything over CHAMBER_MINTEMP.
*
* The timer can also be controlled with the following commands:
*
@@ -1669,6 +1996,9 @@
* View the current statistics with M78.
*/
//#define PRINTCOUNTER
+#if ENABLED(PRINTCOUNTER)
+ #define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print
+#endif
/**
* Password
@@ -1713,9 +2043,9 @@
* Select the language to display on the LCD. These languages are available:
*
* en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, hu, it,
- * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
+ * jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW
*
- * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
+ * :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' }
*/
#define LCD_LANGUAGE en
@@ -1758,16 +2088,6 @@
*/
//#define SDSUPPORT
-/**
- * SD CARD: SPI SPEED
- *
- * Enable one of the following items for a slower SPI transfer speed.
- * This may be required to resolve "volume init" errors.
- */
-//#define SPI_SPEED SPI_HALF_SPEED
-//#define SPI_SPEED SPI_QUARTER_SPEED
-//#define SPI_SPEED SPI_EIGHTH_SPEED
-
/**
* SD CARD: ENABLE CRC
*
@@ -1869,6 +2189,14 @@
//
//#define REPRAP_DISCOUNT_SMART_CONTROLLER
+//
+// GT2560 (YHCB2004) LCD Display
+//
+// Requires Testato, Koepel softwarewire library and
+// Andriy Golovnya's LiquidCrystal_AIP31068 library.
+//
+//#define YHCB2004
+
//
// Original RADDS LCD Display+Encoder+SDCardReader
// http://doku.radds.org/dokumentation/lcd-display/
@@ -2019,6 +2347,11 @@
//
//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
+//
+// K.3D Full Graphic Smart Controller
+//
+//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER
+
//
// ReprapWorld Graphical LCD
// https://reprapworld.com/?products_details&products_id/1218
@@ -2080,11 +2413,17 @@
//
//#define MKS_MINI_12864
+//
+// MKS MINI12864 V3 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight.
+//
+//#define MKS_MINI_12864_V3
+
//
// MKS LCD12864A/B with graphic controller and SD support. Follows MKS_MINI_12864 pinout.
// https://www.aliexpress.com/item/33018110072.html
//
-//#define MKS_LCD12864
+//#define MKS_LCD12864A
+//#define MKS_LCD12864B
//
// FYSETC variant of the MINI12864 graphic controller with SD support
@@ -2156,7 +2495,7 @@
//#define OLED_PANEL_TINYBOY2
//
-// MKS OLED 1.3" 128×64 FULL GRAPHICS CONTROLLER
+// MKS OLED 1.3" 128×64 Full Graphics Controller
// https://reprap.org/wiki/MKS_12864OLED
//
// Tiny, but very sharp OLED display
@@ -2165,7 +2504,7 @@
//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller
//
-// Zonestar OLED 128×64 FULL GRAPHICS CONTROLLER
+// Zonestar OLED 128×64 Full Graphics Controller
//
//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller
//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default)
@@ -2182,10 +2521,15 @@
//#define OVERLORD_OLED
//
-// FYSETC OLED 2.42" 128×64 FULL GRAPHICS CONTROLLER with WS2812 RGB
+// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB
// Where to find : https://www.aliexpress.com/item/4000345255731.html
//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller
+//
+// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller
+//
+//#define K3D_242_OLED_CONTROLLER // Software SPI
+
//=============================================================================
//========================== Extensible UI Displays ===========================
//=============================================================================
@@ -2194,10 +2538,37 @@
// DGUS Touch Display with DWIN OS. (Choose one.)
// ORIGIN : https://www.aliexpress.com/item/32993409517.html
// FYSETC : https://www.aliexpress.com/item/32961471929.html
+// MKS : https://www.aliexpress.com/item/1005002008179262.html
+//
+// Flash display with DGUS Displays for Marlin:
+// - Format the SD card to FAT32 with an allocation size of 4kb.
+// - Download files as specified for your type of display.
+// - Plug the microSD card into the back of the display.
+// - Boot the display and wait for the update to complete.
+//
+// ORIGIN (Marlin DWIN_SET)
+// - Download https://github.com/coldtobi/Marlin_DGUS_Resources
+// - Copy the downloaded DWIN_SET folder to the SD card.
+//
+// FYSETC (Supplier default)
+// - Download https://github.com/FYSETC/FYSTLCD-2.0
+// - Copy the downloaded SCREEN folder to the SD card.
+//
+// HIPRECY (Supplier default)
+// - Download https://github.com/HiPrecy/Touch-Lcd-LEO
+// - Copy the downloaded DWIN_SET folder to the SD card.
+//
+// MKS (MKS-H43) (Supplier default)
+// - Download https://github.com/makerbase-mks/MKS-H43
+// - Copy the downloaded DWIN_SET folder to the SD card.
//
//#define DGUS_LCD_UI_ORIGIN
//#define DGUS_LCD_UI_FYSETC
//#define DGUS_LCD_UI_HIPRECY
+//#define DGUS_LCD_UI_MKS
+#if ENABLED(DGUS_LCD_UI_MKS)
+ #define USE_MKS_GREEN_UI
+#endif
//
// CR-6 OEM touch screen. A DWIN display with touch.
@@ -2228,6 +2599,14 @@
//#define ANYCUBIC_LCD_DEBUG
#endif
+//
+// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028
+//
+//#define NEXTION_TFT
+#if ENABLED(NEXTION_TFT)
+ #define LCD_SERIAL_PORT 1 // Default is 1 for Nextion
+#endif
+
//
// Third-party or vendor-customized controller interfaces.
// Sources should be installed in 'src/lcd/extui'.
@@ -2303,6 +2682,21 @@
//
//#define LONGER_LK_TFT28
+//
+// 320x240, 2.8", FSMC Stock Display from ET4
+//
+//#define ANET_ET4_TFT28
+
+//
+// 480x320, 3.5", FSMC Stock Display from ET5
+//
+//#define ANET_ET5_TFT35
+
+//
+// 1024x600, 7", RGB Stock Display from BIQU-BX
+//
+//#define BIQU_BX_TFT70
+
//
// Generic TFT with detailed options
//
@@ -2335,6 +2729,10 @@
//#define TFT_COLOR_UI
//#define TFT_LVGL_UI
+#if ENABLED(TFT_LVGL_UI)
+ //#define MKS_WIFI_MODULE // MKS WiFi module
+#endif
+
/**
* TFT Rotation. Set to one of the following values:
*
@@ -2355,7 +2753,7 @@
//#define DWIN_CREALITY_LCD
//
-// ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8
+// Touch Screen Settings
//
//#define TOUCH_SCREEN
#if ENABLED(TOUCH_SCREEN)
@@ -2364,10 +2762,15 @@
#define TOUCH_SCREEN_CALIBRATION
- //#define XPT2046_X_CALIBRATION 12316
- //#define XPT2046_Y_CALIBRATION -8981
- //#define XPT2046_X_OFFSET -43
- //#define XPT2046_Y_OFFSET 257
+ //#define TOUCH_CALIBRATION_X 12316
+ //#define TOUCH_CALIBRATION_Y -8981
+ //#define TOUCH_OFFSET_X -43
+ //#define TOUCH_OFFSET_Y 257
+ //#define TOUCH_ORIENTATION TOUCH_LANDSCAPE
+
+ #if BOTH(TOUCH_SCREEN_CALIBRATION, EEPROM_SETTINGS)
+ #define TOUCH_CALIBRATION_AUTO_SAVE // Auto save successful calibration values to EEPROM
+ #endif
#if ENABLED(TFT_COLOR_UI)
//#define SINGLE_TOUCH_NAVIGATION
@@ -2464,7 +2867,7 @@
//#define NEOPIXEL_LED
#if ENABLED(NEOPIXEL_LED)
#define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW / NEO_GRB - four/three channel driver type (defined in Adafruit_NeoPixel.h)
- #define NEOPIXEL_PIN 4 // LED driving pin
+ //#define NEOPIXEL_PIN 4 // LED driving pin
//#define NEOPIXEL2_TYPE NEOPIXEL_TYPE
//#define NEOPIXEL2_PIN 5
#define NEOPIXEL_PIXELS 30 // Number of LEDs in the strip. (Longest strip when NEOPIXEL2_SEPARATE is disabled.)
@@ -2482,9 +2885,11 @@
//#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
#endif
- // Use a single NeoPixel LED for static (background) lighting
- //#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use
- //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W
+ // Use some of the NeoPixel LEDs for static (background) lighting
+ //#define NEOPIXEL_BKGD_INDEX_FIRST 0 // Index of the first background LED
+ //#define NEOPIXEL_BKGD_INDEX_LAST 5 // Index of the last background LED
+ //#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W
+ //#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off
#endif
/**
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 748337004e3c..a6ac581cccff 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -30,7 +30,7 @@
*
* Basic settings can be found in Configuration.h
*/
-#define CONFIGURATION_ADV_H_VERSION 020008
+#define CONFIGURATION_ADV_H_VERSION 02000901
//===========================================================================
//============================= Thermal Settings ============================
@@ -113,10 +113,39 @@
#define CHAMBER_BETA 3950 // Beta value
#endif
-//
-// Hephestos 2 24V heated bed upgrade kit.
-// https://store.bq.com/en/heated-bed-kit-hephestos2
-//
+#if TEMP_SENSOR_COOLER == 1000
+ #define COOLER_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
+ #define COOLER_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
+ #define COOLER_BETA 3950 // Beta value
+#endif
+
+#if TEMP_SENSOR_PROBE == 1000
+ #define PROBE_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
+ #define PROBE_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
+ #define PROBE_BETA 3950 // Beta value
+#endif
+
+#if TEMP_SENSOR_REDUNDANT == 1000
+ #define REDUNDANT_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
+ #define REDUNDANT_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
+ #define REDUNDANT_BETA 3950 // Beta value
+#endif
+
+/**
+ * Configuration options for MAX Thermocouples (-2, -3, -5).
+ * FORCE_HW_SPI: Ignore SCK/MOSI/MISO pins and just use the CS pin & default SPI bus.
+ * MAX31865_WIRES: Set the number of wires for the probe connected to a MAX31865 board, 2-4. Default: 2
+ * MAX31865_50HZ: Enable 50Hz filter instead of the default 60Hz.
+ */
+//#define TEMP_SENSOR_FORCE_HW_SPI
+//#define MAX31865_SENSOR_WIRES_0 2
+//#define MAX31865_SENSOR_WIRES_1 2
+//#define MAX31865_50HZ_FILTER
+
+/**
+ * Hephestos 2 24V heated bed upgrade kit.
+ * https://store.bq.com/en/heated-bed-kit-hephestos2
+ */
//#define HEPHESTOS2_HEATED_BED_KIT
#if ENABLED(HEPHESTOS2_HEATED_BED_KIT)
#undef TEMP_SENSOR_BED
@@ -137,17 +166,21 @@
//
// Heated Chamber options
//
+#if DISABLED(PIDTEMPCHAMBER)
+ #define CHAMBER_CHECK_INTERVAL 5000 // (ms) Interval between checks in bang-bang control
+ #if ENABLED(CHAMBER_LIMIT_SWITCHING)
+ #define CHAMBER_HYSTERESIS 2 // (°C) Only set the relevant heater state when ABS(T-target) > CHAMBER_HYSTERESIS
+ #endif
+#endif
+
#if TEMP_SENSOR_CHAMBER
- #define CHAMBER_MINTEMP 5
- #define CHAMBER_MAXTEMP 60
- #define TEMP_CHAMBER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target
- //#define CHAMBER_LIMIT_SWITCHING
- //#define HEATER_CHAMBER_PIN 44 // Chamber heater on/off pin
+ //#define HEATER_CHAMBER_PIN P2_04 // Required heater on/off pin (example: SKR 1.4 Turbo HE1 plug)
//#define HEATER_CHAMBER_INVERTING false
+ //#define FAN1_PIN -1 // Remove the fan signal on pin P2_04 (example: SKR 1.4 Turbo HE1 plug)
//#define CHAMBER_FAN // Enable a fan on the chamber
#if ENABLED(CHAMBER_FAN)
- #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve.
+ #define CHAMBER_FAN_MODE 2 // Fan control mode: 0=Static; 1=Linear increase when temp is higher than target; 2=V-shaped curve; 3=similar to 1 but fan is always on.
#if CHAMBER_FAN_MODE == 0
#define CHAMBER_FAN_BASE 255 // Chamber fan PWM (0-255)
#elif CHAMBER_FAN_MODE == 1
@@ -156,6 +189,9 @@
#elif CHAMBER_FAN_MODE == 2
#define CHAMBER_FAN_BASE 128 // Minimum chamber fan PWM (0-255)
#define CHAMBER_FAN_FACTOR 25 // PWM increase per °C difference from target
+ #elif CHAMBER_FAN_MODE == 3
+ #define CHAMBER_FAN_BASE 128 // Base chamber fan PWM (0-255)
+ #define CHAMBER_FAN_FACTOR 25 // PWM increase per °C above target
#endif
#endif
@@ -163,12 +199,45 @@
#if ENABLED(CHAMBER_VENT)
#define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo
#define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber
- #define LOW_EXCESS_HEAT_LIMIT 3
+ #define LOW_EXCESS_HEAT_LIMIT 3
#define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20
#define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5
#endif
#endif
+//
+// Laser Cooler options
+//
+#if TEMP_SENSOR_COOLER
+ #define COOLER_MINTEMP 8 // (°C)
+ #define COOLER_MAXTEMP 26 // (°C)
+ #define COOLER_DEFAULT_TEMP 16 // (°C)
+ #define TEMP_COOLER_HYSTERESIS 1 // (°C) Temperature proximity considered "close enough" to the target
+ #define COOLER_PIN 8 // Laser cooler on/off pin used to control power to the cooling element (e.g., TEC, External chiller via relay)
+ #define COOLER_INVERTING false
+ #define TEMP_COOLER_PIN 15 // Laser/Cooler temperature sensor pin. ADC is required.
+ #define COOLER_FAN // Enable a fan on the cooler, Fan# 0,1,2,3 etc.
+ #define COOLER_FAN_INDEX 0 // FAN number 0, 1, 2 etc. e.g.
+ #if ENABLED(COOLER_FAN)
+ #define COOLER_FAN_BASE 100 // Base Cooler fan PWM (0-255); turns on when Cooler temperature is above the target
+ #define COOLER_FAN_FACTOR 25 // PWM increase per °C above target
+ #endif
+#endif
+
+//
+// Laser Coolant Flow Meter
+//
+//#define LASER_COOLANT_FLOW_METER
+#if ENABLED(LASER_COOLANT_FLOW_METER)
+ #define FLOWMETER_PIN 20 // Requires an external interrupt-enabled pin (e.g., RAMPS 2,3,18,19,20,21)
+ #define FLOWMETER_PPL 5880 // (pulses/liter) Flow meter pulses-per-liter on the input pin
+ #define FLOWMETER_INTERVAL 1000 // (ms) Flow rate calculation interval in milliseconds
+ #define FLOWMETER_SAFETY // Prevent running the laser without the minimum flow rate set below
+ #if ENABLED(FLOWMETER_SAFETY)
+ #define FLOWMETER_MIN_LITERS_PER_MINUTE 1.5 // (liters/min) Minimum flow required when enabled
+ #endif
+#endif
+
/**
* Thermal Protection provides additional protection to your printer from damage
* and fire. Marlin always includes safe min and max temperature ranges which
@@ -206,7 +275,7 @@
* and/or decrease WATCH_TEMP_INCREASE. WATCH_TEMP_INCREASE should not be set
* below 2.
*/
- #define WATCH_TEMP_PERIOD 20 // Seconds
+ #define WATCH_TEMP_PERIOD 20 // Seconds
#define WATCH_TEMP_INCREASE 2 // Degrees Celsius
#endif
@@ -238,6 +307,20 @@
#define WATCH_CHAMBER_TEMP_INCREASE 2 // Degrees Celsius
#endif
+/**
+ * Thermal Protection parameters for the laser cooler.
+ */
+#if ENABLED(THERMAL_PROTECTION_COOLER)
+ #define THERMAL_PROTECTION_COOLER_PERIOD 10 // Seconds
+ #define THERMAL_PROTECTION_COOLER_HYSTERESIS 3 // Degrees Celsius
+
+ /**
+ * Laser cooling watch settings (M143/M193).
+ */
+ #define WATCH_COOLER_TEMP_PERIOD 60 // Seconds
+ #define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius
+#endif
+
#if ENABLED(PIDTEMP)
// Add an experimental additional term to the heater power, proportional to the extrusion speed.
// A well-chosen Kc value should add just enough power to melt the increased material volume.
@@ -284,8 +367,8 @@
// DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly.
#define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf
- #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
- #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
+ #define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
+ #define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
#define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED)
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
@@ -331,7 +414,7 @@
* High Temperature Thermistor Support
*
* Thermistors able to support high temperature tend to have a hard time getting
- * good readings at room and lower temperatures. This means HEATER_X_RAW_LO_TEMP
+ * good readings at room and lower temperatures. This means TEMP_SENSOR_X_RAW_LO_TEMP
* will probably be caught when the heating element first turns on during the
* preheating process, which will trigger a min_temp_error as a safety measure
* and force stop everything.
@@ -462,6 +545,11 @@
//#define USE_OCR2A_AS_TOP
#endif
+/**
+ * Use one of the PWM fans as a redundant part-cooling fan
+ */
+//#define REDUNDANT_PART_COOLING_FAN 2 // Index of the fan to sync with FAN 0.
+
// @section extruder
/**
@@ -485,11 +573,15 @@
#define E6_AUTO_FAN_PIN -1
#define E7_AUTO_FAN_PIN -1
#define CHAMBER_AUTO_FAN_PIN -1
+#define COOLER_AUTO_FAN_PIN -1
+#define COOLER_FAN_PIN -1
#define EXTRUDER_AUTO_FAN_TEMPERATURE 50
#define EXTRUDER_AUTO_FAN_SPEED 255 // 255 == full speed
#define CHAMBER_AUTO_FAN_TEMPERATURE 30
#define CHAMBER_AUTO_FAN_SPEED 255
+#define COOLER_AUTO_FAN_TEMPERATURE 18
+#define COOLER_AUTO_FAN_SPEED 255
/**
* Part-Cooling Fan Multiplexer
@@ -511,12 +603,17 @@
#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 105 // Set default power-up brightness (0-255, requires PWM pin)
- //#define CASE_LIGHT_MAX_PWM 128 // Limit pwm
- //#define CASE_LIGHT_MENU // Add Case Light options to the LCD menu
//#define CASE_LIGHT_NO_BRIGHTNESS // Disable brightness control. Enable for non-PWM lighting.
- //#define CASE_LIGHT_USE_NEOPIXEL // Use NeoPixel LED as case light, requires NEOPIXEL_LED.
- #if ENABLED(CASE_LIGHT_USE_NEOPIXEL)
- #define CASE_LIGHT_NEOPIXEL_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White }
+ //#define CASE_LIGHT_MAX_PWM 128 // Limit PWM duty cycle (0-255)
+ //#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
+ #if EITHER(RGB_LED, RGBW_LED)
+ //#define CASE_LIGHT_USE_RGB_LED // Use RGB / RGBW LED as case light
+ #endif
+ #if EITHER(CASE_LIGHT_USE_NEOPIXEL, CASE_LIGHT_USE_RGB_LED)
+ #define CASE_LIGHT_DEFAULT_COLOR { 255, 255, 255, 255 } // { Red, Green, Blue, White }
#endif
#endif
@@ -554,7 +651,7 @@
//#define X_DUAL_STEPPER_DRIVERS
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
- #define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions
+ //#define INVERT_X2_VS_X_DIR // Enable if X2 direction signal is opposite to X
//#define X_DUAL_ENDSTOPS
#if ENABLED(X_DUAL_ENDSTOPS)
#define X2_USE_ENDSTOP _XMAX_
@@ -564,7 +661,7 @@
//#define Y_DUAL_STEPPER_DRIVERS
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
- #define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions
+ //#define INVERT_Y2_VS_Y_DIR // Enable if Y2 direction signal is opposite to Y
//#define Y_DUAL_ENDSTOPS
#if ENABLED(Y_DUAL_ENDSTOPS)
#define Y2_USE_ENDSTOP _YMAX_
@@ -578,6 +675,11 @@
#define NUM_Z_STEPPER_DRIVERS 2 // (1-4) Z options change based on how many
#if NUM_Z_STEPPER_DRIVERS > 1
+ // Enable if Z motor direction signals are the opposite of Z1
+ //#define INVERT_Z2_VS_Z_DIR
+ //#define INVERT_Z3_VS_Z_DIR
+ //#define INVERT_Z4_VS_Z_DIR
+
//#define Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
#define Z2_USE_ENDSTOP _XMAX_
@@ -593,6 +695,12 @@
#endif
#endif
+// Drive the E axis with two synchronized steppers
+//#define E_DUAL_STEPPER_DRIVERS
+#if ENABLED(E_DUAL_STEPPER_DRIVERS)
+ //#define INVERT_E1_VS_E0_DIR // Enable if the E motors need opposite DIR states
+#endif
+
/**
* Dual X Carriage
*
@@ -639,6 +747,9 @@
// Default x offset in duplication mode (typically set to half print bed width)
#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"
#endif
// Activate a solenoid on the active extruder with M380. Disable all with M381.
@@ -653,7 +764,7 @@
* the position of the toolhead relative to the workspace.
*/
-//#define SENSORLESS_BACKOFF_MM { 2, 2 } // (mm) Backoff from endstops before sensorless homing
+//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (mm) Backoff from endstops before sensorless homing
#define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump
#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate)
@@ -662,6 +773,7 @@
#define QUICK_HOME // If G28 contains XY do a diagonal move first
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
+//#define HOME_Z_FIRST // Home Z first. Requires a Z-MIN endstop (not a probe).
//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first
// @section bltouch
@@ -723,8 +835,8 @@
/**
* Use "HIGH SPEED" mode for probing.
* Danger: Disable if your probe sometimes fails. Only suitable for stable well-adjusted systems.
- * This feature was designed for Delta's with very fast Z moves however higher speed cartesians may function
- * If the machine cannot raise the probe fast enough after a trigger, it may enter a fault state.
+ * This feature was designed for Deltabots with very fast Z moves; however, higher speed Cartesians
+ * might be able to use it. If the machine can't raise Z fast enough the BLTouch may go into ALARM.
*/
//#define BLTOUCH_HS_MODE
@@ -799,10 +911,10 @@
//#define ASSISTED_TRAMMING
#if ENABLED(ASSISTED_TRAMMING)
- // Define positions for probing points, use the hotend as reference not the sensor.
- #define TRAMMING_POINT_XY { { 20, 20 }, { 200, 20 }, { 200, 200 }, { 20, 200 } }
+ // Define positions for probe points.
+ #define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } }
- // Define positions names for probing points.
+ // Define position names for probe points.
#define TRAMMING_POINT_NAME_1 "Front-Left"
#define TRAMMING_POINT_NAME_2 "Front-Right"
#define TRAMMING_POINT_NAME_3 "Back-Right"
@@ -811,8 +923,8 @@
#define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation
//#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first
- //#define ASSISTED_TRAMMING_MENU_ITEM // Add a menu item to run G35 Assisted Tramming (MarlinUI)
- //#define ASSISTED_TRAMMING_WIZARD // Make the menu item open a Tramming Wizard sub-menu
+ //#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu
+
//#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment
/**
@@ -836,6 +948,9 @@
#define INVERT_X_STEP_PIN false
#define INVERT_Y_STEP_PIN false
#define INVERT_Z_STEP_PIN false
+#define INVERT_I_STEP_PIN false
+#define INVERT_J_STEP_PIN false
+#define INVERT_K_STEP_PIN false
#define INVERT_E_STEP_PIN false
/**
@@ -847,13 +962,11 @@
#define DISABLE_INACTIVE_X true
#define DISABLE_INACTIVE_Y true
#define DISABLE_INACTIVE_Z true // Set 'false' if the nozzle could fall onto your printed part!
+#define DISABLE_INACTIVE_I true
+#define DISABLE_INACTIVE_J true
+#define DISABLE_INACTIVE_K true
#define DISABLE_INACTIVE_E true
-// If the Nozzle or Bed falls when the Z stepper is disabled, set its resting position here.
-//#define Z_AFTER_DEACTIVATE Z_HOME_POS
-
-//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated
-
// Default Minimum Feedrates for printing and travel moves
#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s) Minimum feedrate. Set with M205 S.
#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s) Minimum travel feedrate. Set with M205 T.
@@ -892,9 +1005,12 @@
#if ENABLED(BACKLASH_COMPENSATION)
// Define values for backlash distance and correction.
// If BACKLASH_GCODE is enabled these values are the defaults.
- #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm)
+ #define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (mm) One value for each linear axis
#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
+
// Set BACKLASH_SMOOTHING_MM to spread backlash correction over multiple segments
// to reduce print artifacts. (Enabling this is costly in memory and computation!)
//#define BACKLASH_SMOOTHING_MM 3 // (mm)
@@ -912,7 +1028,7 @@
// increments while checking for the contact to be broken.
#define BACKLASH_MEASUREMENT_LIMIT 0.5 // (mm)
#define BACKLASH_MEASUREMENT_RESOLUTION 0.005 // (mm)
- #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_SPEED_SLOW // (mm/min)
+ #define BACKLASH_MEASUREMENT_FEEDRATE Z_PROBE_FEEDRATE_SLOW // (mm/min)
#endif
#endif
#endif
@@ -960,6 +1076,13 @@
#define CALIBRATION_MEASURE_LEFT
#define CALIBRATION_MEASURE_BACK
+ //#define CALIBRATION_MEASURE_IMIN
+ //#define CALIBRATION_MEASURE_IMAX
+ //#define CALIBRATION_MEASURE_JMIN
+ //#define CALIBRATION_MEASURE_JMAX
+ //#define CALIBRATION_MEASURE_KMIN
+ //#define CALIBRATION_MEASURE_KMAX
+
// Probing at the exact top center only works if the center is flat. If
// probing on a screwhead or hollow washer, probe near the edges.
//#define CALIBRATION_MEASURE_AT_TOP_EDGES
@@ -1022,7 +1145,7 @@
/**
* I2C-based DIGIPOTs (e.g., Azteeg X3 Pro)
*/
-//#define DIGIPOT_MCP4018 // Requires https://github.com/stawel/SlowSoftI2CMaster
+//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster
//#define DIGIPOT_MCP4451
#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5
@@ -1055,7 +1178,7 @@
#if EITHER(IS_ULTIPANEL, EXTENSIBLE_UI)
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
- #define SHORT_MANUAL_Z_MOVE 0.025 // (mm) Smallest manual Z move (< 0.1mm)
+ #define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines
#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
@@ -1082,7 +1205,15 @@
#if HAS_BED_PROBE
//#define PROBE_OFFSET_WIZARD
#if ENABLED(PROBE_OFFSET_WIZARD)
- #define PROBE_OFFSET_START -4.0 // Estimated nozzle-to-probe Z offset, plus a little extra
+ //
+ // Enable to init the Probe Z-Offset when starting the Wizard.
+ // Use a height slightly above the estimated nozzle-to-probe Z offset.
+ // For example, with an offset of -5, consider a starting height of -4.
+ //
+ //#define PROBE_OFFSET_WIZARD_START_Z -4.0
+
+ // Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
+ //#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
#endif
#endif
@@ -1124,35 +1255,46 @@
#endif
#endif
+ // Insert a menu for preheating at the top level to allow for quick access
+ //#define PREHEAT_SHORTCUT_MENU_ITEM
+
#endif // HAS_LCD_MENU
-// Scroll a longer status message into view
-//#define STATUS_MESSAGE_SCROLLING
+#if HAS_DISPLAY
+ // The timeout (in ms) to return to the status screen from sub-menus
+ //#define LCD_TIMEOUT_TO_STATUS 15000
-// On the Info Screen, display XY with one decimal place when possible
-//#define LCD_DECIMAL_SMALL_XY
+ #if ENABLED(SHOW_BOOTSCREEN)
+ #define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s)
+ #if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI)
+ #define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
+ #endif
+ #endif
-// The timeout (in ms) to return to the status screen from sub-menus
-//#define LCD_TIMEOUT_TO_STATUS 15000
+ // Scroll a longer status message into view
+ //#define STATUS_MESSAGE_SCROLLING
-// Add an 'M73' G-code to set the current percentage
-//#define LCD_SET_PROGRESS_MANUALLY
+ // On the Info Screen, display XY with one decimal place when possible
+ //#define LCD_DECIMAL_SMALL_XY
-// Show the E position (filament used) during printing
-//#define LCD_SHOW_E_TOTAL
+ // Add an 'M73' G-code to set the current percentage
+ //#define LCD_SET_PROGRESS_MANUALLY
-#if ENABLED(SHOW_BOOTSCREEN)
- #define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s)
+ // Show the E position (filament used) during printing
+ //#define LCD_SHOW_E_TOTAL
#endif
-#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
- //#define SHOW_REMAINING_TIME // Display estimated time to completion
- #if ENABLED(SHOW_REMAINING_TIME)
- //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
- //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
+// LCD Print Progress options
+#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY)
+ #if ANY(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
+ //#define SHOW_REMAINING_TIME // Display estimated time to completion
+ #if ENABLED(SHOW_REMAINING_TIME)
+ //#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
+ //#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
+ #endif
#endif
- #if HAS_MARLINUI_U8GLIB
+ #if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI)
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
#endif
@@ -1169,13 +1311,26 @@
#endif
#if ENABLED(SDSUPPORT)
+ /**
+ * SD Card SPI Speed
+ * May be required to resolve "volume init" errors.
+ *
+ * Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED
+ * otherwise full speed will be applied.
+ *
+ * :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED']
+ */
+ //#define SD_SPI_SPEED SPI_HALF_SPEED
// The standard SD detect circuit reads LOW when media is inserted and HIGH when empty.
// Enable this option and set to HIGH if your SD cards are incorrectly detected.
//#define SD_DETECT_STATE HIGH
+ //#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up
//#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash)
+ //#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping
+
#define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls
#define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished
@@ -1187,8 +1342,13 @@
#define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing
+ //#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM
//#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files
+ //#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted
+
+ //#define MEDIA_MENU_AT_TOP // Force the media menu to be listed on the top of the main menu
+
#define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27")
#if ENABLED(PRINTER_EVENT_LEDS)
@@ -1207,17 +1367,23 @@
#if ENABLED(POWER_LOSS_RECOVERY)
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
- //#define POWER_LOSS_RECOVER_ZHOME // Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
//#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_PULL // Set pullup / pulldown as appropriate
+ //#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor
+ //#define POWER_LOSS_PULLDOWN
//#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
+
+ // 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)
+ //#define POWER_LOSS_ZHOME_POS { 0, 0 } // Safe XY position to home Z while avoiding objects on the bed
+ #endif
#endif
/**
@@ -1258,6 +1424,10 @@
// Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
#endif
+ // Allow international symbols in long filenames. To display correctly, the
+ // LCD's font must contain the characters. Check your selected LCD language.
+ //#define UTF_FILENAME_SUPPORT
+
// This allows hosts to request long names for files and folders with M33
//#define LONG_FILENAME_HOST_SUPPORT
@@ -1302,9 +1472,6 @@
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
- #define USB_CS_PIN SDSS
- #define USB_INTR_PIN SD_DETECT_PIN
-
/**
* USB Host Shield Library
*
@@ -1315,7 +1482,18 @@
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
+ //#define USE_UHS2_USB
//#define USE_UHS3_USB
+
+ /**
+ * Native USB Host supported by some boards (USB OTG)
+ */
+ //#define USE_OTG_USB_HOST
+
+ #if DISABLED(USE_OTG_USB_HOST)
+ #define USB_CS_PIN SDSS
+ #define USB_INTR_PIN SD_DETECT_PIN
+ #endif
#endif
/**
@@ -1341,13 +1519,25 @@
* Set this option to one of the following (or the board's defaults apply):
*
* LCD - Use the SD drive in the external LCD controller.
- * ONBOARD - Use the SD drive on the control board. (No SD_DETECT_PIN. M21 to init.)
+ * ONBOARD - Use the SD drive on the control board.
* CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file).
*
* :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ]
*/
//#define SDCARD_CONNECTION LCD
+ // Enable if SD detect is rendered useless (e.g., by using an SD extender)
+ //#define NO_SD_DETECT
+
+ // Multiple volume support - EXPERIMENTAL.
+ //#define MULTI_VOLUME
+ #if ENABLED(MULTI_VOLUME)
+ #define VOLUME_SD_ONBOARD
+ #define VOLUME_USB_FLASH_DRIVE
+ #define DEFAULT_VOLUME SV_SD_ONBOARD
+ #define DEFAULT_SHARED_VOLUME SV_USB_FLASH_DRIVE
+ #endif
+
#endif // SDSUPPORT
/**
@@ -1420,16 +1610,17 @@
*/
//#define STATUS_COMBINE_HEATERS // Use combined heater images instead of separate ones
//#define STATUS_HOTEND_NUMBERLESS // Use plain hotend icons instead of numbered ones (with 2+ hotends)
- #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM)
+ #define STATUS_HOTEND_INVERTED // Show solid nozzle bitmaps when heating (Requires STATUS_HOTEND_ANIM for numbered hotends)
#define STATUS_HOTEND_ANIM // Use a second bitmap to indicate hotend heating
#define STATUS_BED_ANIM // Use a second bitmap to indicate bed heating
#define STATUS_CHAMBER_ANIM // Use a second bitmap to indicate chamber heating
//#define STATUS_CUTTER_ANIM // Use a second bitmap to indicate spindle / laser active
+ //#define STATUS_COOLER_ANIM // Use a second bitmap to indicate laser cooling
+ //#define STATUS_FLOWMETER_ANIM // Use multiple bitmaps to indicate coolant flow
//#define STATUS_ALT_BED_BITMAP // Use the alternative bed bitmap
//#define STATUS_ALT_FAN_BITMAP // Use the alternative fan bitmap
//#define STATUS_FAN_FRAMES 3 // :[0,1,2,3,4] Number of fan animation frames
//#define STATUS_HEAT_PERCENT // Show heating in a progress bar
- //#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving 399 bytes of flash)
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of PROGMEM.
// Frivolous Game Options
@@ -1453,12 +1644,12 @@
#define DGUS_UPDATE_INTERVAL_MS 500 // (ms) Interval between automatic screen updates
- #if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_HIPRECY)
+ #if ANY(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS, DGUS_LCD_UI_HIPRECY)
#define DGUS_PRINT_FILENAME // Display the filename during printing
#define DGUS_PREHEAT_UI // Display a preheat screen during heatup
- #if ENABLED(DGUS_LCD_UI_FYSETC)
- //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for UI_FYSETC
+ #if EITHER(DGUS_LCD_UI_FYSETC, DGUS_LCD_UI_MKS)
+ //#define DGUS_UI_MOVE_DIS_OPTION // Disabled by default for FYSETC and MKS
#else
#define DGUS_UI_MOVE_DIS_OPTION // Enabled by default for UI_HIPRECY
#endif
@@ -1477,6 +1668,44 @@
#endif
#endif // HAS_DGUS_LCD
+//
+// Additional options for AnyCubic Chiron TFT displays
+//
+#if ENABLED(ANYCUBIC_LCD_CHIRON)
+ // By default the type of panel is automatically detected.
+ // Enable one of these options if you know the panel type.
+ //#define CHIRON_TFT_STANDARD
+ //#define CHIRON_TFT_NEW
+
+ // Enable the longer Anycubic powerup startup tune
+ //#define AC_DEFAULT_STARTUP_TUNE
+
+ /**
+ * Display Folders
+ * By default the file browser lists all G-code files (including those in subfolders) in a flat list.
+ * Enable this option to display a hierarchical file browser.
+ *
+ * NOTES:
+ * - Without this option it helps to enable SDCARD_SORT_ALPHA so files are sorted before/after folders.
+ * - When used with the "new" panel, folder names will also have '.gcode' appended to their names.
+ * This hack is currently required to force the panel to show folders.
+ */
+ #define AC_SD_FOLDER_VIEW
+#endif
+
+//
+// Specify additional languages for the UI. Default specified by LCD_LANGUAGE.
+//
+#if ANY(DOGLCD, TFT_COLOR_UI, TOUCH_UI_FTDI_EVE)
+ //#define LCD_LANGUAGE_2 fr
+ //#define LCD_LANGUAGE_3 de
+ //#define LCD_LANGUAGE_4 es
+ //#define LCD_LANGUAGE_5 it
+ #ifdef LCD_LANGUAGE_2
+ //#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change
+ #endif
+#endif
+
//
// Touch UI for the FTDI Embedded Video Engine (EVE)
//
@@ -1488,6 +1717,8 @@
//#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480)
//#define LCD_ALEPHOBJECTS_CLCD_UI // Aleph Objects Color LCD UI
//#define LCD_FYSETC_TFT81050 // FYSETC with 5" (800x480)
+ //#define LCD_EVE3_50G // Matrix Orbital 5.0", 800x480, BT815
+ //#define LCD_EVE2_50G // Matrix Orbital 5.0", 800x480, FT813
// Correct the resolution if not using the stock TFT panel.
//#define TOUCH_UI_320x240
@@ -1544,18 +1775,14 @@
//#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾
//#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬
#endif
+
+ // Cyrillic character set, costs about 27KiB of flash
+ //#define TOUCH_UI_UTF8_CYRILLIC_CHARSET
#endif
// Use a smaller font when labels don't fit buttons
#define TOUCH_UI_FIT_TEXT
- // Allow language selection from menu at run-time (otherwise use LCD_LANGUAGE)
- //#define LCD_LANGUAGE_1 en
- //#define LCD_LANGUAGE_2 fr
- //#define LCD_LANGUAGE_3 de
- //#define LCD_LANGUAGE_4 es
- //#define LCD_LANGUAGE_5 it
-
// Use a numeric passcode for "Screen lock" keypad.
// (recommended for smaller displays)
//#define TOUCH_UI_PASSCODE
@@ -1715,6 +1942,10 @@
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
#endif
+#if BOTH(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS)
+ //#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space
+#endif
+
/**
* Repeatedly attempt G29 leveling until it succeeds.
* Stop after G29_MAX_RETRIES attempts.
@@ -1757,30 +1988,30 @@
//#define USE_TEMP_EXT_COMPENSATION
// Probe temperature calibration generates a table of values starting at PTC_SAMPLE_START
- // (e.g. 30), in steps of PTC_SAMPLE_RES (e.g. 5) with PTC_SAMPLE_COUNT (e.g. 10) samples.
+ // (e.g., 30), in steps of PTC_SAMPLE_RES (e.g., 5) with PTC_SAMPLE_COUNT (e.g., 10) samples.
- //#define PTC_SAMPLE_START 30.0f
- //#define PTC_SAMPLE_RES 5.0f
- //#define PTC_SAMPLE_COUNT 10U
+ //#define PTC_SAMPLE_START 30 // (°C)
+ //#define PTC_SAMPLE_RES 5 // (°C)
+ //#define PTC_SAMPLE_COUNT 10
// Bed temperature calibration builds a similar table.
- //#define BTC_SAMPLE_START 60.0f
- //#define BTC_SAMPLE_RES 5.0f
- //#define BTC_SAMPLE_COUNT 10U
+ //#define BTC_SAMPLE_START 60 // (°C)
+ //#define BTC_SAMPLE_RES 5 // (°C)
+ //#define BTC_SAMPLE_COUNT 10
// The temperature the probe should be at while taking measurements during bed temperature
// calibration.
- //#define BTC_PROBE_TEMP 30.0f
+ //#define BTC_PROBE_TEMP 30 // (°C)
- // Height above Z=0.0f to raise the nozzle. Lowering this can help the probe to heat faster.
- // Note: the Z=0.0f offset is determined by the probe offset which can be set using M851.
- //#define PTC_PROBE_HEATING_OFFSET 0.5f
+ // Height above Z=0.0 to raise the nozzle. Lowering this can help the probe to heat faster.
+ // Note: the Z=0.0 offset is determined by the probe offset which can be set using M851.
+ //#define PTC_PROBE_HEATING_OFFSET 0.5
// Height to raise the Z-probe between heating and taking the next measurement. Some probes
// may fail to untrigger if they have been triggered for a long time, which can be solved by
// increasing the height the probe is raised to.
- //#define PTC_PROBE_RAISE 15U
+ //#define PTC_PROBE_RAISE 15
// If the probe is outside of the defined range, use linear extrapolation using the closest
// point and the PTC_LINEAR_EXTRAPOLATION'th next point. E.g. if set to 4 it will use data[0]
@@ -1895,7 +2126,7 @@
// @section motion
// The number of linear moves that can be in the planner at once.
-// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g. 8, 16, 32)
+// The value of BLOCK_BUFFER_SIZE must be a power of 2 (e.g., 8, 16, 32)
#if BOTH(SDSUPPORT, DIRECT_STEPPING)
#define BLOCK_BUFFER_SIZE 8
#elif ENABLED(SDSUPPORT)
@@ -1931,9 +2162,6 @@
//#define SERIAL_XON_XOFF
#endif
-// Add M575 G-code to change the baud rate
-//#define BAUD_RATE_GCODE
-
#if ENABLED(SDSUPPORT)
// Enable this option to collect and display the maximum
// RX queue usage after transferring a file to SD.
@@ -1944,6 +2172,12 @@
//#define SERIAL_STATS_DROPPED_RX
#endif
+// Monitor RX buffer usage
+// Dump an error to the serial port if the serial receive buffer overflows.
+// If you see these errors, increase the RX_BUFFER_SIZE value.
+// Not supported on all platforms.
+//#define RX_BUFFER_MONITOR
+
/**
* Emergency Command Parser
*
@@ -1954,6 +2188,26 @@
*/
//#define EMERGENCY_PARSER
+/**
+ * Realtime Reporting (requires EMERGENCY_PARSER)
+ *
+ * - Report position and state of the machine (like Grbl).
+ * - Auto-report position during long moves.
+ * - Useful for CNC/LASER.
+ *
+ * Adds support for commands:
+ * S000 : Report State and Position while moving.
+ * P000 : Instant Pause / Hold while moving.
+ * R000 : Resume from Pause / Hold.
+ *
+ * - During Hold all Emergency Parser commands are available, as usual.
+ * - Enable NANODLP_Z_SYNC and NANODLP_ALL_AXIS for move command end-state reports.
+ */
+//#define REALTIME_REPORTING_COMMANDS
+#if ENABLED(REALTIME_REPORTING_COMMANDS)
+ //#define FULL_REPORT_TO_HOST_FEATURE // Auto-report the machine status like Grbl CNC
+#endif
+
// Bad Serial-connections can miss a received command by sending an 'ok'
// Therefore some clients abort after 30 seconds in a timeout.
// Some other clients start sending commands while receiving a 'wait'.
@@ -1997,21 +2251,21 @@
*/
//#define FWRETRACT
#if ENABLED(FWRETRACT)
- #define FWRETRACT_AUTORETRACT // Override slicer retractions
+ #define FWRETRACT_AUTORETRACT // Override slicer retractions
#if ENABLED(FWRETRACT_AUTORETRACT)
- #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length
- #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length
- #endif
- #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value)
- #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value)
- #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting
- #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise
- #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover)
- #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange)
- #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction
- #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction
+ #define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length
+ #define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length
+ #endif
+ #define RETRACT_LENGTH 3 // (mm) Default retract length (positive value)
+ #define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value)
+ #define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting
+ #define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise
+ #define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover)
+ #define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange)
+ #define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction
+ #define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction
#if ENABLED(MIXING_EXTRUDER)
- //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously
+ //#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously
#endif
#endif
@@ -2028,6 +2282,19 @@
//#define EVENT_GCODE_AFTER_TOOLCHANGE "G12X" // Extra G-code to run after tool-change
#endif
+ /**
+ * Extra G-code to run while executing tool-change commands. Can be used to use an additional
+ * stepper motor (I axis, see option LINEAR_AXES in Configuration.h) to drive the tool-changer.
+ */
+ //#define EVENT_GCODE_TOOLCHANGE_T0 "G28 A\nG1 A0" // Extra G-code to run while executing tool-change command T0
+ //#define EVENT_GCODE_TOOLCHANGE_T1 "G1 A10" // Extra G-code to run while executing tool-change command T1
+
+ /**
+ * Tool Sensors detect when tools have been picked up or dropped.
+ * Requires the pins TOOL_SENSOR1_PIN, TOOL_SENSOR2_PIN, etc.
+ */
+ //#define TOOL_SENSOR
+
/**
* Retract and prime filament on tool-change to reduce
* ooze and stringing and to get cleaner transitions.
@@ -2086,14 +2353,15 @@
#endif // HAS_MULTI_EXTRUDER
/**
- * Advanced Pause
- * Experimental feature for filament change support and for parking the nozzle when paused.
- * Adds the GCode M600 for initiating filament change.
- * If PARK_HEAD_ON_PAUSE enabled, adds the GCode M125 to pause printing and park the nozzle.
+ * Advanced Pause for Filament Change
+ * - Adds the G-code M600 Filament Change to initiate a filament change.
+ * - This feature is required for the default FILAMENT_RUNOUT_SCRIPT.
*
- * Requires an LCD display.
- * Requires NOZZLE_PARK_FEATURE.
- * This feature is required for the default FILAMENT_RUNOUT_SCRIPT.
+ * Requirements:
+ * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE.
+ * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER.
+ *
+ * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park.
*/
//#define ADVANCED_PAUSE_FEATURE
#if ENABLED(ADVANCED_PAUSE_FEATURE)
@@ -2159,7 +2427,7 @@
#if AXIS_DRIVER_TYPE_X2(TMC26X)
#define X2_MAX_CURRENT 1000
#define X2_SENSE_RESISTOR 91
- #define X2_MICROSTEPS 16
+ #define X2_MICROSTEPS X_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Y(TMC26X)
@@ -2171,7 +2439,7 @@
#if AXIS_DRIVER_TYPE_Y2(TMC26X)
#define Y2_MAX_CURRENT 1000
#define Y2_SENSE_RESISTOR 91
- #define Y2_MICROSTEPS 16
+ #define Y2_MICROSTEPS Y_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Z(TMC26X)
@@ -2183,19 +2451,37 @@
#if AXIS_DRIVER_TYPE_Z2(TMC26X)
#define Z2_MAX_CURRENT 1000
#define Z2_SENSE_RESISTOR 91
- #define Z2_MICROSTEPS 16
+ #define Z2_MICROSTEPS Z_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Z3(TMC26X)
#define Z3_MAX_CURRENT 1000
#define Z3_SENSE_RESISTOR 91
- #define Z3_MICROSTEPS 16
+ #define Z3_MICROSTEPS Z_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_Z4(TMC26X)
#define Z4_MAX_CURRENT 1000
#define Z4_SENSE_RESISTOR 91
- #define Z4_MICROSTEPS 16
+ #define Z4_MICROSTEPS Z_MICROSTEPS
+ #endif
+
+ #if AXIS_DRIVER_TYPE_I(TMC26X)
+ #define I_MAX_CURRENT 1000
+ #define I_SENSE_RESISTOR 91
+ #define I_MICROSTEPS 16
+ #endif
+
+ #if AXIS_DRIVER_TYPE_J(TMC26X)
+ #define J_MAX_CURRENT 1000
+ #define J_SENSE_RESISTOR 91
+ #define J_MICROSTEPS 16
+ #endif
+
+ #if AXIS_DRIVER_TYPE_K(TMC26X)
+ #define K_MAX_CURRENT 1000
+ #define K_SENSE_RESISTOR 91
+ #define K_MICROSTEPS 16
#endif
#if AXIS_DRIVER_TYPE_E0(TMC26X)
@@ -2207,43 +2493,43 @@
#if AXIS_DRIVER_TYPE_E1(TMC26X)
#define E1_MAX_CURRENT 1000
#define E1_SENSE_RESISTOR 91
- #define E1_MICROSTEPS 16
+ #define E1_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E2(TMC26X)
#define E2_MAX_CURRENT 1000
#define E2_SENSE_RESISTOR 91
- #define E2_MICROSTEPS 16
+ #define E2_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E3(TMC26X)
#define E3_MAX_CURRENT 1000
#define E3_SENSE_RESISTOR 91
- #define E3_MICROSTEPS 16
+ #define E3_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E4(TMC26X)
#define E4_MAX_CURRENT 1000
#define E4_SENSE_RESISTOR 91
- #define E4_MICROSTEPS 16
+ #define E4_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E5(TMC26X)
#define E5_MAX_CURRENT 1000
#define E5_SENSE_RESISTOR 91
- #define E5_MICROSTEPS 16
+ #define E5_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E6(TMC26X)
#define E6_MAX_CURRENT 1000
#define E6_SENSE_RESISTOR 91
- #define E6_MICROSTEPS 16
+ #define E6_MICROSTEPS E0_MICROSTEPS
#endif
#if AXIS_DRIVER_TYPE_E7(TMC26X)
#define E7_MAX_CURRENT 1000
#define E7_SENSE_RESISTOR 91
- #define E7_MICROSTEPS 16
+ #define E7_MICROSTEPS E0_MICROSTEPS
#endif
#endif // TMC26X
@@ -2288,7 +2574,7 @@
#if AXIS_IS_TMC(X2)
#define X2_CURRENT 800
#define X2_CURRENT_HOME X2_CURRENT
- #define X2_MICROSTEPS 16
+ #define X2_MICROSTEPS X_MICROSTEPS
#define X2_RSENSE 0.11
#define X2_CHAIN_POS -1
//#define X2_INTERPOLATE true
@@ -2306,7 +2592,7 @@
#if AXIS_IS_TMC(Y2)
#define Y2_CURRENT 800
#define Y2_CURRENT_HOME Y2_CURRENT
- #define Y2_MICROSTEPS 16
+ #define Y2_MICROSTEPS Y_MICROSTEPS
#define Y2_RSENSE 0.11
#define Y2_CHAIN_POS -1
//#define Y2_INTERPOLATE true
@@ -2324,7 +2610,7 @@
#if AXIS_IS_TMC(Z2)
#define Z2_CURRENT 800
#define Z2_CURRENT_HOME Z2_CURRENT
- #define Z2_MICROSTEPS 16
+ #define Z2_MICROSTEPS Z_MICROSTEPS
#define Z2_RSENSE 0.11
#define Z2_CHAIN_POS -1
//#define Z2_INTERPOLATE true
@@ -2333,7 +2619,7 @@
#if AXIS_IS_TMC(Z3)
#define Z3_CURRENT 800
#define Z3_CURRENT_HOME Z3_CURRENT
- #define Z3_MICROSTEPS 16
+ #define Z3_MICROSTEPS Z_MICROSTEPS
#define Z3_RSENSE 0.11
#define Z3_CHAIN_POS -1
//#define Z3_INTERPOLATE true
@@ -2342,12 +2628,39 @@
#if AXIS_IS_TMC(Z4)
#define Z4_CURRENT 800
#define Z4_CURRENT_HOME Z4_CURRENT
- #define Z4_MICROSTEPS 16
+ #define Z4_MICROSTEPS Z_MICROSTEPS
#define Z4_RSENSE 0.11
#define Z4_CHAIN_POS -1
//#define Z4_INTERPOLATE true
#endif
+ #if AXIS_IS_TMC(I)
+ #define I_CURRENT 800
+ #define I_CURRENT_HOME I_CURRENT
+ #define I_MICROSTEPS 16
+ #define I_RSENSE 0.11
+ #define I_CHAIN_POS -1
+ //#define I_INTERPOLATE true
+ #endif
+
+ #if AXIS_IS_TMC(J)
+ #define J_CURRENT 800
+ #define J_CURRENT_HOME J_CURRENT
+ #define J_MICROSTEPS 16
+ #define J_RSENSE 0.11
+ #define J_CHAIN_POS -1
+ //#define J_INTERPOLATE true
+ #endif
+
+ #if AXIS_IS_TMC(K)
+ #define K_CURRENT 800
+ #define K_CURRENT_HOME K_CURRENT
+ #define K_MICROSTEPS 16
+ #define K_RSENSE 0.11
+ #define K_CHAIN_POS -1
+ //#define K_INTERPOLATE true
+ #endif
+
#if AXIS_IS_TMC(E0)
#define E0_CURRENT 800
#define E0_MICROSTEPS 16
@@ -2358,7 +2671,7 @@
#if AXIS_IS_TMC(E1)
#define E1_CURRENT 800
- #define E1_MICROSTEPS 16
+ #define E1_MICROSTEPS E0_MICROSTEPS
#define E1_RSENSE 0.11
#define E1_CHAIN_POS -1
//#define E1_INTERPOLATE true
@@ -2366,7 +2679,7 @@
#if AXIS_IS_TMC(E2)
#define E2_CURRENT 800
- #define E2_MICROSTEPS 16
+ #define E2_MICROSTEPS E0_MICROSTEPS
#define E2_RSENSE 0.11
#define E2_CHAIN_POS -1
//#define E2_INTERPOLATE true
@@ -2374,7 +2687,7 @@
#if AXIS_IS_TMC(E3)
#define E3_CURRENT 800
- #define E3_MICROSTEPS 16
+ #define E3_MICROSTEPS E0_MICROSTEPS
#define E3_RSENSE 0.11
#define E3_CHAIN_POS -1
//#define E3_INTERPOLATE true
@@ -2382,7 +2695,7 @@
#if AXIS_IS_TMC(E4)
#define E4_CURRENT 800
- #define E4_MICROSTEPS 16
+ #define E4_MICROSTEPS E0_MICROSTEPS
#define E4_RSENSE 0.11
#define E4_CHAIN_POS -1
//#define E4_INTERPOLATE true
@@ -2390,7 +2703,7 @@
#if AXIS_IS_TMC(E5)
#define E5_CURRENT 800
- #define E5_MICROSTEPS 16
+ #define E5_MICROSTEPS E0_MICROSTEPS
#define E5_RSENSE 0.11
#define E5_CHAIN_POS -1
//#define E5_INTERPOLATE true
@@ -2398,7 +2711,7 @@
#if AXIS_IS_TMC(E6)
#define E6_CURRENT 800
- #define E6_MICROSTEPS 16
+ #define E6_MICROSTEPS E0_MICROSTEPS
#define E6_RSENSE 0.11
#define E6_CHAIN_POS -1
//#define E6_INTERPOLATE true
@@ -2406,7 +2719,7 @@
#if AXIS_IS_TMC(E7)
#define E7_CURRENT 800
- #define E7_MICROSTEPS 16
+ #define E7_MICROSTEPS E0_MICROSTEPS
#define E7_RSENSE 0.11
#define E7_CHAIN_POS -1
//#define E7_INTERPOLATE true
@@ -2423,6 +2736,10 @@
//#define Y2_CS_PIN -1
//#define Z2_CS_PIN -1
//#define Z3_CS_PIN -1
+ //#define Z4_CS_PIN -1
+ //#define I_CS_PIN -1
+ //#define J_CS_PIN -1
+ //#define K_CS_PIN -1
//#define E0_CS_PIN -1
//#define E1_CS_PIN -1
//#define E2_CS_PIN -1
@@ -2454,22 +2771,25 @@
* Set *_SERIAL_TX_PIN and *_SERIAL_RX_PIN to match for all drivers
* on the same serial port, either here or in your board's pins file.
*/
- #define X_SLAVE_ADDRESS 0
- #define Y_SLAVE_ADDRESS 0
- #define Z_SLAVE_ADDRESS 0
- #define X2_SLAVE_ADDRESS 0
- #define Y2_SLAVE_ADDRESS 0
- #define Z2_SLAVE_ADDRESS 0
- #define Z3_SLAVE_ADDRESS 0
- #define Z4_SLAVE_ADDRESS 0
- #define E0_SLAVE_ADDRESS 0
- #define E1_SLAVE_ADDRESS 0
- #define E2_SLAVE_ADDRESS 0
- #define E3_SLAVE_ADDRESS 0
- #define E4_SLAVE_ADDRESS 0
- #define E5_SLAVE_ADDRESS 0
- #define E6_SLAVE_ADDRESS 0
- #define E7_SLAVE_ADDRESS 0
+ //#define X_SLAVE_ADDRESS 0
+ //#define Y_SLAVE_ADDRESS 0
+ //#define Z_SLAVE_ADDRESS 0
+ //#define X2_SLAVE_ADDRESS 0
+ //#define Y2_SLAVE_ADDRESS 0
+ //#define Z2_SLAVE_ADDRESS 0
+ //#define Z3_SLAVE_ADDRESS 0
+ //#define Z4_SLAVE_ADDRESS 0
+ //#define I_SLAVE_ADDRESS 0
+ //#define J_SLAVE_ADDRESS 0
+ //#define K_SLAVE_ADDRESS 0
+ //#define E0_SLAVE_ADDRESS 0
+ //#define E1_SLAVE_ADDRESS 0
+ //#define E2_SLAVE_ADDRESS 0
+ //#define E3_SLAVE_ADDRESS 0
+ //#define E4_SLAVE_ADDRESS 0
+ //#define E5_SLAVE_ADDRESS 0
+ //#define E6_SLAVE_ADDRESS 0
+ //#define E7_SLAVE_ADDRESS 0
/**
* Software enable
@@ -2486,6 +2806,9 @@
*/
#define STEALTHCHOP_XY
#define STEALTHCHOP_Z
+ #define STEALTHCHOP_I
+ #define STEALTHCHOP_J
+ #define STEALTHCHOP_K
#define STEALTHCHOP_E
/**
@@ -2503,23 +2826,23 @@
* Define your own with:
* { , , hysteresis_start[1..8] }
*/
- #define CHOPPER_TIMING CHOPPER_DEFAULT_24V // All axes (override below)
- //#define CHOPPER_TIMING_X CHOPPER_DEFAULT_12V // For X Axes (override below)
- //#define CHOPPER_TIMING_X2 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_12V // For Y Axes (override below)
- //#define CHOPPER_TIMING_Y2 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_Z CHOPPER_DEFAULT_12V // For Z Axes (override below)
- //#define CHOPPER_TIMING_Z2 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_Z3 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_Z4 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E CHOPPER_DEFAULT_12V // For Extruders (override below)
- //#define CHOPPER_TIMING_E1 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E2 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E3 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E4 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E5 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E6 CHOPPER_DEFAULT_12V
- //#define CHOPPER_TIMING_E7 CHOPPER_DEFAULT_12V
+ #define CHOPPER_TIMING CHOPPER_DEFAULT_12V // All axes (override below) // TODO 24V?
+ //#define CHOPPER_TIMING_X CHOPPER_TIMING // 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_Z CHOPPER_TIMING // For Z Axes (override below)
+ //#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
+ //#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
+ //#define CHOPPER_TIMING_Z4 CHOPPER_TIMING_Z
+ //#define CHOPPER_TIMING_E CHOPPER_TIMING // 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
+ //#define CHOPPER_TIMING_E4 CHOPPER_TIMING_E
+ //#define CHOPPER_TIMING_E5 CHOPPER_TIMING_E
+ //#define CHOPPER_TIMING_E6 CHOPPER_TIMING_E
+ //#define CHOPPER_TIMING_E7 CHOPPER_TIMING_E
/**
* Monitor Trinamic drivers
@@ -2557,6 +2880,9 @@
#define Z2_HYBRID_THRESHOLD 3
#define Z3_HYBRID_THRESHOLD 3
#define Z4_HYBRID_THRESHOLD 3
+ #define I_HYBRID_THRESHOLD 3
+ #define J_HYBRID_THRESHOLD 3
+ #define K_HYBRID_THRESHOLD 3
#define E0_HYBRID_THRESHOLD 30
#define E1_HYBRID_THRESHOLD 30
#define E2_HYBRID_THRESHOLD 30
@@ -2582,7 +2908,7 @@
*
* It is recommended to set HOMING_BUMP_MM to { 0, 0, 0 }.
*
- * SPI_ENDSTOPS *** Beta feature! *** TMC2130 Only ***
+ * SPI_ENDSTOPS *** Beta feature! *** TMC2130/TMC5160 Only ***
* Poll the driver through SPI to determine load when homing.
* Removes the need for a wire from DIAG1 to an endstop pin.
*
@@ -2603,6 +2929,9 @@
//#define Z2_STALL_SENSITIVITY Z_STALL_SENSITIVITY
//#define Z3_STALL_SENSITIVITY Z_STALL_SENSITIVITY
//#define Z4_STALL_SENSITIVITY Z_STALL_SENSITIVITY
+ //#define I_STALL_SENSITIVITY 8
+ //#define J_STALL_SENSITIVITY 8
+ //#define K_STALL_SENSITIVITY 8
//#define SPI_ENDSTOPS // TMC2130 only
//#define IMPROVE_HOMING_RELIABILITY
#endif
@@ -2627,7 +2956,7 @@
/**
* Enable M122 debugging command for TMC stepper drivers.
- * M122 S0/1 will enable continous reporting.
+ * M122 S0/1 will enable continuous reporting.
*/
//#define TMC_DEBUG
@@ -2681,138 +3010,165 @@
#endif
#if AXIS_IS_L64XX(X2)
- #define X2_MICROSTEPS 128
- #define X2_OVERCURRENT 2000
- #define X2_STALLCURRENT 1500
- #define X2_MAX_VOLTAGE 127
- #define X2_CHAIN_POS -1
- #define X2_SLEW_RATE 1
+ #define X2_MICROSTEPS X_MICROSTEPS
+ #define X2_OVERCURRENT 2000
+ #define X2_STALLCURRENT 1500
+ #define X2_MAX_VOLTAGE 127
+ #define X2_CHAIN_POS -1
+ #define X2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Y)
- #define Y_MICROSTEPS 128
- #define Y_OVERCURRENT 2000
- #define Y_STALLCURRENT 1500
- #define Y_MAX_VOLTAGE 127
- #define Y_CHAIN_POS -1
- #define Y_SLEW_RATE 1
+ #define Y_MICROSTEPS 128
+ #define Y_OVERCURRENT 2000
+ #define Y_STALLCURRENT 1500
+ #define Y_MAX_VOLTAGE 127
+ #define Y_CHAIN_POS -1
+ #define Y_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Y2)
- #define Y2_MICROSTEPS 128
- #define Y2_OVERCURRENT 2000
- #define Y2_STALLCURRENT 1500
- #define Y2_MAX_VOLTAGE 127
- #define Y2_CHAIN_POS -1
- #define Y2_SLEW_RATE 1
+ #define Y2_MICROSTEPS Y_MICROSTEPS
+ #define Y2_OVERCURRENT 2000
+ #define Y2_STALLCURRENT 1500
+ #define Y2_MAX_VOLTAGE 127
+ #define Y2_CHAIN_POS -1
+ #define Y2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z)
- #define Z_MICROSTEPS 128
- #define Z_OVERCURRENT 2000
- #define Z_STALLCURRENT 1500
- #define Z_MAX_VOLTAGE 127
- #define Z_CHAIN_POS -1
- #define Z_SLEW_RATE 1
+ #define Z_MICROSTEPS 128
+ #define Z_OVERCURRENT 2000
+ #define Z_STALLCURRENT 1500
+ #define Z_MAX_VOLTAGE 127
+ #define Z_CHAIN_POS -1
+ #define Z_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z2)
- #define Z2_MICROSTEPS 128
- #define Z2_OVERCURRENT 2000
- #define Z2_STALLCURRENT 1500
- #define Z2_MAX_VOLTAGE 127
- #define Z2_CHAIN_POS -1
- #define Z2_SLEW_RATE 1
+ #define Z2_MICROSTEPS Z_MICROSTEPS
+ #define Z2_OVERCURRENT 2000
+ #define Z2_STALLCURRENT 1500
+ #define Z2_MAX_VOLTAGE 127
+ #define Z2_CHAIN_POS -1
+ #define Z2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z3)
- #define Z3_MICROSTEPS 128
- #define Z3_OVERCURRENT 2000
- #define Z3_STALLCURRENT 1500
- #define Z3_MAX_VOLTAGE 127
- #define Z3_CHAIN_POS -1
- #define Z3_SLEW_RATE 1
+ #define Z3_MICROSTEPS Z_MICROSTEPS
+ #define Z3_OVERCURRENT 2000
+ #define Z3_STALLCURRENT 1500
+ #define Z3_MAX_VOLTAGE 127
+ #define Z3_CHAIN_POS -1
+ #define Z3_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(Z4)
- #define Z4_MICROSTEPS 128
- #define Z4_OVERCURRENT 2000
- #define Z4_STALLCURRENT 1500
- #define Z4_MAX_VOLTAGE 127
- #define Z4_CHAIN_POS -1
- #define Z4_SLEW_RATE 1
+ #define Z4_MICROSTEPS Z_MICROSTEPS
+ #define Z4_OVERCURRENT 2000
+ #define Z4_STALLCURRENT 1500
+ #define Z4_MAX_VOLTAGE 127
+ #define Z4_CHAIN_POS -1
+ #define Z4_SLEW_RATE 1
+ #endif
+
+ #if AXIS_DRIVER_TYPE_I(L6470)
+ #define I_MICROSTEPS 128
+ #define I_OVERCURRENT 2000
+ #define I_STALLCURRENT 1500
+ #define I_MAX_VOLTAGE 127
+ #define I_CHAIN_POS -1
+ #define I_SLEW_RATE 1
+ #endif
+
+ #if AXIS_DRIVER_TYPE_J(L6470)
+ #define J_MICROSTEPS 128
+ #define J_OVERCURRENT 2000
+ #define J_STALLCURRENT 1500
+ #define J_MAX_VOLTAGE 127
+ #define J_CHAIN_POS -1
+ #define J_SLEW_RATE 1
+ #endif
+
+ #if AXIS_DRIVER_TYPE_K(L6470)
+ #define K_MICROSTEPS 128
+ #define K_OVERCURRENT 2000
+ #define K_STALLCURRENT 1500
+ #define K_MAX_VOLTAGE 127
+ #define K_CHAIN_POS -1
+ #define K_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E0)
- #define E0_MICROSTEPS 128
- #define E0_OVERCURRENT 2000
- #define E0_STALLCURRENT 1500
- #define E0_MAX_VOLTAGE 127
- #define E0_CHAIN_POS -1
- #define E0_SLEW_RATE 1
+ #define E0_MICROSTEPS 128
+ #define E0_OVERCURRENT 2000
+ #define E0_STALLCURRENT 1500
+ #define E0_MAX_VOLTAGE 127
+ #define E0_CHAIN_POS -1
+ #define E0_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E1)
- #define E1_MICROSTEPS 128
- #define E1_OVERCURRENT 2000
- #define E1_STALLCURRENT 1500
- #define E1_MAX_VOLTAGE 127
- #define E1_CHAIN_POS -1
- #define E1_SLEW_RATE 1
+ #define E1_MICROSTEPS E0_MICROSTEPS
+ #define E1_OVERCURRENT 2000
+ #define E1_STALLCURRENT 1500
+ #define E1_MAX_VOLTAGE 127
+ #define E1_CHAIN_POS -1
+ #define E1_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E2)
- #define E2_MICROSTEPS 128
- #define E2_OVERCURRENT 2000
- #define E2_STALLCURRENT 1500
- #define E2_MAX_VOLTAGE 127
- #define E2_CHAIN_POS -1
- #define E2_SLEW_RATE 1
+ #define E2_MICROSTEPS E0_MICROSTEPS
+ #define E2_OVERCURRENT 2000
+ #define E2_STALLCURRENT 1500
+ #define E2_MAX_VOLTAGE 127
+ #define E2_CHAIN_POS -1
+ #define E2_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E3)
- #define E3_MICROSTEPS 128
- #define E3_OVERCURRENT 2000
- #define E3_STALLCURRENT 1500
- #define E3_MAX_VOLTAGE 127
- #define E3_CHAIN_POS -1
- #define E3_SLEW_RATE 1
+ #define E3_MICROSTEPS E0_MICROSTEPS
+ #define E3_OVERCURRENT 2000
+ #define E3_STALLCURRENT 1500
+ #define E3_MAX_VOLTAGE 127
+ #define E3_CHAIN_POS -1
+ #define E3_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E4)
- #define E4_MICROSTEPS 128
- #define E4_OVERCURRENT 2000
- #define E4_STALLCURRENT 1500
- #define E4_MAX_VOLTAGE 127
- #define E4_CHAIN_POS -1
- #define E4_SLEW_RATE 1
+ #define E4_MICROSTEPS E0_MICROSTEPS
+ #define E4_OVERCURRENT 2000
+ #define E4_STALLCURRENT 1500
+ #define E4_MAX_VOLTAGE 127
+ #define E4_CHAIN_POS -1
+ #define E4_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E5)
- #define E5_MICROSTEPS 128
- #define E5_OVERCURRENT 2000
- #define E5_STALLCURRENT 1500
- #define E5_MAX_VOLTAGE 127
- #define E5_CHAIN_POS -1
- #define E5_SLEW_RATE 1
+ #define E5_MICROSTEPS E0_MICROSTEPS
+ #define E5_OVERCURRENT 2000
+ #define E5_STALLCURRENT 1500
+ #define E5_MAX_VOLTAGE 127
+ #define E5_CHAIN_POS -1
+ #define E5_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E6)
- #define E6_MICROSTEPS 128
- #define E6_OVERCURRENT 2000
- #define E6_STALLCURRENT 1500
- #define E6_MAX_VOLTAGE 127
- #define E6_CHAIN_POS -1
- #define E6_SLEW_RATE 1
+ #define E6_MICROSTEPS E0_MICROSTEPS
+ #define E6_OVERCURRENT 2000
+ #define E6_STALLCURRENT 1500
+ #define E6_MAX_VOLTAGE 127
+ #define E6_CHAIN_POS -1
+ #define E6_SLEW_RATE 1
#endif
#if AXIS_IS_L64XX(E7)
- #define E7_MICROSTEPS 128
- #define E7_OVERCURRENT 2000
- #define E7_STALLCURRENT 1500
- #define E7_MAX_VOLTAGE 127
- #define E7_CHAIN_POS -1
- #define E7_SLEW_RATE 1
+ #define E7_MICROSTEPS E0_MICROSTEPS
+ #define E7_OVERCURRENT 2000
+ #define E7_STALLCURRENT 1500
+ #define E7_MAX_VOLTAGE 127
+ #define E7_CHAIN_POS -1
+ #define E7_SLEW_RATE 1
#endif
/**
@@ -2948,10 +3304,22 @@
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
- //#define SPINDLE_SERVO // A servo converting an angle to spindle power
+ //#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11
+ #if ENABLED(AIR_EVACUATION)
+ #define AIR_EVACUATION_ACTIVE LOW // Set to "HIGH" if the on/off function is active HIGH
+ //#define AIR_EVACUATION_PIN 42 // Override the default Cutter Vacuum or Laser Blower pin
+ #endif
+
+ //#define AIR_ASSIST // Air Assist control with G-codes M8-M9
+ #if ENABLED(AIR_ASSIST)
+ #define AIR_ASSIST_ACTIVE LOW // Active state on air assist pin
+ //#define AIR_ASSIST_PIN 44 // Override the default Air Assist pin
+ #endif
+
+ //#define SPINDLE_SERVO // A servo converting an angle to spindle power
#ifdef SPINDLE_SERVO
- #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control
- #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle
+ #define SPINDLE_SERVO_NR 0 // Index of servo used for spindle control
+ #define SPINDLE_SERVO_MIN 10 // Minimum angle for servo spindle
#endif
/**
@@ -3002,6 +3370,10 @@
#define SPEED_POWER_MAX 100 // (%) 0-100
#define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
+ // Define the minimum and maximum test pulse time values for a laser test fire function
+ #define LASER_TEST_PULSE_MIN 1 // Used with Laser Control Menu
+ #define LASER_TEST_PULSE_MAX 999 // Caution: Menu may not show more than 3 characters
+
/**
* Enable inline laser power to be handled in the planner / stepper routines.
* Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I)
@@ -3076,8 +3448,30 @@
#define SPINDLE_LASER_POWERDOWN_DELAY 50 // (ms) Delay to allow the spindle to stop
#endif
+
+ //
+ // Laser I2C Ammeter (High precision INA226 low/high side module)
+ //
+ //#define I2C_AMMETER
+ #if ENABLED(I2C_AMMETER)
+ #define I2C_AMMETER_IMAX 0.1 // (Amps) Calibration value for the expected current range
+ #define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value
+ #endif
+
#endif
-#endif
+#endif // SPINDLE_FEATURE || LASER_FEATURE
+
+/**
+ * Synchronous Laser Control with M106/M107
+ *
+ * Marlin normally applies M106/M107 fan speeds at a time "soon after" processing
+ * a planner block. This is too inaccurate for a PWM/TTL laser attached to the fan
+ * header (as with some add-on laser kits). Enable this option to set fan/laser
+ * speeds with much more exact timing for improved print fidelity.
+ *
+ * NOTE: This option sacrifices some cooling fan speed options.
+ */
+//#define LASER_SYNCHRONOUS_M106_M107
/**
* Coolant Control
@@ -3138,13 +3532,27 @@
*/
//#define POWER_MONITOR_CURRENT // Monitor the system current
//#define POWER_MONITOR_VOLTAGE // Monitor the system voltage
-#if EITHER(POWER_MONITOR_CURRENT, POWER_MONITOR_VOLTAGE)
- #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF!
- #define POWER_MONITOR_CURRENT_OFFSET -1 // Offset value for current sensors with linear function output
- #define POWER_MONITOR_VOLTS_PER_VOLT 0.11786 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF!
+
+#if ENABLED(POWER_MONITOR_CURRENT)
+ #define POWER_MONITOR_VOLTS_PER_AMP 0.05000 // Input voltage to the MCU analog pin per amp - DO NOT apply more than ADC_VREF!
+ #define POWER_MONITOR_CURRENT_OFFSET 0 // Offset (in amps) applied to the calculated current
#define POWER_MONITOR_FIXED_VOLTAGE 13.6 // Voltage for a current sensor with no voltage sensor (for power display)
#endif
+#if ENABLED(POWER_MONITOR_VOLTAGE)
+ #define POWER_MONITOR_VOLTS_PER_VOLT 0.077933 // Input voltage to the MCU analog pin per volt - DO NOT apply more than ADC_VREF!
+ #define POWER_MONITOR_VOLTAGE_OFFSET 0 // Offset (in volts) applied to the calculated voltage
+#endif
+
+/**
+ * Stepper Driver Anti-SNAFU Protection
+ *
+ * If the SAFE_POWER_PIN is defined for your board, Marlin will check
+ * that stepper drivers are properly plugged in before applying power.
+ * Disable protection if your stepper drivers don't support the feature.
+ */
+//#define DISABLE_DRIVER_SAFE_POWER_PROTECT
+
/**
* CNC Coordinate Systems
*
@@ -3158,6 +3566,11 @@
*/
#define AUTO_REPORT_TEMPERATURES
+/**
+ * Auto-report position with M154 S
+ */
+//#define AUTO_REPORT_POSITION
+
/**
* Include capabilities in M115 output
*/
@@ -3227,7 +3640,7 @@
#define PROPORTIONAL_FONT_RATIO 1.0
/**
- * Spend 28 bytes of SRAM to optimize the GCode parser
+ * Spend 28 bytes of SRAM to optimize the G-code parser
*/
#define FASTER_GCODE_PARSER
@@ -3235,6 +3648,10 @@
//#define GCODE_QUOTED_STRINGS // Support for quoted string parameters
#endif
+// Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack)
+//#define MEATPACK_ON_SERIAL_PORT_1
+//#define MEATPACK_ON_SERIAL_PORT_2
+
//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase
//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW
@@ -3274,29 +3691,99 @@
#endif
/**
- * User-defined menu items that execute custom GCode
+ * User-defined menu items to run custom G-code.
+ * Up to 25 may be defined, but the actual number is LCD-dependent.
*/
-//#define CUSTOM_USER_MENUS
-#if ENABLED(CUSTOM_USER_MENUS)
- //#define CUSTOM_USER_MENU_TITLE "Custom Commands"
- #define USER_SCRIPT_DONE "M117 User Script Done"
- #define USER_SCRIPT_AUDIBLE_FEEDBACK
- //#define USER_SCRIPT_RETURN // Return to status screen after a script
- #define USER_DESC_1 "Home & UBL Info"
- #define USER_GCODE_1 "G28\nG29 W"
+// Custom Menu: Main Menu
+//#define CUSTOM_MENU_MAIN
+#if ENABLED(CUSTOM_MENU_MAIN)
+ //#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_ONLY_IDLE // Only show custom menu when the machine is idle
+
+ #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_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_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_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 "Home & Info"
+ //#define MAIN_MENU_ITEM_5_GCODE "G28\nM503"
+ //#define MAIN_MENU_ITEM_5_CONFIRM
+#endif
- #define USER_DESC_2 "Preheat for " PREHEAT_1_LABEL
- #define USER_GCODE_2 "M140 S" STRINGIFY(PREHEAT_1_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_1_TEMP_HOTEND)
+// Custom Menu: Configuration Menu
+//#define CUSTOM_MENU_CONFIG
+#if ENABLED(CUSTOM_MENU_CONFIG)
+ //#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands"
+ #define CUSTOM_MENU_CONFIG_SCRIPT_DONE "M117 Wireless Script Done"
+ #define CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK
+ //#define CUSTOM_MENU_CONFIG_SCRIPT_RETURN // Return to status screen after a script
+ #define CUSTOM_MENU_CONFIG_ONLY_IDLE // Only show custom menu when the machine is idle
+
+ #define CONFIG_MENU_ITEM_1_DESC "Wifi ON"
+ #define CONFIG_MENU_ITEM_1_GCODE "M118 [ESP110] WIFI-STA pwd=12345678"
+ //#define CONFIG_MENU_ITEM_1_CONFIRM // Show a confirmation dialog before this action
+
+ #define CONFIG_MENU_ITEM_2_DESC "Bluetooth ON"
+ #define CONFIG_MENU_ITEM_2_GCODE "M118 [ESP110] BT pwd=12345678"
+ //#define CONFIG_MENU_ITEM_2_CONFIRM
+
+ //#define CONFIG_MENU_ITEM_3_DESC "Radio OFF"
+ //#define CONFIG_MENU_ITEM_3_GCODE "M118 [ESP110] OFF pwd=12345678"
+ //#define CONFIG_MENU_ITEM_3_CONFIRM
+
+ //#define CONFIG_MENU_ITEM_4_DESC "Wifi ????"
+ //#define CONFIG_MENU_ITEM_4_GCODE "M118 ????"
+ //#define CONFIG_MENU_ITEM_4_CONFIRM
+
+ //#define CONFIG_MENU_ITEM_5_DESC "Wifi ????"
+ //#define CONFIG_MENU_ITEM_5_GCODE "M118 ????"
+ //#define CONFIG_MENU_ITEM_5_CONFIRM
+#endif
- #define USER_DESC_3 "Preheat for " PREHEAT_2_LABEL
- #define USER_GCODE_3 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nM104 S" STRINGIFY(PREHEAT_2_TEMP_HOTEND)
+/**
+ * User-defined buttons to run custom G-code.
+ * Up to 25 may be defined.
+ */
+//#define CUSTOM_USER_BUTTONS
+#if ENABLED(CUSTOM_USER_BUTTONS)
+ //#define BUTTON1_PIN -1
+ #if PIN_EXISTS(BUTTON1)
+ #define BUTTON1_HIT_STATE LOW // State of the triggered button. NC=LOW. NO=HIGH.
+ #define BUTTON1_WHEN_PRINTING false // Button allowed to trigger during printing?
+ #define BUTTON1_GCODE "G28"
+ #define BUTTON1_DESC "Homing" // Optional string to set the LCD status
+ #endif
- #define USER_DESC_4 "Heat Bed/Home/Level"
- #define USER_GCODE_4 "M140 S" STRINGIFY(PREHEAT_2_TEMP_BED) "\nG28\nG29"
+ //#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 USER_DESC_5 "Home & Info"
- #define USER_GCODE_5 "G28\nM503"
+ //#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
/**
@@ -3325,6 +3812,9 @@
* Implement M486 to allow Marlin to skip objects
*/
//#define CANCEL_OBJECTS
+#if ENABLED(CANCEL_OBJECTS)
+ #define CANCEL_OBJECTS_REPORTING // Emit the current object as a status message
+#endif
/**
* I2C position encoders for closed loop control.
@@ -3401,7 +3891,7 @@
*/
#define I2CPE_MIN_UPD_TIME_MS 4 // (ms) Minimum time between encoder checks.
- // Use a rolling average to identify persistant errors that indicate skips, as opposed to vibration and noise.
+ // Use a rolling average to identify persistent errors that indicate skips, as opposed to vibration and noise.
#define I2CPE_ERR_ROLLING_AVERAGE
#endif // I2C_POSITION_ENCODERS
@@ -3440,12 +3930,22 @@
#define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move
//#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction
- //#define GANTRY_CALIBRATION_SAFE_POSITION { X_CENTER, Y_CENTER } // Safe position for nozzle
+ //#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle
//#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM
//#define GANTRY_CALIBRATION_COMMANDS_PRE ""
#define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position
#endif
+/**
+ * Instant freeze / unfreeze functionality
+ * Specified pin has pullup and connecting to ground will instantly pause motion.
+ * Potentially useful for emergency stop that allows being resumed.
+ */
+//#define FREEZE_FEATURE
+#if ENABLED(FREEZE_FEATURE)
+ //#define FREEZE_PIN 41 // Override the default (KILL) pin here
+#endif
+
/**
* MAX7219 Debug Matrix
*
@@ -3482,14 +3982,20 @@
/**
* NanoDLP Sync support
*
- * Add support for Synchronized Z moves when using with NanoDLP. G0/G1 axis moves will output "Z_move_comp"
- * string to enable synchronization with DLP projector exposure. This change will allow to use
- * [[WaitForDoneMessage]] instead of populating your gcode with M400 commands
+ * Support for Synchronized Z moves when used with NanoDLP. G0/G1 axis moves will
+ * output a "Z_move_comp" string to enable synchronization with DLP projector exposure.
+ * This feature allows you to use [[WaitForDoneMessage]] instead of M400 commands.
*/
//#define NANODLP_Z_SYNC
#if ENABLED(NANODLP_Z_SYNC)
- //#define NANODLP_ALL_AXIS // Enables "Z_move_comp" output on any axis move.
- // Default behavior is limited to Z axis only.
+ //#define NANODLP_ALL_AXIS // Send a "Z_move_comp" report for any axis move (not just Z).
+#endif
+
+/**
+ * Ethernet. Use M552 to enable and set the IP address.
+ */
+#if HAS_ETHERNET
+ #define MAC_ADDRESS { 0xDE, 0xAD, 0xBE, 0xEF, 0xF0, 0x0D } // A MAC address unique to your network
#endif
/**
@@ -3522,16 +4028,26 @@
#endif
/**
- * Průša Multi-Material Unit v2
+ * Průša Multi-Material Unit (MMU)
* Enable in Configuration.h
+ *
+ * These devices allow a single stepper driver on the board to drive
+ * multi-material feeders with any number of stepper motors.
*/
-#if ENABLED(PRUSA_MMU2)
-
+#if HAS_PRUSA_MMU1
+ /**
+ * This option only allows the multiplexer to switch on tool-change.
+ * Additional options to configure custom E moves are pending.
+ *
+ * Override the default DIO selector pins here, if needed.
+ * Some pins files may provide defaults for these pins.
+ */
+ //#define E_MUX0_PIN 40 // Always Required
+ //#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs
+ //#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs
+#elif HAS_PRUSA_MMU2
// Serial port used for communication with MMU2.
- // For AVR enable the UART port used for the MMU. (e.g., mmuSerial)
- // For 32-bit boards check your HAL for available serial ports. (e.g., Serial2)
#define MMU2_SERIAL_PORT 2
- #define MMU2_SERIAL mmuSerial
// Use hardware reset for MMU if a pin is defined for it
//#define MMU2_RST_PIN 23
@@ -3544,44 +4060,29 @@
// Add an LCD menu for MMU2
//#define MMU2_MENUS
-
- // Settings for filament load / unload.
- // This is for Průša MK3-style extruders. Customize for your hardware.
- #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
- #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \
- { 7.2, 1145 }, \
- { 14.4, 871 }, \
- { 36.0, 1393 }, \
- { 14.4, 871 }, \
- { 50.0, 198 }
-
- #define MMU2_RAMMING_SEQUENCE \
- { 1.0, 1000 }, \
- { 1.0, 1500 }, \
- { 2.0, 2000 }, \
- { 1.5, 3000 }, \
- { 2.5, 4000 }, \
- { -15.0, 5000 }, \
- { -14.0, 1200 }, \
- { -6.0, 600 }, \
- { 10.0, 700 }, \
- { -10.0, 400 }, \
- { -50.0, 2000 }
-
- /**
- * MMU Extruder Sensor
- *
- * Support for a Průša (or other) IR Sensor to detect filament near the extruder
- * and make loading more reliable. Suitable for an extruder equipped with a filament
- * sensor less than 38mm from the gears.
- *
- * During loading the extruder will stop when the sensor is triggered, then do a last
- * move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
- * If all attempts fail, a filament runout will be triggered.
- */
- //#define MMU_EXTRUDER_SENSOR
- #if ENABLED(MMU_EXTRUDER_SENSOR)
- #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
+ #if EITHER(MMU2_MENUS, HAS_PRUSA_MMU2S)
+ // Settings for filament load / unload from the LCD menu.
+ // This is for Průša MK3-style extruders. Customize for your hardware.
+ #define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
+ #define MMU2_LOAD_TO_NOZZLE_SEQUENCE \
+ { 7.2, 1145 }, \
+ { 14.4, 871 }, \
+ { 36.0, 1393 }, \
+ { 14.4, 871 }, \
+ { 50.0, 198 }
+
+ #define MMU2_RAMMING_SEQUENCE \
+ { 1.0, 1000 }, \
+ { 1.0, 1500 }, \
+ { 2.0, 2000 }, \
+ { 1.5, 3000 }, \
+ { 2.5, 4000 }, \
+ { -15.0, 5000 }, \
+ { -14.0, 1200 }, \
+ { -6.0, 600 }, \
+ { 10.0, 700 }, \
+ { -10.0, 400 }, \
+ { -50.0, 2000 }
#endif
/**
@@ -3589,8 +4090,7 @@
* This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S.
* See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11
*/
- //#define PRUSA_MMU2_S_MODE
- #if ENABLED(PRUSA_MMU2_S_MODE)
+ #if HAS_PRUSA_MMU2S
#define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries)
#define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min)
@@ -3606,11 +4106,29 @@
#define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \
{ -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE }
+ #else
+
+ /**
+ * MMU1 Extruder Sensor
+ *
+ * Support for a Průša (or other) IR Sensor to detect filament near the extruder
+ * and make loading more reliable. Suitable for an extruder equipped with a filament
+ * sensor less than 38mm from the gears.
+ *
+ * During loading the extruder will stop when the sensor is triggered, then do a last
+ * move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
+ * If all attempts fail, a filament runout will be triggered.
+ */
+ //#define MMU_EXTRUDER_SENSOR
+ #if ENABLED(MMU_EXTRUDER_SENSOR)
+ #define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
+ #endif
+
#endif
//#define MMU2_DEBUG // Write debug info to serial output
-#endif // PRUSA_MMU2
+#endif // HAS_PRUSA_MMU2
/**
* Advanced Print Counter settings
@@ -3645,3 +4163,16 @@
// Enable Marlin dev mode which adds some special commands
//#define MARLIN_DEV_MODE
+
+/**
+ * Postmortem Debugging captures misbehavior and outputs the CPU status and backtrace to serial.
+ * When running in the debugger it will break for debugging. This is useful to help understand
+ * a crash from a remote location. Requires ~400 bytes of SRAM and 5Kb of flash.
+ */
+//#define POSTMORTEM_DEBUGGING
+
+/**
+ * Software Reset options
+ */
+//#define SOFT_RESET_VIA_SERIAL // 'KILL' and '^X' commands will soft-reset the controller
+//#define SOFT_RESET_ON_KILL // Use a digital button to soft-reset the controller after KILL
diff --git a/Marlin/Makefile b/Marlin/Makefile
index 49cb960b92fe..d09e5828f5b2 100644
--- a/Marlin/Makefile
+++ b/Marlin/Makefile
@@ -110,7 +110,7 @@ LIQUID_TWI2 ?= 0
WIRE ?= 0
# This defines if Tone is needed (i.e SPEAKER is defined in Configuration.h)
-# Disabling this (and SPEAKER) saves approximatively 350 bytes of memory.
+# Disabling this (and SPEAKER) saves approximately 350 bytes of memory.
TONE ?= 1
# This defines if U8GLIB is needed (may require RELOC_WORKAROUND)
@@ -219,7 +219,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1111)
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
# MKS GEN L
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
-# zrib V2.0 control board (Chinese knock off RAMPS replica)
+# zrib V2.0 control board (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
@@ -323,6 +323,8 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1203)
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
# abee Scoovo X9H
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
+# Rambo ThinkerV2
+else ifeq ($(HARDWARE_MOTHERBOARD),1206)
#
# Other ATmega1280, ATmega2560
@@ -991,5 +993,5 @@ clean:
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
-# Automaticaly include the dependency files created by gcc
+# Automatically include the dependency files created by gcc
-include ${patsubst %.o, %.d, ${OBJ}}
diff --git a/Marlin/Version.h b/Marlin/Version.h
index 60e068ba3521..2a5f451c7918 100644
--- a/Marlin/Version.h
+++ b/Marlin/Version.h
@@ -28,7 +28,7 @@
/**
* Marlin release version identifier
*/
-//#define SHORT_BUILD_VERSION "2.0.7.2"
+//#define SHORT_BUILD_VERSION "2.0.9.1"
/**
* Verbose version identifier which should contain a reference to the location
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
-//#define STRING_DISTRIBUTION_DATE "2020-07-09"
+//#define STRING_DISTRIBUTION_DATE "2021-06-27"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
@@ -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/MarlinFirmware/Marlin"
+//#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 "https://marlinfw.org"
+//#define WEBSITE_URL "marlinfw.org"
/**
* Set the vendor info the serial USB interface, if changable
diff --git a/Marlin/src/HAL/AVR/HAL.cpp b/Marlin/src/HAL/AVR/HAL.cpp
index 58d57c8ee54b..708583b262a6 100644
--- a/Marlin/src/HAL/AVR/HAL.cpp
+++ b/Marlin/src/HAL/AVR/HAL.cpp
@@ -24,6 +24,13 @@
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
+#ifdef USBCON
+ DefaultSerial1 MSerial0(false, Serial);
+ #ifdef BLUETOOTH
+ BTSerial btSerial(false, bluetoothSerial);
+ #endif
+#endif
+
// ------------------------
// Public Variables
// ------------------------
@@ -51,6 +58,15 @@ void HAL_init() {
#endif
}
+void HAL_reboot() {
+ #if ENABLED(USE_WATCHDOG)
+ while (1) { /* run out the watchdog */ }
+ #else
+ void (*resetFunc)() = 0; // Declare resetFunc() at address 0
+ resetFunc(); // Jump to address 0
+ #endif
+}
+
#if ENABLED(SDSUPPORT)
#include "../../sd/SdFatUtil.h"
diff --git a/Marlin/src/HAL/AVR/HAL.h b/Marlin/src/HAL/AVR/HAL.h
index 6e0afa8f10ed..a5896a0e970f 100644
--- a/Marlin/src/HAL/AVR/HAL.h
+++ b/Marlin/src/HAL/AVR/HAL.h
@@ -25,7 +25,7 @@
#include "watchdog.h"
#include "math.h"
-#ifdef IS_AT90USB
+#ifdef USBCON
#include
#else
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
@@ -81,25 +81,47 @@ typedef int8_t pin_t;
//extern uint8_t MCUSR;
// Serial ports
-#ifdef IS_AT90USB
- #define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
+#ifdef USBCON
+ #include "../../core/serial_hook.h"
+ typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
+ extern DefaultSerial1 MSerial0;
+ #ifdef BLUETOOTH
+ typedef ForwardSerial1Class< decltype(bluetoothSerial) > BTSerial;
+ extern BTSerial btSerial;
+ #endif
+
+ #define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
- #error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#endif
- #define MYSERIAL0 customizedSerial1
+ #define MYSERIAL1 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
- #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
+ #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial."
#endif
- #define MYSERIAL1 customizedSerial2
+ #define MYSERIAL2 customizedSerial2
+ #endif
+
+ #ifdef SERIAL_PORT_3
+ #if !WITHIN(SERIAL_PORT_3, -1, 3)
+ #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
+ #endif
+ #define MYSERIAL3 customizedSerial3
#endif
#endif
+#ifdef MMU2_SERIAL_PORT
+ #if !WITHIN(MMU2_SERIAL_PORT, -1, 3)
+ #error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
+ #endif
+ #define MMU2_SERIAL mmuSerial
+#endif
+
#ifdef LCD_SERIAL_PORT
#if !WITHIN(LCD_SERIAL_PORT, -1, 3)
- #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#endif
#define LCD_SERIAL lcdSerial
#if HAS_DGUS_LCD
@@ -120,14 +142,18 @@ void HAL_init();
inline void HAL_clear_reset_source() { MCUSR = 0; }
inline uint8_t HAL_get_reset_source() { return MCUSR; }
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot();
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
-extern "C" {
- int freeMemory();
-}
-#pragma GCC diagnostic pop
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
+extern "C" int freeMemory();
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
// ADC
#ifdef DIDR2
@@ -160,7 +186,7 @@ inline void HAL_adc_init() {
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
-#define HAL_SENSITIVE_PINS 0, 1
+#define HAL_SENSITIVE_PINS 0, 1,
#ifdef __AVR_AT90USB1286__
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)
diff --git a/Marlin/src/HAL/AVR/HAL_SPI.cpp b/Marlin/src/HAL/AVR/HAL_SPI.cpp
index 31e589746cf2..1a1b98b3dd2a 100644
--- a/Marlin/src/HAL/AVR/HAL_SPI.cpp
+++ b/Marlin/src/HAL/AVR/HAL_SPI.cpp
@@ -34,17 +34,17 @@
#include "../../inc/MarlinConfig.h"
void spiBegin() {
- OUT_WRITE(SS_PIN, HIGH);
- SET_OUTPUT(SCK_PIN);
- SET_INPUT(MISO_PIN);
- SET_OUTPUT(MOSI_PIN);
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ SET_OUTPUT(SD_SCK_PIN);
+ SET_INPUT(SD_MISO_PIN);
+ SET_OUTPUT(SD_MOSI_PIN);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
- //SET_OUTPUT(SS_PIN);
+ //SET_OUTPUT(SD_SS_PIN);
// set SS high - may be chip select for another SPI device
//#if SET_SPI_SS_HIGH
- //WRITE(SS_PIN, HIGH);
+ //WRITE(SD_SS_PIN, HIGH);
//#endif
// set a default rate
spiInit(1);
@@ -88,7 +88,7 @@ void spiBegin() {
}
/** SPI read data */
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
SPDR = 0xFF;
for (uint16_t i = 0; i < nbyte; i++) {
@@ -107,7 +107,7 @@ void spiBegin() {
}
/** SPI send block */
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
SPDR = token;
for (uint16_t i = 0; i < 512; i += 2) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
@@ -195,19 +195,19 @@ void spiBegin() {
// no interrupts during byte receive - about 8µs
cli();
// output pin high - like sending 0xFF
- WRITE(MOSI_PIN, HIGH);
+ WRITE(SD_MOSI_PIN, HIGH);
LOOP_L_N(i, 8) {
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
nop; // adjust so SCK is nice
nop;
data <<= 1;
- if (READ(MISO_PIN)) data |= 1;
+ if (READ(SD_MISO_PIN)) data |= 1;
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
}
sei();
@@ -215,7 +215,7 @@ void spiBegin() {
}
// Soft SPI read data
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
buf[i] = spiRec();
}
@@ -225,10 +225,10 @@ void spiBegin() {
// no interrupts during byte send - about 8µs
cli();
LOOP_L_N(i, 8) {
- WRITE(SCK_PIN, LOW);
- WRITE(MOSI_PIN, data & 0x80);
+ WRITE(SD_SCK_PIN, LOW);
+ WRITE(SD_MOSI_PIN, data & 0x80);
data <<= 1;
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
}
nop; // hold SCK high for a few ns
@@ -236,13 +236,13 @@ void spiBegin() {
nop;
nop;
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
sei();
}
// Soft SPI send block
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
spiSend(token);
for (uint16_t i = 0; i < 512; i++)
spiSend(buf[i]);
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp
index 8feac32aa74c..cd8bf5e6903b 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.cpp
+++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp
@@ -38,7 +38,7 @@
#include "../../inc/MarlinConfig.h"
-#if !IS_AT90USB && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
+#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
#include "MarlinSerial.h"
#include "../../MarlinCore.h"
@@ -556,161 +556,6 @@ void MarlinSerial::flushTX() {
}
}
-/**
- * Imports from print.h
- */
-
-template
-void MarlinSerial::print(char c, int base) {
- print((long)c, base);
-}
-
-template
-void MarlinSerial::print(unsigned char b, int base) {
- print((unsigned long)b, base);
-}
-
-template
-void MarlinSerial::print(int n, int base) {
- print((long)n, base);
-}
-
-template
-void MarlinSerial::print(unsigned int n, int base) {
- print((unsigned long)n, base);
-}
-
-template
-void MarlinSerial::print(long n, int base) {
- if (base == 0) write(n);
- else if (base == 10) {
- if (n < 0) { print('-'); n = -n; }
- printNumber(n, 10);
- }
- else
- printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(double n, int digits) {
- printFloat(n, digits);
-}
-
-template
-void MarlinSerial::println() {
- print('\r');
- print('\n');
-}
-
-template
-void MarlinSerial::println(const String& s) {
- print(s);
- println();
-}
-
-template
-void MarlinSerial::println(const char c[]) {
- print(c);
- println();
-}
-
-template
-void MarlinSerial::println(char c, int base) {
- print(c, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned char b, int base) {
- print(b, base);
- println();
-}
-
-template
-void MarlinSerial::println(int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(double n, int digits) {
- print(n, digits);
- println();
-}
-
-// Private Methods
-
-template
-void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
- if (n) {
- unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
- int8_t i = 0;
- while (n) {
- buf[i++] = n % base;
- n /= base;
- }
- while (i--)
- print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
- }
- else
- print('0');
-}
-
-template
-void MarlinSerial::printFloat(double number, uint8_t digits) {
- // Handle negative numbers
- if (number < 0.0) {
- print('-');
- number = -number;
- }
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- LOOP_L_N(i, digits) rounding *= 0.1;
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits) {
- print('.');
- // Extract digits from the remainder one at a time
- while (digits--) {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
- }
-}
-
// Hookup ISR handlers
ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) {
MarlinSerial>::store_rxd_char();
@@ -720,11 +565,9 @@ ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
MarlinSerial>::_tx_udr_empty_irq();
}
-// Preinstantiate
-template class MarlinSerial>;
-
-// Instantiate
-MarlinSerial> customizedSerial1;
+// Because of the template definition above, it's required to instantiate the template to have all methods generated
+template class MarlinSerial< MarlinSerialCfg >;
+MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser);
#ifdef SERIAL_PORT_2
@@ -737,13 +580,26 @@ MarlinSerial> customizedSerial1;
MarlinSerial>::_tx_udr_empty_irq();
}
- // Preinstantiate
- template class MarlinSerial>;
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT2 customizedSerial2(MSerialT2::HasEmergencyParser);
- // Instantiate
- MarlinSerial> customizedSerial2;
+#endif // SERIAL_PORT_2
-#endif
+#ifdef SERIAL_PORT_3
+
+ // Hookup ISR handlers
+ ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _RX_vect)) {
+ MarlinSerial>::store_rxd_char();
+ }
+
+ ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _UDRE_vect)) {
+ MarlinSerial>::_tx_udr_empty_irq();
+ }
+
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT3 customizedSerial3(MSerialT3::HasEmergencyParser);
+
+#endif // SERIAL_PORT_3
#ifdef MMU2_SERIAL_PORT
@@ -755,13 +611,10 @@ MarlinSerial> customizedSerial1;
MarlinSerial>::_tx_udr_empty_irq();
}
- // Preinstantiate
- template class MarlinSerial>;
-
- // Instantiate
- MarlinSerial> mmuSerial;
+ template class MarlinSerial< MMU2SerialCfg >;
+ MSerialMMU2 mmuSerial(MSerialMMU2::HasEmergencyParser);
-#endif
+#endif // MMU2_SERIAL_PORT
#ifdef LCD_SERIAL_PORT
@@ -773,11 +626,8 @@ MarlinSerial> customizedSerial1;
MarlinSerial>::_tx_udr_empty_irq();
}
- // Preinstantiate
- template class MarlinSerial>;
-
- // Instantiate
- MarlinSerial> lcdSerial;
+ template class MarlinSerial< LCDSerialCfg >;
+ MSerialLCD lcdSerial(MSerialLCD::HasEmergencyParser);
#if HAS_DGUS_LCD
template
@@ -790,13 +640,13 @@ MarlinSerial> customizedSerial1;
}
#endif
-#endif
+#endif // LCD_SERIAL_PORT
-#endif // !IS_AT90USB && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
+#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
// For AT90USB targets use the UART for BT interfacing
-#if BOTH(IS_AT90USB, BLUETOOTH)
- HardwareSerial bluetoothSerial;
+#if defined(USBCON) && ENABLED(BLUETOOTH)
+ MSerialBT bluetoothSerial(false);
#endif
#endif // __AVR__
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h
index 3850e2a47e2a..0565c7b9db9e 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.h
+++ b/Marlin/src/HAL/AVR/MarlinSerial.h
@@ -34,6 +34,7 @@
#include
#include "../../inc/MarlinConfigPre.h"
+#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
@@ -135,10 +136,6 @@
UART_DECL(3);
#endif
- #define DEC 10
- #define HEX 16
- #define OCT 8
- #define BIN 2
#define BYTE 0
// Templated type selector
@@ -202,60 +199,30 @@
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
- public:
-
+ public:
FORCE_INLINE static void store_rxd_char();
FORCE_INLINE static void _tx_udr_empty_irq();
- public:
- MarlinSerial() {};
- static void begin(const long);
- static void end();
- static int peek();
- static int read();
- static void flush();
- static ring_buffer_pos_t available();
- static void write(const uint8_t c);
- static void flushTX();
- #if HAS_DGUS_LCD
- static ring_buffer_pos_t get_tx_buffer_free();
- #endif
-
- static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
-
- FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
- FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
- FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
- FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
-
- FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
- FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
- FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
- FORCE_INLINE static void print(const char* str) { write(str); }
-
- static void print(char, int = BYTE);
- static void print(unsigned char, int = BYTE);
- static void print(int, int = DEC);
- static void print(unsigned int, int = DEC);
- static void print(long, int = DEC);
- static void print(unsigned long, int = DEC);
- static void print(double, int = 2);
-
- static void println(const String& s);
- static void println(const char[]);
- static void println(char, int = BYTE);
- static void println(unsigned char, int = BYTE);
- static void println(int, int = DEC);
- static void println(unsigned int, int = DEC);
- static void println(long, int = DEC);
- static void println(unsigned long, int = DEC);
- static void println(double, int = 2);
- static void println();
- operator bool() { return true; }
-
- private:
- static void printNumber(unsigned long, const uint8_t);
- static void printFloat(double, uint8_t);
+ public:
+ static void begin(const long);
+ static void end();
+ static int peek();
+ static int read();
+ static void flush();
+ static ring_buffer_pos_t available();
+ static void write(const uint8_t c);
+ static void flushTX();
+ #if HAS_DGUS_LCD
+ static ring_buffer_pos_t get_tx_buffer_free();
+ #endif
+
+ enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
+ static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
+
+ FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
+ FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
+ FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
+ FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
};
template
@@ -270,12 +237,18 @@
static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
- extern MarlinSerial> customizedSerial1;
- #ifdef SERIAL_PORT_2
+ typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT1;
+ extern MSerialT1 customizedSerial1;
- extern MarlinSerial> customizedSerial2;
+ #ifdef SERIAL_PORT_2
+ typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT2;
+ extern MSerialT2 customizedSerial2;
+ #endif
+ #ifdef SERIAL_PORT_3
+ typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT3;
+ extern MSerialT3 customizedSerial3;
#endif
#endif // !USBCON
@@ -284,49 +257,41 @@
template
struct MMU2SerialCfg {
static constexpr int PORT = serial;
+ static constexpr unsigned int RX_SIZE = 32;
+ static constexpr unsigned int TX_SIZE = 32;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
- static constexpr unsigned int RX_SIZE = 32;
- static constexpr unsigned int TX_SIZE = 32;
static constexpr bool RX_OVERRUNS = false;
};
- extern MarlinSerial> mmuSerial;
+ typedef Serial1Class< MarlinSerial< MMU2SerialCfg > > MSerialMMU2;
+ extern MSerialMMU2 mmuSerial;
#endif
#ifdef LCD_SERIAL_PORT
template
struct LCDSerialCfg {
- static constexpr int PORT = serial;
- static constexpr bool XONOFF = false;
- static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
- static constexpr bool DROPPED_RX = false;
- static constexpr bool RX_FRAMING_ERRORS = false;
- static constexpr bool MAX_RX_QUEUED = false;
- #if HAS_DGUS_LCD
- static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE;
- static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE;
- static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
- #elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
- static constexpr unsigned int RX_SIZE = 64;
- static constexpr unsigned int TX_SIZE = 128;
- static constexpr bool RX_OVERRUNS = false;
- #else
- static constexpr unsigned int RX_SIZE = 64;
- static constexpr unsigned int TX_SIZE = 128;
- static constexpr bool RX_OVERRUNS = false
- #endif
+ static constexpr int PORT = serial;
+ static constexpr unsigned int RX_SIZE = TERN(HAS_DGUS_LCD, DGUS_RX_BUFFER_SIZE, 64);
+ static constexpr unsigned int TX_SIZE = TERN(HAS_DGUS_LCD, DGUS_TX_BUFFER_SIZE, 128);
+ static constexpr bool XONOFF = false;
+ static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
+ static constexpr bool DROPPED_RX = false;
+ static constexpr bool RX_FRAMING_ERRORS = false;
+ static constexpr bool MAX_RX_QUEUED = false;
+ static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS);
};
- extern MarlinSerial> lcdSerial;
-
+ typedef Serial1Class< MarlinSerial< LCDSerialCfg > > MSerialLCD;
+ extern MSerialLCD lcdSerial;
#endif
// Use the UART for Bluetooth in AT90USB configurations
-#if BOTH(IS_AT90USB, BLUETOOTH)
- extern HardwareSerial bluetoothSerial;
+#if defined(USBCON) && ENABLED(BLUETOOTH)
+ typedef Serial1Class MSerialBT;
+ extern MSerialBT bluetoothSerial;
#endif
diff --git a/Marlin/src/HAL/AVR/eeprom.cpp b/Marlin/src/HAL/AVR/eeprom.cpp
index c7906985eb60..8d084dec7fdf 100644
--- a/Marlin/src/HAL/AVR/eeprom.cpp
+++ b/Marlin/src/HAL/AVR/eeprom.cpp
@@ -40,13 +40,13 @@ bool PersistentStore::access_start() { return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
- // EEPROM has only ~100,000 write cycles,
- // so only write bytes that have changed!
- if (v != eeprom_read_byte(p)) {
+ if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
+ if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
@@ -59,7 +59,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/AVR/endstop_interrupts.h b/Marlin/src/HAL/AVR/endstop_interrupts.h
index ae9a605accce..50f29c3356ce 100644
--- a/Marlin/src/HAL/AVR/endstop_interrupts.h
+++ b/Marlin/src/HAL/AVR/endstop_interrupts.h
@@ -124,7 +124,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X_MAX_PIN);
#endif
#endif
@@ -132,7 +132,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X_MIN_PIN);
#endif
#endif
@@ -140,7 +140,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y_MAX_PIN);
#endif
#endif
@@ -148,7 +148,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y_MIN_PIN);
#endif
#endif
@@ -156,7 +156,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MAX_PIN);
#endif
#endif
@@ -164,15 +164,60 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MIN_PIN);
#endif
#endif
+ #if HAS_I_MAX
+ #if (digitalPinToInterrupt(I_MAX_PIN) != NOT_AN_INTERRUPT)
+ _ATTACH(I_MAX_PIN);
+ #else
+ static_assert(digitalPinHasPCICR(I_MAX_PIN), "I_MAX_PIN is not interrupt-capable");
+ pciSetup(I_MAX_PIN);
+ #endif
+ #elif HAS_I_MIN
+ #if (digitalPinToInterrupt(I_MIN_PIN) != NOT_AN_INTERRUPT)
+ _ATTACH(I_MIN_PIN);
+ #else
+ static_assert(digitalPinHasPCICR(I_MIN_PIN), "I_MIN_PIN is not interrupt-capable");
+ pciSetup(I_MIN_PIN);
+ #endif
+ #endif
+ #if HAS_J_MAX
+ #if (digitalPinToInterrupt(J_MAX_PIN) != NOT_AN_INTERRUPT)
+ _ATTACH(J_MAX_PIN);
+ #else
+ static_assert(digitalPinHasPCICR(J_MAX_PIN), "J_MAX_PIN is not interrupt-capable");
+ pciSetup(J_MAX_PIN);
+ #endif
+ #elif HAS_J_MIN
+ #if (digitalPinToInterrupt(J_MIN_PIN) != NOT_AN_INTERRUPT)
+ _ATTACH(J_MIN_PIN);
+ #else
+ static_assert(digitalPinHasPCICR(J_MIN_PIN), "J_MIN_PIN is not interrupt-capable");
+ pciSetup(J_MIN_PIN);
+ #endif
+ #endif
+ #if HAS_K_MAX
+ #if (digitalPinToInterrupt(K_MAX_PIN) != NOT_AN_INTERRUPT)
+ _ATTACH(K_MAX_PIN);
+ #else
+ static_assert(digitalPinHasPCICR(K_MAX_PIN), "K_MAX_PIN is not interrupt-capable");
+ pciSetup(K_MAX_PIN);
+ #endif
+ #elif HAS_K_MIN
+ #if (digitalPinToInterrupt(K_MIN_PIN) != NOT_AN_INTERRUPT)
+ _ATTACH(K_MIN_PIN);
+ #else
+ static_assert(digitalPinHasPCICR(K_MIN_PIN), "K_MIN_PIN is not interrupt-capable");
+ pciSetup(K_MIN_PIN);
+ #endif
+ #endif
#if HAS_X2_MAX
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X2_MAX_PIN);
#endif
#endif
@@ -180,7 +225,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X2_MIN_PIN);
#endif
#endif
@@ -188,7 +233,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y2_MAX_PIN);
#endif
#endif
@@ -196,7 +241,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y2_MIN_PIN);
#endif
#endif
@@ -204,7 +249,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z2_MAX_PIN);
#endif
#endif
@@ -212,7 +257,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z2_MIN_PIN);
#endif
#endif
@@ -220,7 +265,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z3_MAX_PIN);
#endif
#endif
@@ -228,7 +273,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z3_MIN_PIN);
#endif
#endif
@@ -236,7 +281,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MAX_PIN);
#else
- static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z4_MAX_PIN);
#endif
#endif
@@ -244,7 +289,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MIN_PIN);
#else
- static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z4_MIN_PIN);
#endif
#endif
@@ -252,10 +297,9 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PROBE_PIN);
#else
- static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
+ static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
-
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
}
diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp
index b51d7f97686a..70132e71ee54 100644
--- a/Marlin/src/HAL/AVR/fastio.cpp
+++ b/Marlin/src/HAL/AVR/fastio.cpp
@@ -241,7 +241,7 @@ uint8_t extDigitalRead(const int8_t pin) {
*
* DC values -1.0 to 1.0. Negative duty cycle inverts the pulse.
*/
-uint16_t set_pwm_frequency_hz(const float &hz, const float dca, const float dcb, const float dcc) {
+uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb, const float dcc) {
float count = 0;
if (hz > 0 && (dca || dcb || dcc)) {
count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq.
diff --git a/Marlin/src/HAL/AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h
index dd0163466110..f77d4f666c7d 100644
--- a/Marlin/src/HAL/AVR/fastio.h
+++ b/Marlin/src/HAL/AVR/fastio.h
@@ -284,8 +284,8 @@ enum ClockSource2 : char {
* PWM availability macros
*/
-// Determine which harware PWMs are already in use
-#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN)
+// Determine which hardware PWMs are already in use
+#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN || P == COOLER_AUTO_FAN_PIN)
#if PIN_EXISTS(CONTROLLER_FAN)
#define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN)
#else
diff --git a/Marlin/src/HAL/AVR/inc/SanityCheck.h b/Marlin/src/HAL/AVR/inc/SanityCheck.h
index 731cf9286582..51ba247953b4 100644
--- a/Marlin/src/HAL/AVR/inc/SanityCheck.h
+++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h
@@ -56,3 +56,10 @@
#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS)
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
#endif
+
+/**
+ * Postmortem debugging
+ */
+#if ENABLED(POSTMORTEM_DEBUGGING)
+ #error "POSTMORTEM_DEBUGGING is not supported on AVR boards."
+#endif
diff --git a/Marlin/src/HAL/AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h
index dac6b1b150bd..55fddb05b862 100644
--- a/Marlin/src/HAL/AVR/pinsDebug.h
+++ b/Marlin/src/HAL/AVR/pinsDebug.h
@@ -38,7 +38,7 @@
// portModeRegister takes a different argument
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
- #define digitalPinToPort_DEBUG(p) digitalPinToPort_Teensy(p)
+ #define digitalPinToPort_DEBUG(p) digitalPinToPort(p)
#define GET_PINMODE(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin))
#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70
@@ -235,8 +235,8 @@ static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin");
inline void com_print(const uint8_t N, const uint8_t Z) {
const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
- SERIAL_ECHOPGM(" COM");
- SERIAL_CHAR('0' + N, Z);
+ SERIAL_ECHOPAIR(" COM", AS_CHAR('0' + N));
+ SERIAL_CHAR(Z);
SERIAL_ECHOPAIR(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
}
@@ -247,8 +247,8 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
- SERIAL_ECHOPGM(" TIMER");
- SERIAL_CHAR(T + '0', L);
+ SERIAL_ECHOPAIR(" TIMER", AS_CHAR(T + '0'));
+ SERIAL_CHAR(L);
SERIAL_ECHO_SP(3);
if (N == 3) {
@@ -262,19 +262,11 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
SERIAL_ECHOPAIR(" WGM: ", WGM);
com_print(T,L);
SERIAL_ECHOPAIR(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
-
- SERIAL_ECHOPGM(" TCCR");
- SERIAL_CHAR(T + '0');
- SERIAL_ECHOPAIR("A: ", *TCCRA);
-
- SERIAL_ECHOPGM(" TCCR");
- SERIAL_CHAR(T + '0');
- SERIAL_ECHOPAIR("B: ", *TCCRB);
+ SERIAL_ECHOPAIR(" TCCR", AS_CHAR(T + '0'), "A: ", *TCCRA);
+ SERIAL_ECHOPAIR(" TCCR", AS_CHAR(T + '0'), "B: ", *TCCRB);
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
- SERIAL_ECHOPGM(" TIMSK");
- SERIAL_CHAR(T + '0');
- SERIAL_ECHOPAIR(": ", *TMSK);
+ SERIAL_ECHOPAIR(" TIMSK", AS_CHAR(T + '0'), ": ", *TMSK);
const uint8_t OCIE = L - 'A' + 1;
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
diff --git a/Marlin/src/HAL/AVR/spi_pins.h b/Marlin/src/HAL/AVR/spi_pins.h
index f3fa78e2bfaf..831972938a7b 100644
--- a/Marlin/src/HAL/AVR/spi_pins.h
+++ b/Marlin/src/HAL/AVR/spi_pins.h
@@ -51,15 +51,15 @@
#define AVR_SS_PIN 16
#endif
-#ifndef SCK_PIN
- #define SCK_PIN AVR_SCK_PIN
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN AVR_SCK_PIN
#endif
-#ifndef MISO_PIN
- #define MISO_PIN AVR_MISO_PIN
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN AVR_MISO_PIN
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN AVR_MOSI_PIN
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN AVR_MOSI_PIN
#endif
-#ifndef SS_PIN
- #define SS_PIN AVR_SS_PIN
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN AVR_SS_PIN
#endif
diff --git a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
index cb95a48cccec..9d928e7af3b0 100644
--- a/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
+++ b/Marlin/src/HAL/AVR/u8g_com_HAL_AVR_sw_spi.cpp
@@ -62,7 +62,7 @@
#include "../shared/Marduino.h"
#include "../shared/Delay.h"
-#include
+#include
uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
volatile uint8_t *u8g_outData, *u8g_outClock;
diff --git a/Marlin/src/HAL/DUE/DebugMonitor.cpp b/Marlin/src/HAL/DUE/DebugMonitor.cpp
deleted file mode 100644
index 79759151d891..000000000000
--- a/Marlin/src/HAL/DUE/DebugMonitor.cpp
+++ /dev/null
@@ -1,342 +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 .
- *
- */
-#ifdef ARDUINO_ARCH_SAM
-
-#include "../../core/macros.h"
-#include "../../core/serial.h"
-
-#include "../shared/backtrace/unwinder.h"
-#include "../shared/backtrace/unwmemaccess.h"
-
-#include
-
-// Debug monitor that dumps to the Programming port all status when
-// an exception or WDT timeout happens - And then resets the board
-
-// All the Monitor routines must run with interrupts disabled and
-// under an ISR execution context. That is why we cannot reuse the
-// Serial interrupt routines or any C runtime, as we don't know the
-// state we are when running them
-
-// A SW memory barrier, to ensure GCC does not overoptimize loops
-#define sw_barrier() __asm__ volatile("": : :"memory");
-
-// (re)initialize UART0 as a monitor output to 250000,n,8,1
-static void TXBegin() {
-
- // Disable UART interrupt in NVIC
- NVIC_DisableIRQ( UART_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();
-
- // Disable clock
- pmc_disable_periph_clk( ID_UART );
-
- // Configure PMC
- pmc_enable_periph_clk( ID_UART );
-
- // Disable PDC channel
- UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
-
- // Reset and disable receiver and transmitter
- UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
-
- // Configure mode: 8bit, No parity, 1 bit stop
- UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
-
- // Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
- UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
-
- // Enable receiver and transmitter
- UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
-}
-
-// Send character through UART with no interrupts
-static void TX(char c) {
- while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
- UART->UART_THR = c;
-}
-
-// Send String through UART
-static void TX(const char* s) {
- while (*s) TX(*s++);
-}
-
-static void TXDigit(uint32_t d) {
- if (d < 10) TX((char)(d+'0'));
- else if (d < 16) TX((char)(d+'A'-10));
- else TX('?');
-}
-
-// Send Hex number thru UART
-static void TXHex(uint32_t v) {
- TX("0x");
- for (uint8_t i = 0; i < 8; i++, v <<= 4)
- TXDigit((v >> 28) & 0xF);
-}
-
-// Send Decimal number thru UART
-static void TXDec(uint32_t v) {
- if (!v) {
- TX('0');
- return;
- }
-
- char nbrs[14];
- char *p = &nbrs[0];
- while (v != 0) {
- *p++ = '0' + (v % 10);
- v /= 10;
- }
- do {
- p--;
- TX(*p);
- } while (p != &nbrs[0]);
-}
-
-// Dump a backtrace entry
-static bool UnwReportOut(void* ctx, const UnwReport* bte) {
- int* p = (int*)ctx;
-
- (*p)++;
- TX('#'); TXDec(*p); TX(" : ");
- TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
- TX('+'); TXDec(bte->address - bte->function);
- TX(" PC:");TXHex(bte->address); TX('\n');
- return true;
-}
-
-#ifdef UNW_DEBUG
- void UnwPrintf(const char* format, ...) {
- char dest[256];
- va_list argptr;
- va_start(argptr, format);
- vsprintf(dest, format, argptr);
- va_end(argptr);
- TX(&dest[0]);
- }
-#endif
-
-/* Table of function pointers for passing to the unwinder */
-static const UnwindCallbacks UnwCallbacks = {
- UnwReportOut,
- UnwReadW,
- UnwReadH,
- UnwReadB
- #ifdef UNW_DEBUG
- , UnwPrintf
- #endif
-};
-
-/**
- * HardFaultHandler_C:
- * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
- * as the parameter. We can then read the values from the stack and place them
- * into local variables for ease of reading.
- * We then read the various Fault Status and Address Registers to help decode
- * cause of the fault.
- * The function ends with a BKPT instruction to force control back into the debugger
- */
-extern "C"
-void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
-
- static const char* causestr[] = {
- "NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
- };
-
- UnwindFrame btf;
-
- // Dump report to the Programming port (interrupts are DISABLED)
- TXBegin();
- TX("\n\n## Software Fault detected ##\n");
- TX("Cause: "); TX(causestr[cause]); TX('\n');
-
- TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
- TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
- TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
- TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
- TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
- TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
- TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
- TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
-
- // Configurable Fault Status Register
- // Consists of MMSR, BFSR and UFSR
- TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
-
- // Hard Fault Status Register
- TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
-
- // Debug Fault Status Register
- TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
-
- // Auxiliary Fault Status Register
- TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
-
- // Read the Fault Address Registers. These may not contain valid values.
- // Check BFARVALID/MMARVALID to see if they are valid values
- // MemManage Fault Address Register
- TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
-
- // Bus Fault Address Register
- TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
-
- TX("ExcLR: "); TXHex(lr); TX('\n');
- TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
-
- btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
- btf.fp = btf.sp;
- btf.lr = ((unsigned long)sp[5]);
- btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
-
- // Perform a backtrace
- TX("\nBacktrace:\n\n");
- int ctr = 0;
- UnwindStart(&btf, &UnwCallbacks, &ctr);
-
- // Disable all NVIC interrupts
- NVIC->ICER[0] = 0xFFFFFFFF;
- NVIC->ICER[1] = 0xFFFFFFFF;
-
- // Relocate VTOR table to default position
- SCB->VTOR = 0;
-
- // Disable USB
- otg_disable();
-
- // Restart watchdog
- WDT_Restart(WDT);
-
- // Reset controller
- NVIC_SystemReset();
- for (;;) WDT_Restart(WDT);
-}
-
-__attribute__((naked)) void NMI_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#0")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void HardFault_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#1")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void MemManage_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#2")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void BusFault_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#3")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void UsageFault_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#4")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void DebugMon_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#5")
- A("b HardFault_HandlerC")
- );
-}
-
-/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
-__attribute__((naked)) void WDT_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#6")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void RSTC_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#7")
- A("b HardFault_HandlerC")
- );
-}
-
-#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/HAL.cpp b/Marlin/src/HAL/DUE/HAL.cpp
index 6ce85a4643bb..a3985652e71d 100644
--- a/Marlin/src/HAL/DUE/HAL.cpp
+++ b/Marlin/src/HAL/DUE/HAL.cpp
@@ -40,6 +40,8 @@ uint16_t HAL_adc_result;
// Public functions
// ------------------------
+TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
+
// HAL initialization task
void HAL_init() {
// Initialize the USB stack
@@ -47,6 +49,7 @@ void HAL_init() {
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
usb_task_init();
+ TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
// HAL idle task
@@ -74,6 +77,8 @@ uint8_t HAL_get_reset_source() {
}
}
+void HAL_reboot() { rstc_start_software_reset(RSTC); }
+
void _delay_ms(const int delay_ms) {
// Todo: port for Due?
delay(delay_ms);
@@ -102,4 +107,18 @@ uint16_t HAL_adc_get_result() {
return HAL_adc_result;
}
+// Forward the default serial ports
+#if USING_HW_SERIAL0
+ DefaultSerial1 MSerial0(false, Serial);
+#endif
+#if USING_HW_SERIAL1
+ DefaultSerial2 MSerial1(false, Serial1);
+#endif
+#if USING_HW_SERIAL2
+ DefaultSerial3 MSerial2(false, Serial2);
+#endif
+#if USING_HW_SERIAL3
+ DefaultSerial4 MSerial3(false, Serial3);
+#endif
+
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h
index 88ace5957535..92e26bcf4362 100644
--- a/Marlin/src/HAL/DUE/HAL.h
+++ b/Marlin/src/HAL/DUE/HAL.h
@@ -36,36 +36,61 @@
#include
-#define _MSERIAL(X) Serial##X
+#include "../../core/serial_hook.h"
+
+typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
+typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
+typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
+typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
+extern DefaultSerial1 MSerial0;
+extern DefaultSerial2 MSerial1;
+extern DefaultSerial3 MSerial2;
+extern DefaultSerial4 MSerial3;
+
+#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
-#define Serial0 Serial
-// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
- #define MYSERIAL0 customizedSerial1
+ #define MYSERIAL1 customizedSerial1
#elif WITHIN(SERIAL_PORT, 0, 3)
- #define MYSERIAL0 MSERIAL(SERIAL_PORT)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
- #error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "The required SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
- #define MYSERIAL1 customizedSerial2
+ #define MYSERIAL2 customizedSerial2
#elif WITHIN(SERIAL_PORT_2, 0, 3)
- #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
+ #define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
- #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
+ #error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial."
+ #endif
+#endif
+
+#ifdef SERIAL_PORT_3
+ #if SERIAL_PORT_3 == -1 || ENABLED(EMERGENCY_PARSER)
+ #define MYSERIAL3 customizedSerial3
+ #elif WITHIN(SERIAL_PORT_3, 0, 3)
+ #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
+ #else
+ #error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
+ #endif
+#endif
+
+#ifdef MMU2_SERIAL_PORT
+ #if WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from 0 to 3."
#endif
#endif
#ifdef LCD_SERIAL_PORT
- #if LCD_SERIAL_PORT == -1
- #define LCD_SERIAL lcdSerial
- #elif WITHIN(LCD_SERIAL_PORT, 0, 3)
+ #if WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from 0 to 3."
#endif
#endif
@@ -75,16 +100,6 @@
// On AVR this is in math.h?
#define square(x) ((x)*(x))
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*((void**)(addr)))
-#undef pgm_read_word
-#define pgm_read_word(addr) (*((uint16_t*)(addr)))
-
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS
@@ -105,7 +120,7 @@ void sei(); // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot();
//
// ADC
@@ -153,10 +168,16 @@ void HAL_init();
//
void _delay_ms(const int delay);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/Marlin/src/HAL/DUE/HAL_MinSerial.cpp b/Marlin/src/HAL/DUE/HAL_MinSerial.cpp
new file mode 100644
index 000000000000..93c4ed67d63c
--- /dev/null
+++ b/Marlin/src/HAL/DUE/HAL_MinSerial.cpp
@@ -0,0 +1,91 @@
+/**
+ * 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 .
+ *
+ */
+#ifdef ARDUINO_ARCH_SAM
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+
+#include "../shared/HAL_MinSerial.h"
+
+#include
+
+static void TXBegin() {
+ // Disable UART interrupt in NVIC
+ NVIC_DisableIRQ( UART_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();
+
+ // Disable clock
+ pmc_disable_periph_clk( ID_UART );
+
+ // Configure PMC
+ pmc_enable_periph_clk( ID_UART );
+
+ // Disable PDC channel
+ UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
+
+ // Reset and disable receiver and transmitter
+ UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
+
+ // Configure mode: 8bit, No parity, 1 bit stop
+ UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
+
+ // Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
+ UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
+
+ // Enable receiver and transmitter
+ UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
+}
+
+// A SW memory barrier, to ensure GCC does not overoptimize loops
+#define sw_barrier() __asm__ volatile("": : :"memory");
+static void TX(char c) {
+ while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
+ UART->UART_THR = c;
+}
+
+void install_min_serial() {
+ HAL_min_serial_init = &TXBegin;
+ 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 // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/HAL_SPI.cpp b/Marlin/src/HAL/DUE/HAL_SPI.cpp
index 0451d8bcc4ff..d3d76e94e5dd 100644
--- a/Marlin/src/HAL/DUE/HAL_SPI.cpp
+++ b/Marlin/src/HAL/DUE/HAL_SPI.cpp
@@ -56,8 +56,8 @@
#pragma GCC optimize (3)
typedef uint8_t (*pfnSpiTransfer)(uint8_t b);
- typedef void (*pfnSpiRxBlock)(uint8_t* buf, uint32_t nbyte);
- typedef void (*pfnSpiTxBlock)(const uint8_t* buf, uint32_t nbyte);
+ typedef void (*pfnSpiRxBlock)(uint8_t *buf, uint32_t nbyte);
+ typedef void (*pfnSpiTxBlock)(const uint8_t *buf, uint32_t nbyte);
/* ---------------- Macros to be able to access definitions from asm */
#define _PORT(IO) DIO ## IO ## _WPORT
@@ -69,10 +69,10 @@
// run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
static uint8_t spiTransferTx0(uint8_t bout) { // using Mode 0
- uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
- uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
+ uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
uint32_t idx = 0;
/* Negate bout, as the assembler requires a negated value */
@@ -154,9 +154,9 @@
static uint8_t spiTransferRx0(uint8_t) { // using Mode 0
uint32_t bin = 0;
uint32_t work = 0;
- uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
/* The software SPI routine */
__asm__ __volatile__(
@@ -225,36 +225,36 @@
static uint8_t spiTransfer1(uint8_t b) { // using Mode 0
int bits = 8;
do {
- WRITE(MOSI_PIN, b & 0x80);
+ WRITE(SD_MOSI_PIN, b & 0x80);
b <<= 1; // little setup time
- WRITE(SCK_PIN, HIGH);
+ WRITE(SD_SCK_PIN, HIGH);
DELAY_NS(125); // 10 cycles @ 84mhz
- b |= (READ(MISO_PIN) != 0);
+ b |= (READ(SD_MISO_PIN) != 0);
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_SCK_PIN, LOW);
DELAY_NS(125); // 10 cycles @ 84mhz
} while (--bits);
return b;
}
// all the others
- static uint32_t spiDelayCyclesX4 = (F_CPU) / 1000000; // 4µs => 125khz
+ static uint16_t spiDelayNS = 4000; // 4000ns => 125khz
static uint8_t spiTransferX(uint8_t b) { // using Mode 0
int bits = 8;
do {
- WRITE(MOSI_PIN, b & 0x80);
+ WRITE(SD_MOSI_PIN, b & 0x80);
b <<= 1; // little setup time
- WRITE(SCK_PIN, HIGH);
- __delay_4cycles(spiDelayCyclesX4);
+ WRITE(SD_SCK_PIN, HIGH);
+ DELAY_NS(spiDelayNS);
- b |= (READ(MISO_PIN) != 0);
+ b |= (READ(SD_MISO_PIN) != 0);
- WRITE(SCK_PIN, LOW);
- __delay_4cycles(spiDelayCyclesX4);
+ WRITE(SD_SCK_PIN, LOW);
+ DELAY_NS(spiDelayNS);
} while (--bits);
return b;
}
@@ -270,11 +270,11 @@
static pfnSpiTransfer spiTransferTx = (pfnSpiTransfer)spiTransferX;
// Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
- static void spiTxBlock0(const uint8_t* ptr, uint32_t todo) {
- uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
- uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ static void spiTxBlock0(const uint8_t *ptr, uint32_t todo) {
+ uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
+ uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
uint32_t work = 0;
uint32_t txval = 0;
@@ -349,12 +349,12 @@
);
}
- static void spiRxBlock0(uint8_t* ptr, uint32_t todo) {
+ static void spiRxBlock0(uint8_t *ptr, uint32_t todo) {
uint32_t bin = 0;
uint32_t work = 0;
- uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
- uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
- uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
+ uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
+ uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
+ uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
/* The software SPI routine */
__asm__ __volatile__(
@@ -425,48 +425,48 @@
);
}
- static void spiTxBlockX(const uint8_t* buf, uint32_t todo) {
+ static void spiTxBlockX(const uint8_t *buf, uint32_t todo) {
do {
(void)spiTransferTx(*buf++);
} while (--todo);
}
- static void spiRxBlockX(uint8_t* buf, uint32_t todo) {
+ static void spiRxBlockX(uint8_t *buf, uint32_t todo) {
do {
*buf++ = spiTransferRx(0xFF);
} while (--todo);
}
- // Pointers to generic functions for block tranfers
+ // Pointers to generic functions for block transfers
static pfnSpiTxBlock spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
#if MB(ALLIGATOR)
- #define _SS_WRITE(S) WRITE(SS_PIN, S)
+ #define _SS_WRITE(S) WRITE(SD_SS_PIN, S)
#else
#define _SS_WRITE(S) NOOP
#endif
void spiBegin() {
- SET_OUTPUT(SS_PIN);
+ SET_OUTPUT(SD_SS_PIN);
_SS_WRITE(HIGH);
- SET_OUTPUT(SCK_PIN);
- SET_INPUT(MISO_PIN);
- SET_OUTPUT(MOSI_PIN);
+ SET_OUTPUT(SD_SCK_PIN);
+ SET_INPUT(SD_MISO_PIN);
+ SET_OUTPUT(SD_MOSI_PIN);
}
uint8_t spiRec() {
_SS_WRITE(LOW);
- WRITE(MOSI_PIN, HIGH); // Output 1s 1
+ WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
uint8_t b = spiTransferRx(0xFF);
_SS_WRITE(HIGH);
return b;
}
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
if (nbyte) {
_SS_WRITE(LOW);
- WRITE(MOSI_PIN, HIGH); // Output 1s 1
+ WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
spiRxBlock(buf, nbyte);
_SS_WRITE(HIGH);
}
@@ -478,7 +478,7 @@
_SS_WRITE(HIGH);
}
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
_SS_WRITE(LOW);
(void)spiTransferTx(token);
spiTxBlock(buf, 512);
@@ -510,7 +510,7 @@
spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
break;
default:
- spiDelayCyclesX4 = ((F_CPU) / 1000000) >> (6 - spiRate);
+ spiDelayNS = 4000 >> (6 - spiRate); // spiRate of 2 gives the maximum error with current CPU
spiTransferTx = (pfnSpiTransfer)spiTransferX;
spiTransferRx = (pfnSpiTransfer)spiTransferX;
spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
@@ -519,8 +519,8 @@
}
_SS_WRITE(HIGH);
- WRITE(MOSI_PIN, HIGH);
- WRITE(SCK_PIN, LOW);
+ WRITE(SD_MOSI_PIN, HIGH);
+ WRITE(SD_SCK_PIN, LOW);
}
/** Begin SPI transaction, set clock, bit order, data mode */
@@ -575,20 +575,20 @@
// Configure SPI pins
PIO_Configure(
- g_APinDescription[SCK_PIN].pPort,
- g_APinDescription[SCK_PIN].ulPinType,
- g_APinDescription[SCK_PIN].ulPin,
- g_APinDescription[SCK_PIN].ulPinConfiguration);
+ g_APinDescription[SD_SCK_PIN].pPort,
+ g_APinDescription[SD_SCK_PIN].ulPinType,
+ g_APinDescription[SD_SCK_PIN].ulPin,
+ g_APinDescription[SD_SCK_PIN].ulPinConfiguration);
PIO_Configure(
- g_APinDescription[MOSI_PIN].pPort,
- g_APinDescription[MOSI_PIN].ulPinType,
- g_APinDescription[MOSI_PIN].ulPin,
- g_APinDescription[MOSI_PIN].ulPinConfiguration);
+ g_APinDescription[SD_MOSI_PIN].pPort,
+ g_APinDescription[SD_MOSI_PIN].ulPinType,
+ g_APinDescription[SD_MOSI_PIN].ulPin,
+ g_APinDescription[SD_MOSI_PIN].ulPinConfiguration);
PIO_Configure(
- g_APinDescription[MISO_PIN].pPort,
- g_APinDescription[MISO_PIN].ulPinType,
- g_APinDescription[MISO_PIN].ulPin,
- g_APinDescription[MISO_PIN].ulPinConfiguration);
+ g_APinDescription[SD_MISO_PIN].pPort,
+ g_APinDescription[SD_MISO_PIN].ulPinType,
+ g_APinDescription[SD_MISO_PIN].ulPin,
+ g_APinDescription[SD_MISO_PIN].ulPinConfiguration);
// set master mode, peripheral select, fault detection
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS);
@@ -606,7 +606,7 @@
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM2_CS, HIGH);
WRITE(SPI_FLASH_CS, HIGH);
- WRITE(SS_PIN, HIGH);
+ WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, LOW);
@@ -645,7 +645,7 @@
}
// Read from SPI into buffer
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
if (!nbyte) return;
--nbyte;
for (int i = 0; i < nbyte; i++) {
@@ -668,7 +668,7 @@
//DELAY_US(1U);
}
- void spiSend(const uint8_t* buf, size_t nbyte) {
+ void spiSend(const uint8_t *buf, size_t nbyte) {
if (!nbyte) return;
--nbyte;
for (size_t i = 0; i < nbyte; i++) {
@@ -689,7 +689,7 @@
FLUSH_RX();
}
- void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
+ void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {
if (!nbyte) return;
--nbyte;
for (size_t i = 0; i < nbyte; i++) {
@@ -702,7 +702,7 @@
}
// Write from buffer to SPI
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
SPI0->SPI_TDR = (uint32_t)token | SPI_PCS(SPI_CHAN);
WHILE_TX(0);
//WHILE_RX(0);
@@ -801,19 +801,19 @@
uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); }
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
for (int i = 0; i < nbyte; i++)
buf[i] = spiTransfer(0xFF);
}
void spiSend(uint8_t data) { spiTransfer(data); }
- void spiSend(const uint8_t* buf, size_t nbyte) {
+ void spiSend(const uint8_t *buf, size_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
spiTransfer(buf[i]);
}
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
spiTransfer(token);
for (uint16_t i = 0; i < 512; i++)
spiTransfer(buf[i]);
diff --git a/Marlin/src/HAL/DUE/MarlinSerial.cpp b/Marlin/src/HAL/DUE/MarlinSerial.cpp
index c9a372eeb14f..fe62ff5607d5 100644
--- a/Marlin/src/HAL/DUE/MarlinSerial.cpp
+++ b/Marlin/src/HAL/DUE/MarlinSerial.cpp
@@ -382,7 +382,7 @@ void MarlinSerial::flush() {
}
template
-void MarlinSerial::write(const uint8_t c) {
+size_t MarlinSerial::write(const uint8_t c) {
_written = true;
if (Cfg::TX_SIZE == 0) {
@@ -400,7 +400,7 @@ void MarlinSerial::write(const uint8_t c) {
// XOFF char at the RX isr, but it is properly handled there
if (!(HWUART->UART_IMR & UART_IMR_TXRDY) && (HWUART->UART_SR & UART_SR_TXRDY)) {
HWUART->UART_THR = c;
- return;
+ return 1;
}
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
@@ -428,6 +428,7 @@ void MarlinSerial::write(const uint8_t c) {
// Enable TX isr - Non atomic, but it will eventually enable TX isr
HWUART->UART_IER = UART_IER_TXRDY;
}
+ return 1;
}
template
@@ -473,169 +474,21 @@ void MarlinSerial::flushTX() {
}
}
-/**
- * Imports from print.h
- */
-
-template
-void MarlinSerial::print(char c, int base) {
- print((long)c, base);
-}
-
-template
-void MarlinSerial::print(unsigned char b, int base) {
- print((unsigned long)b, base);
-}
-
-template
-void MarlinSerial::print(int n, int base) {
- print((long)n, base);
-}
-
-template
-void MarlinSerial::print(unsigned int n, int base) {
- print((unsigned long)n, base);
-}
-
-template
-void MarlinSerial::print(long n, int base) {
- if (base == 0) write(n);
- else if (base == 10) {
- if (n < 0) { print('-'); n = -n; }
- printNumber(n, 10);
- }
- else
- printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
-}
-
-template
-void MarlinSerial::print(double n, int digits) {
- printFloat(n, digits);
-}
-
-template
-void MarlinSerial::println() {
- print('\r');
- print('\n');
-}
-
-template
-void MarlinSerial::println(const String& s) {
- print(s);
- println();
-}
-
-template
-void MarlinSerial::println(const char c[]) {
- print(c);
- println();
-}
-
-template
-void MarlinSerial::println(char c, int base) {
- print(c, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned char b, int base) {
- print(b, base);
- println();
-}
-
-template
-void MarlinSerial::println(int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned int n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(unsigned long n, int base) {
- print(n, base);
- println();
-}
-
-template
-void MarlinSerial::println(double n, int digits) {
- print(n, digits);
- println();
-}
-
-// Private Methods
-template
-void MarlinSerial::printNumber(unsigned long n, uint8_t base) {
- if (n) {
- unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
- int8_t i = 0;
- while (n) {
- buf[i++] = n % base;
- n /= base;
- }
- while (i--)
- print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
- }
- else
- print('0');
-}
-
-template
-void MarlinSerial::printFloat(double number, uint8_t digits) {
- // Handle negative numbers
- if (number < 0.0) {
- print('-');
- number = -number;
- }
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- LOOP_L_N(i, digits) rounding *= 0.1;
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits) {
- print('.');
- // Extract digits from the remainder one at a time
- while (digits--) {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
- }
-}
// If not using the USB port as serial port
-#if SERIAL_PORT >= 0
- template class MarlinSerial>; // Define
- MarlinSerial> customizedSerial1; // Instantiate
+#if defined(SERIAL_PORT) && SERIAL_PORT >= 0
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT1 customizedSerial1(MarlinSerialCfg::EMERGENCYPARSER);
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
- template class MarlinSerial>; // Define
- MarlinSerial> customizedSerial2; // Instantiate
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT2 customizedSerial2(MarlinSerialCfg::EMERGENCYPARSER);
+#endif
+
+#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0
+ template class MarlinSerial< MarlinSerialCfg >;
+ MSerialT3 customizedSerial3(MarlinSerialCfg::EMERGENCYPARSER);
#endif
#endif // ARDUINO_ARCH_SAM
diff --git a/Marlin/src/HAL/DUE/MarlinSerial.h b/Marlin/src/HAL/DUE/MarlinSerial.h
index a194eba2f386..4a62e2834f7f 100644
--- a/Marlin/src/HAL/DUE/MarlinSerial.h
+++ b/Marlin/src/HAL/DUE/MarlinSerial.h
@@ -30,11 +30,7 @@
#include
#include "../../inc/MarlinConfigPre.h"
-
-#define DEC 10
-#define HEX 16
-#define OCT 8
-#define BIN 2
+#include "../../core/serial_hook.h"
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
@@ -119,7 +115,7 @@ class MarlinSerial {
static int read();
static void flush();
static ring_buffer_pos_t available();
- static void write(const uint8_t c);
+ static size_t write(const uint8_t c);
static void flushTX();
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
@@ -128,35 +124,6 @@ class MarlinSerial {
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
-
- FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
- FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
- FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
- FORCE_INLINE static void print(const char* str) { write(str); }
-
- static void print(char, int = 0);
- static void print(unsigned char, int = 0);
- static void print(int, int = DEC);
- static void print(unsigned int, int = DEC);
- static void print(long, int = DEC);
- static void print(unsigned long, int = DEC);
- static void print(double, int = 2);
-
- static void println(const String& s);
- static void println(const char[]);
- static void println(char, int = 0);
- static void println(unsigned char, int = 0);
- static void println(int, int = DEC);
- static void println(unsigned int, int = DEC);
- static void println(long, int = DEC);
- static void println(unsigned long, int = DEC);
- static void println(double, int = 2);
- static void println();
- operator bool() { return true; }
-
-private:
- static void printNumber(unsigned long, const uint8_t);
- static void printFloat(double, uint8_t);
};
// Serial port configuration
@@ -173,10 +140,17 @@ struct MarlinSerialCfg {
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
-#if SERIAL_PORT >= 0
- extern MarlinSerial> customizedSerial1;
+#if defined(SERIAL_PORT) && SERIAL_PORT >= 0
+ typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT1;
+ extern MSerialT1 customizedSerial1;
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
- extern MarlinSerial> customizedSerial2;
+ typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT2;
+ extern MSerialT2 customizedSerial2;
+#endif
+
+#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0
+ typedef Serial1Class< MarlinSerial< MarlinSerialCfg > > MSerialT3;
+ extern MSerialT3 customizedSerial3;
#endif
diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp
index a41dbfeb7a57..67c597da80c4 100644
--- a/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp
+++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.cpp
@@ -19,13 +19,13 @@
* along with this program. If not, see .
*
*/
+#ifdef ARDUINO_ARCH_SAM
/**
* MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE
* Copyright (c) 2017 Eduardo José Tagle. All right reserved
* Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved.
*/
-#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
@@ -33,10 +33,6 @@
#include "MarlinSerialUSB.h"
-#if ENABLED(EMERGENCY_PARSER)
- #include "../../feature/e_parser.h"
-#endif
-
// Imports from Atmel USB Stack/CDC implementation
extern "C" {
bool usb_task_cdc_isenabled();
@@ -50,10 +46,6 @@ extern "C" {
// Pending character
static int pending_char = -1;
-#if ENABLED(EMERGENCY_PARSER)
- static EmergencyParser::State emergency_state; // = EP_RESET
-#endif
-
// Public Methods
void MarlinSerialUSB::begin(const long) {}
@@ -73,7 +65,7 @@ int MarlinSerialUSB::peek() {
pending_char = udi_cdc_getc();
- TERN_(EMERGENCY_PARSER, emergency_parser.update(emergency_state, (char)pending_char));
+ TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)pending_char));
return pending_char;
}
@@ -95,29 +87,27 @@ int MarlinSerialUSB::read() {
int c = udi_cdc_getc();
- TERN_(EMERGENCY_PARSER, emergency_parser.update(emergency_state, (char)c));
+ TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast(this)->emergency_state, (char)c));
return c;
}
-bool MarlinSerialUSB::available() {
- /* If Pending chars */
- return pending_char >= 0 ||
- /* or USB CDC enumerated and configured on the PC side and some
- bytes where sent to us */
- (usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
+int MarlinSerialUSB::available() {
+ if (pending_char > 0) return pending_char;
+ return pending_char == 0 ||
+ // or USB CDC enumerated and configured on the PC side and some bytes where sent to us */
+ (usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
}
void MarlinSerialUSB::flush() { }
-void MarlinSerialUSB::flushTX() { }
-void MarlinSerialUSB::write(const uint8_t c) {
+size_t MarlinSerialUSB::write(const uint8_t c) {
/* Do not even bother sending anything if USB CDC is not enumerated
or not configured on the PC side or there is no program on the PC
listening to our messages */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
- return;
+ return 0;
/* Wait until the PC has read the pending to be sent data */
while (usb_task_cdc_isenabled() &&
@@ -129,161 +119,23 @@ void MarlinSerialUSB::write(const uint8_t c) {
or not configured on the PC side or there is no program on the PC
listening to our messages at this point */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
- return;
+ return 0;
// Fifo full
// udi_cdc_signal_overrun();
udi_cdc_putc(c);
-}
-
-/**
- * Imports from print.h
- */
-
-void MarlinSerialUSB::print(char c, int base) {
- print((long)c, base);
-}
-
-void MarlinSerialUSB::print(unsigned char b, int base) {
- print((unsigned long)b, base);
-}
-
-void MarlinSerialUSB::print(int n, int base) {
- print((long)n, base);
-}
-
-void MarlinSerialUSB::print(unsigned int n, int base) {
- print((unsigned long)n, base);
-}
-
-void MarlinSerialUSB::print(long n, int base) {
- if (base == 0)
- write(n);
- else if (base == 10) {
- if (n < 0) {
- print('-');
- n = -n;
- }
- printNumber(n, 10);
- }
- else
- printNumber(n, base);
-}
-
-void MarlinSerialUSB::print(unsigned long n, int base) {
- if (base == 0) write(n);
- else printNumber(n, base);
-}
-
-void MarlinSerialUSB::print(double n, int digits) {
- printFloat(n, digits);
-}
-
-void MarlinSerialUSB::println() {
- print('\r');
- print('\n');
-}
-
-void MarlinSerialUSB::println(const String& s) {
- print(s);
- println();
-}
-
-void MarlinSerialUSB::println(const char c[]) {
- print(c);
- println();
-}
-
-void MarlinSerialUSB::println(char c, int base) {
- print(c, base);
- println();
-}
-
-void MarlinSerialUSB::println(unsigned char b, int base) {
- print(b, base);
- println();
-}
-
-void MarlinSerialUSB::println(int n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(unsigned int n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(long n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(unsigned long n, int base) {
- print(n, base);
- println();
-}
-
-void MarlinSerialUSB::println(double n, int digits) {
- print(n, digits);
- println();
-}
-
-// Private Methods
-
-void MarlinSerialUSB::printNumber(unsigned long n, uint8_t base) {
- if (n) {
- unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
- int8_t i = 0;
- while (n) {
- buf[i++] = n % base;
- n /= base;
- }
- while (i--)
- print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
- }
- else
- print('0');
-}
-
-void MarlinSerialUSB::printFloat(double number, uint8_t digits) {
- // Handle negative numbers
- if (number < 0.0) {
- print('-');
- number = -number;
- }
-
- // Round correctly so that print(1.999, 2) prints as "2.00"
- double rounding = 0.5;
- LOOP_L_N(i, digits)
- rounding *= 0.1;
-
- number += rounding;
-
- // Extract the integer part of the number and print it
- unsigned long int_part = (unsigned long)number;
- double remainder = number - (double)int_part;
- print(int_part);
-
- // Print the decimal point, but only if there are digits beyond
- if (digits) {
- print('.');
- // Extract digits from the remainder one at a time
- while (digits--) {
- remainder *= 10.0;
- int toPrint = int(remainder);
- print(toPrint);
- remainder -= toPrint;
- }
- }
+ return 1;
}
// Preinstantiate
#if SERIAL_PORT == -1
- MarlinSerialUSB customizedSerial1;
+ MSerialT1 customizedSerial1(TERN0(EMERGENCY_PARSER, true));
#endif
#if SERIAL_PORT_2 == -1
- MarlinSerialUSB customizedSerial2;
+ MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true));
+#endif
+#if SERIAL_PORT_3 == -1
+ MSerialT3 customizedSerial3(TERN0(EMERGENCY_PARSER, true));
#endif
#endif // HAS_USB_SERIAL
diff --git a/Marlin/src/HAL/DUE/MarlinSerialUSB.h b/Marlin/src/HAL/DUE/MarlinSerialUSB.h
index 2e3622e5534a..6da1ef8c08f6 100644
--- a/Marlin/src/HAL/DUE/MarlinSerialUSB.h
+++ b/Marlin/src/HAL/DUE/MarlinSerialUSB.h
@@ -27,73 +27,39 @@
*/
#include "../../inc/MarlinConfig.h"
-
-#if HAS_USB_SERIAL
+#include "../../core/serial_hook.h"
#include
-#define DEC 10
-#define HEX 16
-#define OCT 8
-#define BIN 2
-
-class MarlinSerialUSB {
-
-public:
- MarlinSerialUSB() {};
- static void begin(const long);
- static void end();
- static int peek();
- static int read();
- static void flush();
- static void flushTX();
- static bool available();
- static void write(const uint8_t c);
+struct MarlinSerialUSB {
+ void begin(const long);
+ void end();
+ int peek();
+ int read();
+ void flush();
+ int available();
+ size_t write(const uint8_t c);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
- FORCE_INLINE static uint32_t dropped() { return 0; }
+ FORCE_INLINE uint32_t dropped() { return 0; }
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
- FORCE_INLINE static int rxMaxEnqueued() { return 0; }
+ FORCE_INLINE int rxMaxEnqueued() { return 0; }
#endif
-
- FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
- FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
- FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
- FORCE_INLINE static void print(const char* str) { write(str); }
-
- static void print(char, int = 0);
- static void print(unsigned char, int = 0);
- static void print(int, int = DEC);
- static void print(unsigned int, int = DEC);
- static void print(long, int = DEC);
- static void print(unsigned long, int = DEC);
- static void print(double, int = 2);
-
- static void println(const String& s);
- static void println(const char[]);
- static void println(char, int = 0);
- static void println(unsigned char, int = 0);
- static void println(int, int = DEC);
- static void println(unsigned int, int = DEC);
- static void println(long, int = DEC);
- static void println(unsigned long, int = DEC);
- static void println(double, int = 2);
- static void println();
- operator bool() { return true; }
-
-private:
- static void printNumber(unsigned long, const uint8_t);
- static void printFloat(double, uint8_t);
};
#if SERIAL_PORT == -1
- extern MarlinSerialUSB customizedSerial1;
+ typedef Serial1Class MSerialT1;
+ extern MSerialT1 customizedSerial1;
#endif
#if SERIAL_PORT_2 == -1
- extern MarlinSerialUSB customizedSerial2;
+ typedef Serial1Class MSerialT2;
+ extern MSerialT2 customizedSerial2;
#endif
-#endif // HAS_USB_SERIAL
+#if SERIAL_PORT_3 == -1
+ typedef Serial1Class MSerialT3;
+ extern MSerialT3 customizedSerial3;
+#endif
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
index be4b49c0f992..fcfcef88beb1 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_shared_hw_spi.cpp
@@ -60,16 +60,15 @@
#if HAS_MARLINUI_U8GLIB
-#include
+#include
#include "../../../MarlinCore.h"
-void spiBegin();
-void spiInit(uint8_t spiRate);
-void spiSend(uint8_t b);
-void spiSend(const uint8_t* buf, size_t n);
+#ifndef LCD_SPI_SPEED
+ #define LCD_SPI_SPEED SPI_QUARTER_SPEED
+#endif
-#include "../../shared/Marduino.h"
+#include "../../shared/HAL_SPI.h"
#include "../fastio.h"
void u8g_SetPIOutput_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index) {
@@ -100,11 +99,7 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
spiBegin();
- #ifndef SPI_SPEED
- #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
- #endif
- spiInit(2);
-
+ spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
index 47060d6a5be2..65bfd4f4e2d4 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_st7920_sw_spi.cpp
@@ -59,9 +59,10 @@
#if ENABLED(U8GLIB_ST7920)
+#include "../../../inc/MarlinConfig.h"
#include "../../shared/Delay.h"
-#include
+#include
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
@@ -145,7 +146,7 @@ uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
}
#if ENABLED(LIGHTWEIGHT_UI)
- #include "../../../lcd/ultralcd.h"
+ #include "../../../lcd/marlinui.h"
#include "../../shared/HAL_ST7920.h"
#define ST7920_CS_PIN LCD_PINS_RS
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
index ea7204fa366b..2b13c182d023 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi.cpp
@@ -59,15 +59,12 @@
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
-#undef SPI_SPEED
-#define SPI_SPEED 2 // About 2 MHz
-
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
#include "../../shared/Marduino.h"
#include "../../shared/Delay.h"
-#include
+#include
#if ENABLED(FYSETC_MINI_12864)
#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_3
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
index 615a386c3542..904924793b4c 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.cpp
@@ -59,9 +59,10 @@
#if HAS_MARLINUI_U8GLIB
+#include "../../../inc/MarlinConfig.h"
#include "../../shared/Delay.h"
-#include
+#include
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
diff --git a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h
index f076c503cac2..45231fd091eb 100644
--- a/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h
+++ b/Marlin/src/HAL/DUE/dogm/u8g_com_HAL_DUE_sw_spi_shared.h
@@ -23,7 +23,7 @@
#include "../../../inc/MarlinConfigPre.h"
#include "../../shared/Marduino.h"
-#include
+#include
void u8g_SetPIOutput_DUE(u8g_t *u8g, uint8_t pin_index);
void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level);
diff --git a/Marlin/src/HAL/DUE/eeprom_flash.cpp b/Marlin/src/HAL/DUE/eeprom_flash.cpp
index 6f38da0967cb..b4cb9912b24f 100644
--- a/Marlin/src/HAL/DUE/eeprom_flash.cpp
+++ b/Marlin/src/HAL/DUE/eeprom_flash.cpp
@@ -135,11 +135,11 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
#define DEBUG_OUT ENABLED(EE_EMU_DEBUG)
#include "../../core/debug_out.h"
-static void ee_Dump(const int page, const void* data) {
+static void ee_Dump(const int page, const void *data) {
#ifdef EE_EMU_DEBUG
- const uint8_t* c = (const uint8_t*) data;
+ const uint8_t *c = (const uint8_t*) data;
char buffer[80];
sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page);
@@ -181,7 +181,7 @@ static void ee_Dump(const int page, const void* data) {
* @param data (pointer to the data buffer)
*/
__attribute__ ((long_call, section (".ramfunc")))
-static bool ee_PageWrite(uint16_t page, const void* data) {
+static bool ee_PageWrite(uint16_t page, const void *data) {
uint16_t i;
uint32_t addrflash = uint32_t(getFlashStorage(page));
@@ -293,8 +293,8 @@ static bool ee_PageWrite(uint16_t page, const void* data) {
ee_Dump(-page, data);
// Calculate count of changed bits
- uint32_t* p1 = (uint32_t*)addrflash;
- uint32_t* p2 = (uint32_t*)data;
+ uint32_t *p1 = (uint32_t*)addrflash;
+ uint32_t *p2 = (uint32_t*)data;
int count = 0;
for (i =0; i> 2; i++) {
if (p1[i] != p2[i]) {
@@ -470,7 +470,7 @@ static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) {
for (int page = curPage - 1; page >= 0; --page) {
// Get a pointer to the flash page
- uint8_t* pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
+ uint8_t *pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
uint16_t i = 0;
while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */
@@ -550,7 +550,7 @@ static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) {
for (int page = curPage - 1; page >= 0; --page) {
// Get a pointer to the flash page
- uint8_t* pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
+ uint8_t *pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
uint16_t i = 0;
while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */
@@ -589,7 +589,7 @@ static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) {
}
static bool ee_IsPageClean(int page) {
- uint32_t* pflash = (uint32_t*) getFlashStorage(page);
+ uint32_t *pflash = (uint32_t*) getFlashStorage(page);
for (uint16_t i = 0; i < (PageSize >> 2); ++i)
if (*pflash++ != 0xFFFFFFFF) return false;
return true;
@@ -599,7 +599,7 @@ static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData
// Check if RAM buffer has something to be written
bool isEmpty = true;
- uint32_t* p = (uint32_t*) &buffer[0];
+ uint32_t *p = (uint32_t*) &buffer[0];
for (uint16_t j = 0; j < (PageSize >> 2); j++) {
if (*p++ != 0xFFFFFFFF) {
isEmpty = false;
@@ -976,14 +976,13 @@ bool PersistentStore::access_start() { ee_Init(); return true; }
bool PersistentStore::access_finish() { ee_Flush(); return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
- // EEPROM has only ~100,000 write cycles,
- // so only write bytes that have changed!
- if (v != ee_Read(uint32_t(p))) {
+ if (v != ee_Read(uint32_t(p))) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
ee_Write(uint32_t(p), v);
- delay(2);
+ if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (ee_Read(uint32_t(p)) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
@@ -996,7 +995,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = ee_Read(uint32_t(pos));
if (writing) *value = c;
diff --git a/Marlin/src/HAL/DUE/eeprom_wired.cpp b/Marlin/src/HAL/DUE/eeprom_wired.cpp
index 4599d6a7cd44..557a2f2cffa5 100644
--- a/Marlin/src/HAL/DUE/eeprom_wired.cpp
+++ b/Marlin/src/HAL/DUE/eeprom_wired.cpp
@@ -42,14 +42,13 @@ bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ uint16_t written = 0;
while (size--) {
uint8_t * const p = (uint8_t * const)pos;
uint8_t v = *value;
- // EEPROM has only ~100,000 write cycles,
- // so only write bytes that have changed!
- if (v != eeprom_read_byte(p)) {
+ if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
- delay(2);
+ if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
@@ -62,7 +61,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/DUE/endstop_interrupts.h b/Marlin/src/HAL/DUE/endstop_interrupts.h
index 999ada512761..9c7e2104882e 100644
--- a/Marlin/src/HAL/DUE/endstop_interrupts.h
+++ b/Marlin/src/HAL/DUE/endstop_interrupts.h
@@ -64,4 +64,10 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
+ TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
+ TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
+ TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
+ TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
+ TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
+ TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
}
diff --git a/Marlin/src/HAL/DUE/fastio.h b/Marlin/src/HAL/DUE/fastio.h
index 286319302dd2..a609210d8130 100644
--- a/Marlin/src/HAL/DUE/fastio.h
+++ b/Marlin/src/HAL/DUE/fastio.h
@@ -33,7 +33,7 @@
* For ARDUINO_ARCH_SAM
* Note the code here was specifically crafted by disassembling what GCC produces
* out of it, so GCC is able to optimize it out as much as possible to the least
- * amount of instructions. Be very carefull if you modify them, as "clean code"
+ * amount of instructions. Be very careful if you modify them, as "clean code"
* leads to less efficient compiled code!!
*/
@@ -50,7 +50,7 @@
#define PWM_PIN(P) WITHIN(P, 2, 13)
#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+ #define MASK(PIN) _BV(PIN)
#endif
/**
@@ -163,6 +163,9 @@
#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 (substitution)
+#define SET_INPUT_PULLDOWN SET_INPUT
+
// Set pin as output (wrapper) - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
// Set pin as PWM
@@ -477,7 +480,7 @@
#define DIO91_PIN 15
#define DIO91_WPORT PIOB
-#if ARDUINO_SAM_ARCHIM
+#ifdef ARDUINO_SAM_ARCHIM
#define DIO92_PIN 11
#define DIO92_WPORT PIOC
diff --git a/Marlin/src/HAL/DUE/inc/SanityCheck.h b/Marlin/src/HAL/DUE/inc/SanityCheck.h
index 688069650630..87b09cf29257 100644
--- a/Marlin/src/HAL/DUE/inc/SanityCheck.h
+++ b/Marlin/src/HAL/DUE/inc/SanityCheck.h
@@ -40,7 +40,7 @@
* Usually the hardware SPI pins are only available to the LCD. This makes the DUE hard SPI used at the same time
* as the TMC2130 soft SPI the most common setup.
*/
-#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == MOSI_PIN || TMC_SW_##P == MISO_PIN || TMC_SW_##P == SCK_PIN))
+#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == SD_MOSI_PIN || TMC_SW_##P == SD_MISO_PIN || TMC_SW_##P == SD_SCK_PIN))
#if ENABLED(SDSUPPORT) && HAS_DRIVER(TMC2130)
#if ENABLED(TMC_USE_SW_SPI)
@@ -57,5 +57,5 @@
#endif
#if HAS_TMC_SW_SERIAL
- #error "TMC220x Software Serial is not supported on this platform."
+ #error "TMC220x Software Serial is not supported on the DUE platform."
#endif
diff --git a/Marlin/src/HAL/DUE/spi_pins.h b/Marlin/src/HAL/DUE/spi_pins.h
index e28eaf827020..cec22c2c374a 100644
--- a/Marlin/src/HAL/DUE/spi_pins.h
+++ b/Marlin/src/HAL/DUE/spi_pins.h
@@ -43,22 +43,22 @@
#define SPI_PIN 87
#define SPI_CHAN 1
#endif
- #define SCK_PIN 76
- #define MISO_PIN 74
- #define MOSI_PIN 75
+ #define SD_SCK_PIN 76
+ #define SD_MISO_PIN 74
+ #define SD_MOSI_PIN 75
#else
// defaults
#define DUE_SOFTWARE_SPI
- #ifndef SCK_PIN
- #define SCK_PIN 52
+ #ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 52
#endif
- #ifndef MISO_PIN
- #define MISO_PIN 50
+ #ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 50
#endif
- #ifndef MOSI_PIN
- #define MOSI_PIN 51
+ #ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 51
#endif
#endif
/* A.28, A.29, B.21, C.26, C.29 */
-#define SS_PIN SDSS
+#define SD_SS_PIN SDSS
diff --git a/Marlin/src/HAL/DUE/timers.cpp b/Marlin/src/HAL/DUE/timers.cpp
index 9b937d1a7c83..65073c510d7c 100644
--- a/Marlin/src/HAL/DUE/timers.cpp
+++ b/Marlin/src/HAL/DUE/timers.cpp
@@ -121,7 +121,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
- return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
+ return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
diff --git a/Marlin/src/HAL/DUE/usb/arduino_due_x.h b/Marlin/src/HAL/DUE/usb/arduino_due_x.h
index d3b333fb349a..e7b6f3dcb303 100644
--- a/Marlin/src/HAL/DUE/usb/arduino_due_x.h
+++ b/Marlin/src/HAL/DUE/usb/arduino_due_x.h
@@ -71,7 +71,7 @@
/* ------------------------------------------------------------------------ */
/**
- * \page arduino_due_x_board_info "Arduino Due/X - Board informations"
+ * \page arduino_due_x_board_info "Arduino Due/X - Board information"
* This page lists several definition related to the board description.
*
*/
diff --git a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
index ea2936359d81..3dcbbaecd28f 100644
--- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
+++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
@@ -32,7 +32,7 @@ Ctrl_status sd_mmc_spi_test_unit_ready() {
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.getSd2Card().cardSize() - 1;
+ *nb_sector = card.diskIODriver()->cardSize() - 1;
return CTRL_GOOD;
}
@@ -68,30 +68,30 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
{
char buffer[80];
sprintf_P(buffer, PSTR("SDRD: %d @ 0x%08x\n"), nb_sector, addr);
- PORT_REDIRECT(0);
+ PORT_REDIRECT(SERIAL_PORTMASK(0));
SERIAL_ECHO(buffer);
}
#endif
// Start reading
- if (!card.getSd2Card().readStart(addr))
+ if (!card.diskIODriver()->readStart(addr))
return CTRL_FAIL;
// For each specified sector
while (nb_sector--) {
// Read a sector
- card.getSd2Card().readData(sector_buf);
+ card.diskIODriver()->readData(sector_buf);
// RAM -> USB
- if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, NULL)) {
- card.getSd2Card().readStop();
+ if (!udi_msc_trans_block(true, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
+ card.diskIODriver()->readStop();
return CTRL_FAIL;
}
}
// Stop reading
- card.getSd2Card().readStop();
+ card.diskIODriver()->readStop();
// Done
return CTRL_GOOD;
@@ -108,29 +108,29 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
{
char buffer[80];
sprintf_P(buffer, PSTR("SDWR: %d @ 0x%08x\n"), nb_sector, addr);
- PORT_REDIRECT(0);
+ PORT_REDIRECT(SERIAL_PORTMASK(0));
SERIAL_ECHO(buffer);
}
#endif
- if (!card.getSd2Card().writeStart(addr, nb_sector))
+ if (!card.diskIODriver()->writeStart(addr, nb_sector))
return CTRL_FAIL;
// For each specified sector
while (nb_sector--) {
// USB -> RAM
- if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, NULL)) {
- card.getSd2Card().writeStop();
+ if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
+ card.diskIODriver()->writeStop();
return CTRL_FAIL;
}
// Write a sector
- card.getSd2Card().writeData(sector_buf);
+ card.diskIODriver()->writeData(sector_buf);
}
// Stop writing
- card.getSd2Card().writeStop();
+ card.diskIODriver()->writeStop();
// Done
return CTRL_GOOD;
diff --git a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h
index d77e4f95232b..553fd3c29a88 100644
--- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h
+++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h
@@ -74,7 +74,7 @@
#define SD_MMC_REMOVING 2
-//---- CONTROL FONCTIONS ----
+//---- CONTROL FUNCTIONS ----
//!
//! @brief This function initializes the hw/sw resources required to drive the SD_MMC_SPI.
//!/
@@ -134,7 +134,7 @@ extern bool sd_mmc_spi_wr_protect(void);
extern bool sd_mmc_spi_removal(void);
-//---- ACCESS DATA FONCTIONS ----
+//---- ACCESS DATA FUNCTIONS ----
#if ACCESS_USB == true
// Standard functions for open in read/write mode the device
diff --git a/Marlin/src/HAL/DUE/usb/udd.h b/Marlin/src/HAL/DUE/usb/udd.h
index 7ec8c03dee63..319d8842f744 100644
--- a/Marlin/src/HAL/DUE/usb/udd.h
+++ b/Marlin/src/HAL/DUE/usb/udd.h
@@ -90,7 +90,7 @@ typedef struct {
//! This buffer must be word align for DATA IN phase (use prefix COMPILER_WORD_ALIGNED for buffer)
uint8_t *payload;
- //! Size of buffer to send or fill, and content the number of byte transfered
+ //! Size of buffer to send or fill, and content the number of byte transferred
uint16_t payload_size;
//! Callback called after reception of ZLP from setup request
@@ -132,10 +132,10 @@ typedef void (*udd_callback_halt_cleared_t)(void);
*
* \param status UDD_EP_TRANSFER_OK, if transfer is complete
* \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted
- * \param n number of data transfered
+ * \param n number of data transferred
*/
typedef void (*udd_callback_trans_t) (udd_ep_status_t status,
- iram_size_t nb_transfered, udd_ep_id_t ep);
+ iram_size_t nb_transferred, udd_ep_id_t ep);
/**
* \brief Authorizes the VBUS event
@@ -303,7 +303,7 @@ bool udd_ep_wait_stall_clear(udd_ep_id_t ep,
* The driver uses a specific DMA USB to transfer data
* from internal RAM to endpoint, if this one is available.
* When the transfer is finished or aborted (stall, reset, ...), the \a callback is called.
- * The \a callback returns the transfer status and eventually the number of byte transfered.
+ * The \a callback returns the transfer status and eventually the number of byte transferred.
* Note: The control endpoint is not authorized.
*
* \param ep The ID of the endpoint to use
diff --git a/Marlin/src/HAL/DUE/usb/udi_cdc.c b/Marlin/src/HAL/DUE/usb/udi_cdc.c
index cbe23dbb68fb..89debe57f130 100644
--- a/Marlin/src/HAL/DUE/usb/udi_cdc.c
+++ b/Marlin/src/HAL/DUE/usb/udi_cdc.c
@@ -162,7 +162,7 @@ static void udi_cdc_ctrl_state_notify(uint8_t port, udd_ep_id_t ep);
*
* \param status UDD_EP_TRANSFER_OK, if transfer finished
* \param status UDD_EP_TRANSFER_ABORT, if transfer aborted
- * \param n number of data transfered
+ * \param n number of data transferred
*/
static void udi_cdc_serial_state_msg_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep);
@@ -200,7 +200,7 @@ static void udi_cdc_data_received(udd_ep_status_t status, iram_size_t n, udd_ep_
*
* \param status UDD_EP_TRANSFER_OK, if transfer finished
* \param status UDD_EP_TRANSFER_ABORT, if transfer aborted
- * \param n number of data transfered
+ * \param n number of data transferred
*/
static void udi_cdc_data_sent(udd_ep_status_t status, iram_size_t n, udd_ep_id_t ep);
diff --git a/Marlin/src/HAL/DUE/usb/udi_cdc.h b/Marlin/src/HAL/DUE/usb/udi_cdc.h
index 0ecf7bb00e5e..b61845011aa2 100644
--- a/Marlin/src/HAL/DUE/usb/udi_cdc.h
+++ b/Marlin/src/HAL/DUE/usb/udi_cdc.h
@@ -675,11 +675,11 @@ iram_size_t udi_cdc_multi_write_buf(uint8_t port, const void* buf, iram_size_t s
* - \code // Waits and gets a value on CDC line
int udi_cdc_getc(void);
// Reads a RAM buffer on CDC line
- iram_size_t udi_cdc_read_buf(int* buf, iram_size_t size);
+ iram_size_t udi_cdc_read_buf(int *buf, iram_size_t size);
// Puts a byte on CDC line
int udi_cdc_putc(int value);
// Writes a RAM buffer on CDC line
- iram_size_t udi_cdc_write_buf(const int* buf, iram_size_t size); \endcode
+ iram_size_t udi_cdc_write_buf(const int *buf, iram_size_t size); \endcode
*
* \section udi_cdc_use_cases Advanced use cases
* For more advanced use of the UDI CDC module, see the following use cases:
diff --git a/Marlin/src/HAL/DUE/usb/udi_cdc_conf.h b/Marlin/src/HAL/DUE/usb/udi_cdc_conf.h
index d406a87743f3..e61b8cbaadf4 100644
--- a/Marlin/src/HAL/DUE/usb/udi_cdc_conf.h
+++ b/Marlin/src/HAL/DUE/usb/udi_cdc_conf.h
@@ -106,7 +106,7 @@ extern "C" {
*/
//@{
# if UDI_CDC_PORT_NB > 2
-# error USBB, UDP, UDPHS and UOTGHS interfaces have not enought endpoints.
+# error USBB, UDP, UDPHS and UOTGHS interfaces have not enough endpoints.
# endif
#define UDI_CDC_DATA_EP_IN_0 (1 | USB_EP_DIR_IN) // TX
#define UDI_CDC_DATA_EP_OUT_0 (2 | USB_EP_DIR_OUT) // RX
diff --git a/Marlin/src/HAL/DUE/usb/udi_msc.c b/Marlin/src/HAL/DUE/usb/udi_msc.c
index b7c3bb5ea016..dd3404877210 100644
--- a/Marlin/src/HAL/DUE/usb/udi_msc.c
+++ b/Marlin/src/HAL/DUE/usb/udi_msc.c
@@ -173,7 +173,7 @@ static void udi_msc_cbw_wait(void);
*
* \param status UDD_EP_TRANSFER_OK, if transfer is finished
* \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted
- * \param nb_received number of data transfered
+ * \param nb_received number of data transferred
*/
static void udi_msc_cbw_received(udd_ep_status_t status,
iram_size_t nb_received, udd_ep_id_t ep);
@@ -211,7 +211,7 @@ static void udi_msc_data_send(uint8_t * buffer, uint8_t buf_size);
*
* \param status UDD_EP_TRANSFER_OK, if transfer finish
* \param status UDD_EP_TRANSFER_ABORT, if transfer aborted
- * \param nb_sent number of data transfered
+ * \param nb_sent number of data transferred
*/
static void udi_msc_data_sent(udd_ep_status_t status, iram_size_t nb_sent,
udd_ep_id_t ep);
@@ -244,7 +244,7 @@ void udi_msc_csw_send(void);
*
* \param status UDD_EP_TRANSFER_OK, if transfer is finished
* \param status UDD_EP_TRANSFER_ABORT, if transfer is aborted
- * \param nb_sent number of data transfered
+ * \param nb_sent number of data transferred
*/
static void udi_msc_csw_sent(udd_ep_status_t status, iram_size_t nb_sent,
udd_ep_id_t ep);
@@ -463,7 +463,7 @@ uint8_t udi_msc_getsetting(void)
static void udi_msc_cbw_invalid(void)
{
if (!udi_msc_b_cbw_invalid)
- return; // Don't re-stall endpoint if error reseted by setup
+ return; // Don't re-stall endpoint if error reset by setup
udd_ep_set_halt(UDI_MSC_EP_OUT);
// If stall cleared then re-stall it. Only Setup MSC Reset can clear it
udd_ep_wait_stall_clear(UDI_MSC_EP_OUT, udi_msc_cbw_invalid);
@@ -472,7 +472,7 @@ static void udi_msc_cbw_invalid(void)
static void udi_msc_csw_invalid(void)
{
if (!udi_msc_b_cbw_invalid)
- return; // Don't re-stall endpoint if error reseted by setup
+ return; // Don't re-stall endpoint if error reset by setup
udd_ep_set_halt(UDI_MSC_EP_IN);
// If stall cleared then re-stall it. Only Setup MSC Reset can clear it
udd_ep_wait_stall_clear(UDI_MSC_EP_IN, udi_msc_csw_invalid);
diff --git a/Marlin/src/HAL/DUE/usb/uotghs_device_due.c b/Marlin/src/HAL/DUE/usb/uotghs_device_due.c
index e13232a39c7d..c7e8f8d99135 100644
--- a/Marlin/src/HAL/DUE/usb/uotghs_device_due.c
+++ b/Marlin/src/HAL/DUE/usb/uotghs_device_due.c
@@ -325,7 +325,7 @@ static void udd_sleep_mode(bool b_idle)
/**
* \name Control endpoint low level management routine.
*
- * This function performs control endpoint mangement.
+ * This function performs control endpoint management.
* It handle the SETUP/DATA/HANDSHAKE phases of a control transaction.
*/
//@{
@@ -397,9 +397,9 @@ static void udd_ctrl_endofrequest(void);
/**
* \brief Main interrupt routine for control endpoint
*
- * This switchs control endpoint events to correct sub function.
+ * This switches control endpoint events to correct sub function.
*
- * \return \c 1 if an event about control endpoint is occured, otherwise \c 0.
+ * \return \c 1 if an event about control endpoint is occurred, otherwise \c 0.
*/
static bool udd_ctrl_interrupt(void);
@@ -410,7 +410,7 @@ static bool udd_ctrl_interrupt(void);
* \name Management of bulk/interrupt/isochronous endpoints
*
* The UDD manages the data transfer on endpoints:
- * - Start data tranfer on endpoint with USB Device DMA
+ * - Start data transfer on endpoint with USB Device DMA
* - Send a ZLP packet if requested
* - Call callback registered to signal end of transfer
* The transfer abort and stall feature are supported.
@@ -431,7 +431,7 @@ typedef struct {
uint8_t *buf;
//! Size of buffer to send or fill
iram_size_t buf_size;
- //!< Size of data transfered
+ //!< Size of data transferred
iram_size_t buf_cnt;
//!< Size of data loaded (or prepared for DMA) last time
iram_size_t buf_load;
@@ -486,7 +486,7 @@ static void udd_ep_finish_job(udd_ep_job_t * ptr_job, bool b_abort, uint8_t ep_n
#ifdef UDD_EP_DMA_SUPPORTED
/**
- * \brief Start the next transfer if necessary or complet the job associated.
+ * \brief Start the next transfer if necessary or complete the job associated.
*
* \param ep endpoint number without direction flag
*/
@@ -496,9 +496,9 @@ static void udd_ep_finish_job(udd_ep_job_t * ptr_job, bool b_abort, uint8_t ep_n
/**
* \brief Main interrupt routine for bulk/interrupt/isochronous endpoints
*
- * This switchs endpoint events to correct sub function.
+ * This switches endpoint events to correct sub function.
*
- * \return \c 1 if an event about bulk/interrupt/isochronous endpoints has occured, otherwise \c 0.
+ * \return \c 1 if an event about bulk/interrupt/isochronous endpoints has occurred, otherwise \c 0.
*/
static bool udd_ep_interrupt(void);
@@ -520,7 +520,7 @@ static bool udd_ep_interrupt(void);
*
* Note:
* Here, the global interrupt mask is not clear when an USB interrupt is enabled
- * because this one can not be occured during the USB ISR (=during INTX is masked).
+ * because this one can not be occurred during the USB ISR (=during INTX is masked).
* See Technical reference $3.8.3 Masking interrupt requests in peripheral modules.
*/
#ifdef UHD_ENABLE
@@ -787,7 +787,7 @@ void udd_attach(void)
udd_sleep_mode(true);
otg_unfreeze_clock();
- // This section of clock check can be improved with a chek of
+ // This section of clock check can be improved with a check of
// USB clock source via sysclk()
// Check USB clock because the source can be a PLL
while (!Is_otg_clock_usable());
@@ -803,7 +803,7 @@ void udd_attach(void)
#ifdef USB_DEVICE_HS_SUPPORT
udd_enable_msof_interrupt();
#endif
- // Reset following interupts flag
+ // Reset following interrupts flag
udd_ack_reset();
udd_ack_sof();
udd_ack_msof();
@@ -902,7 +902,7 @@ bool udd_ep_alloc(udd_ep_id_t ep, uint8_t bmAttributes,
}
dbg_print("alloc(%x, %d) ", ep, MaxEndpointSize);
- // Bank choise
+ // Bank choice
switch (bmAttributes & USB_EP_TYPE_MASK) {
case USB_EP_TYPE_ISOCHRONOUS:
nb_bank = UDD_ISOCHRONOUS_NB_BANK(ep);
@@ -1228,7 +1228,7 @@ bool udd_ep_wait_stall_clear(udd_ep_id_t ep,
if (Is_udd_endpoint_stall_requested(ep)
|| ptr_job->stall_requested) {
- // Endpoint halted then registes the callback
+ // Endpoint halted then registers the callback
ptr_job->busy = true;
ptr_job->call_nohalt = callback;
} else {
@@ -1386,7 +1386,7 @@ static void udd_ctrl_setup_received(void)
// Decode setup request
if (udc_process_setup() == false) {
- // Setup request unknow then stall it
+ // Setup request unknown then stall it
udd_ctrl_stall_data();
udd_ack_setup_received(0);
return;
@@ -1447,7 +1447,7 @@ static void udd_ctrl_in_sent(void)
udd_ctrl_prev_payload_buf_cnt += udd_ctrl_payload_buf_cnt;
if ((udd_g_ctrlreq.req.wLength == udd_ctrl_prev_payload_buf_cnt)
|| b_shortpacket) {
- // All data requested are transfered or a short packet has been sent
+ // All data requested are transferred or a short packet has been sent
// then it is the end of data phase.
// Generate an OUT ZLP for handshake phase.
udd_ctrl_send_zlp_out();
@@ -1516,7 +1516,7 @@ static void udd_ctrl_out_received(void)
// End of SETUP request:
// - Data IN Phase aborted,
// - or last Data IN Phase hidden by ZLP OUT sending quiclky,
- // - or ZLP OUT received normaly.
+ // - or ZLP OUT received normally.
udd_ctrl_endofrequest();
} else {
// Protocol error during SETUP request
@@ -1544,7 +1544,7 @@ static void udd_ctrl_out_received(void)
(udd_ctrl_prev_payload_buf_cnt +
udd_ctrl_payload_buf_cnt))) {
// End of reception because it is a short packet
- // Before send ZLP, call intermediat calback
+ // Before send ZLP, call intermediate callback
// in case of data receiv generate a stall
udd_g_ctrlreq.payload_size = udd_ctrl_payload_buf_cnt;
if (NULL != udd_g_ctrlreq.over_under_run) {
@@ -1565,7 +1565,7 @@ static void udd_ctrl_out_received(void)
if (udd_g_ctrlreq.payload_size == udd_ctrl_payload_buf_cnt) {
// Overrun then request a new payload buffer
if (!udd_g_ctrlreq.over_under_run) {
- // No callback availabled to request a new payload buffer
+ // No callback available to request a new payload buffer
udd_ctrl_stall_data();
// Ack reception of OUT to replace NAK by a STALL
udd_ack_out_received(0);
@@ -1805,7 +1805,7 @@ static void udd_ep_trans_done(udd_ep_id_t ep)
// transfer size of UDD_ENDPOINT_MAX_TRANS Bytes
next_trans = UDD_ENDPOINT_MAX_TRANS;
- // Set 0 to tranfer the maximum
+ // Set 0 to transfer the maximum
udd_dma_ctrl = UOTGHS_DEVDMACONTROL_BUFF_LENGTH(0);
} else {
udd_dma_ctrl = UOTGHS_DEVDMACONTROL_BUFF_LENGTH(next_trans);
@@ -1850,7 +1850,7 @@ static void udd_ep_trans_done(udd_ep_id_t ep)
}
cpu_irq_restore(flags);
- // Here a ZLP has been recieved
+ // Here a ZLP has been received
// and the DMA transfer must be not started.
// It is the end of transfer
ptr_job->buf_size = ptr_job->buf_cnt;
@@ -1991,13 +1991,13 @@ static bool udd_ep_interrupt(void)
}
dbg_print("dma%x: ", ep);
udd_disable_endpoint_dma_interrupt(ep);
- // Save number of data no transfered
+ // Save number of data no transferred
nb_remaining = (udd_endpoint_dma_get_status(ep) &
UOTGHS_DEVDMASTATUS_BUFF_COUNT_Msk)
>> UOTGHS_DEVDMASTATUS_BUFF_COUNT_Pos;
if (nb_remaining) {
// Transfer no complete (short packet or ZLP) then:
- // Update number of data transfered
+ // Update number of data transferred
ptr_job->buf_cnt -= nb_remaining;
// Set transfer complete to stop the transfer
ptr_job->buf_size = ptr_job->buf_cnt;
@@ -2056,7 +2056,7 @@ static bool udd_ep_interrupt(void)
udd_disable_endpoint_interrupt(ep);
Assert(ptr_job->stall_requested);
- // A stall has been requested during backgound transfer
+ // A stall has been requested during background transfer
ptr_job->stall_requested = false;
udd_disable_endpoint_bank_autoswitch(ep);
udd_enable_stall_handshake(ep);
diff --git a/Marlin/src/HAL/DUE/usb/usb_protocol_msc.h b/Marlin/src/HAL/DUE/usb/usb_protocol_msc.h
index 0fef30804662..e1e59237d823 100644
--- a/Marlin/src/HAL/DUE/usb/usb_protocol_msc.h
+++ b/Marlin/src/HAL/DUE/usb/usb_protocol_msc.h
@@ -130,7 +130,7 @@ struct usb_msc_cbw {
struct usb_msc_csw {
le32_t dCSWSignature; //!< Must contain 'USBS'
le32_t dCSWTag; //!< Same as dCBWTag
- le32_t dCSWDataResidue; //!< Number of bytes not transfered
+ le32_t dCSWDataResidue; //!< Number of bytes not transferred
uint8_t bCSWStatus; //!< Status code
};
diff --git a/Marlin/src/HAL/DUE/usb/usb_task.c b/Marlin/src/HAL/DUE/usb/usb_task.c
index 66bdb265d881..54a808d7f4f1 100644
--- a/Marlin/src/HAL/DUE/usb/usb_task.c
+++ b/Marlin/src/HAL/DUE/usb/usb_task.c
@@ -264,7 +264,7 @@ bool usb_task_extra_string(void) {
** Handle device requests that the ASF stack doesn't
*/
bool usb_task_other_requests(void) {
- uint8_t* ptr = 0;
+ uint8_t *ptr = 0;
uint16_t size = 0;
if (Udd_setup_type() == USB_REQ_TYPE_VENDOR) {
@@ -322,7 +322,7 @@ void usb_task_init(void) {
char *sptr;
// Patch in the filament diameter
- sprintf_P(diam, PSTR("%d"), (int)((DEFAULT_NOMINAL_FILAMENT_DIA) * 1000.0));
+ itoa((int)((DEFAULT_NOMINAL_FILAMENT_DIA) * 1000), diam, 10);
// And copy it to the proper place, expanding it to unicode
sptr = &diam[0];
diff --git a/Marlin/src/HAL/DUE/watchdog.cpp b/Marlin/src/HAL/DUE/watchdog.cpp
index 0f4697183056..e144db8291e3 100644
--- a/Marlin/src/HAL/DUE/watchdog.cpp
+++ b/Marlin/src/HAL/DUE/watchdog.cpp
@@ -36,7 +36,7 @@ void watchdogSetup() {
#if ENABLED(USE_WATCHDOG)
// 4 seconds timeout
- uint32_t timeout = 4000;
+ uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000);
// Calculate timeout value in WDT counter ticks: This assumes
// the slow clock is running at 32.768 kHz watchdog
diff --git a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp
index d4b2f42c5351..145662215a9b 100644
--- a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp
+++ b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.cpp
@@ -20,14 +20,10 @@
*
*/
-#include "FlushableHardwareSerial.h"
-
#ifdef ARDUINO_ARCH_ESP32
-FlushableHardwareSerial::FlushableHardwareSerial(int uart_nr)
- : HardwareSerial(uart_nr)
-{}
+#include "FlushableHardwareSerial.h"
-FlushableHardwareSerial flushableSerial(0);
+Serial1Class flushableSerial(false, 0);
-#endif // ARDUINO_ARCH_ESP32
+#endif
diff --git a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h
index b43caea13c1d..012dda8626b0 100644
--- a/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h
+++ b/Marlin/src/HAL/ESP32/FlushableHardwareSerial.h
@@ -21,17 +21,14 @@
*/
#pragma once
-#ifdef ARDUINO_ARCH_ESP32
-
#include
+#include "../shared/Marduino.h"
+#include "../../core/serial_hook.h"
+
class FlushableHardwareSerial : public HardwareSerial {
public:
- FlushableHardwareSerial(int uart_nr);
-
- inline void flushTX() { /* No need to flush the hardware serial, but defined here for compatibility. */ }
+ FlushableHardwareSerial(int uart_nr) : HardwareSerial(uart_nr) {}
};
-extern FlushableHardwareSerial flushableSerial;
-
-#endif // ARDUINO_ARCH_ESP32
+extern Serial1Class flushableSerial;
diff --git a/Marlin/src/HAL/ESP32/HAL.cpp b/Marlin/src/HAL/ESP32/HAL.cpp
index 1e00df5177ad..7818dbdd87ea 100644
--- a/Marlin/src/HAL/ESP32/HAL.cpp
+++ b/Marlin/src/HAL/ESP32/HAL.cpp
@@ -40,6 +40,10 @@
#endif
#endif
+#if ENABLED(ESP3D_WIFISUPPORT)
+ DefaultSerial1 MSerial0(false, Serial2Socket);
+#endif
+
// ------------------------
// Externs
// ------------------------
@@ -86,8 +90,6 @@ volatile int numPWMUsed = 0,
#endif
-void HAL_init() { i2s_init(); }
-
void HAL_init_board() {
#if ENABLED(ESP3D_WIFISUPPORT)
@@ -122,6 +124,10 @@ void HAL_init_board() {
#endif
#endif
+ // Initialize the i2s peripheral only if the I2S stepper stream is enabled.
+ // The following initialization is performed after Serial1 and Serial2 are defined as
+ // their native pins might conflict with the i2s stream even when they are remapped.
+ TERN_(I2S_STEPPER_STREAM, i2s_init());
}
void HAL_idletask() {
@@ -135,6 +141,8 @@ void HAL_clear_reset_source() { }
uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
+void HAL_reboot() { ESP.restart(); }
+
void _delay_ms(int delay_ms) { delay(delay_ms); }
// return free memory between end of heap (or end bss) and whatever is current
@@ -179,6 +187,7 @@ void HAL_adc_init() {
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
+ TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h
index ebc16c9525e7..0f920520306f 100644
--- a/Marlin/src/HAL/ESP32/HAL.h
+++ b/Marlin/src/HAL/ESP32/HAL.h
@@ -51,13 +51,15 @@
extern portMUX_TYPE spinlock;
-#define MYSERIAL0 flushableSerial
+#define MYSERIAL1 flushableSerial
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(ESP3D_WIFISUPPORT)
- #define MYSERIAL1 Serial2Socket
+ typedef ForwardSerial1Class< decltype(Serial2Socket) > DefaultSerial1;
+ extern DefaultSerial1 MSerial0;
+ #define MYSERIAL2 MSerial0
#else
- #define MYSERIAL1 webSocketSerial
+ #define MYSERIAL2 webSocketSerial
#endif
#endif
@@ -67,10 +69,6 @@ extern portMUX_TYPE spinlock;
#define ENABLE_ISRS() if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock)
#define DISABLE_ISRS() portENTER_CRITICAL(&spinlock)
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*(addr))
-
// ------------------------
// Types
// ------------------------
@@ -90,20 +88,33 @@ extern uint16_t HAL_adc_result;
// Public functions
// ------------------------
+//
+// Tone
+//
+void toneInit();
+void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
+void noTone(const pin_t _pin);
+
// clear reset reason
void HAL_clear_reset_source();
// reset reason
uint8_t HAL_get_reset_source();
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot();
void _delay_ms(int delay);
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
void analogWrite(pin_t pin, int value);
@@ -128,7 +139,7 @@ void HAL_adc_start_conversion(const uint8_t adc_pin);
#define HAL_IDLETASK 1
#define BOARD_INIT() HAL_init_board();
void HAL_idletask();
-void HAL_init();
+inline void HAL_init() {}
void HAL_init_board();
//
diff --git a/Marlin/src/HAL/ESP32/HAL_SPI.cpp b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
index 8e5875fc388d..8743ac5be215 100644
--- a/Marlin/src/HAL/ESP32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
@@ -53,11 +53,11 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
- #if !PIN_EXISTS(SS)
- #error "SS_PIN not defined!"
+ #if !PIN_EXISTS(SD_SS)
+ #error "SD_SS_PIN not defined!"
#endif
- OUT_WRITE(SS_PIN, HIGH);
+ OUT_WRITE(SD_SS_PIN, HIGH);
}
void spiInit(uint8_t spiRate) {
@@ -85,7 +85,7 @@ uint8_t spiRec() {
return returnByte;
}
-void spiRead(uint8_t* buf, uint16_t nbyte) {
+void spiRead(uint8_t *buf, uint16_t nbyte) {
SPI.beginTransaction(spiConfig);
SPI.transferBytes(0, buf, nbyte);
SPI.endTransaction();
@@ -97,7 +97,7 @@ void spiSend(uint8_t b) {
SPI.endTransaction();
}
-void spiSendBlock(uint8_t token, const uint8_t* buf) {
+void spiSendBlock(uint8_t token, const uint8_t *buf) {
SPI.beginTransaction(spiConfig);
SPI.transfer(token);
SPI.writeBytes(const_cast(buf), 512);
diff --git a/Marlin/src/HAL/ESP32/Servo.h b/Marlin/src/HAL/ESP32/Servo.h
index b0d929452732..8542092d66ea 100644
--- a/Marlin/src/HAL/ESP32/Servo.h
+++ b/Marlin/src/HAL/ESP32/Servo.h
@@ -30,7 +30,7 @@ class Servo {
MAX_PULSE_WIDTH = 2400, // Longest pulse sent to a servo
TAU_MSEC = 20,
TAU_USEC = (TAU_MSEC * 1000),
- MAX_COMPARE = ((1 << 16) - 1), // 65535
+ MAX_COMPARE = _BV(16) - 1, // 65535
CHANNEL_MAX_NUM = 16;
public:
diff --git a/Marlin/src/HAL/ESP32/Tone.cpp b/Marlin/src/HAL/ESP32/Tone.cpp
new file mode 100644
index 000000000000..376c0f32e129
--- /dev/null
+++ b/Marlin/src/HAL/ESP32/Tone.cpp
@@ -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
+ *
+ * Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
+ *
+ * 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 .
+ *
+ */
+
+/**
+ * Description: Tone function for ESP32
+ * Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
+ */
+
+#ifdef ARDUINO_ARCH_ESP32
+
+#include "../../inc/MarlinConfig.h"
+#include "HAL.h"
+
+static pin_t tone_pin;
+volatile static int32_t toggles;
+
+void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
+ tone_pin = _pin;
+ toggles = 2 * frequency * duration / 1000;
+ HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
+}
+
+void noTone(const pin_t _pin) {
+ HAL_timer_disable_interrupt(TONE_TIMER_NUM);
+ WRITE(_pin, LOW);
+}
+
+HAL_TONE_TIMER_ISR() {
+ HAL_timer_isr_prologue(TONE_TIMER_NUM);
+
+ if (toggles) {
+ toggles--;
+ TOGGLE(tone_pin);
+ }
+ else noTone(tone_pin); // turn off interrupt
+}
+
+#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
index ca7f47a1f8bd..eb5b9d60395a 100644
--- a/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
+++ b/Marlin/src/HAL/ESP32/WebSocketSerial.cpp
@@ -29,7 +29,7 @@
#include "wifi.h"
#include
-WebSocketSerial webSocketSerial;
+MSerialWebSocketT webSocketSerial(false);
AsyncWebSocket ws("/ws"); // TODO Move inside the class.
// RingBuffer impl
@@ -137,16 +137,12 @@ size_t WebSocketSerial::write(const uint8_t c) {
return ret;
}
-size_t WebSocketSerial::write(const uint8_t* buffer, size_t size) {
+size_t WebSocketSerial::write(const uint8_t *buffer, size_t size) {
size_t written = 0;
for (size_t i = 0; i < size; i++)
written += write(buffer[i]);
return written;
}
-void WebSocketSerial::flushTX() {
- // No need to do anything as there's no benefit to sending partial lines over the websocket connection.
-}
-
#endif // WIFISUPPORT
#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/WebSocketSerial.h b/Marlin/src/HAL/ESP32/WebSocketSerial.h
index 7a25c6dc5e9c..6b3e419d10c5 100644
--- a/Marlin/src/HAL/ESP32/WebSocketSerial.h
+++ b/Marlin/src/HAL/ESP32/WebSocketSerial.h
@@ -22,6 +22,7 @@
#pragma once
#include "../../inc/MarlinConfig.h"
+#include "../../core/serial_hook.h"
#include
@@ -53,7 +54,7 @@ class RingBuffer {
ring_buffer_pos_t read(uint8_t *buffer);
void flush();
ring_buffer_pos_t write(const uint8_t c);
- ring_buffer_pos_t write(const uint8_t* buffer, ring_buffer_pos_t size);
+ ring_buffer_pos_t write(const uint8_t *buffer, ring_buffer_pos_t size);
};
class WebSocketSerial: public Stream {
@@ -68,11 +69,8 @@ class WebSocketSerial: public Stream {
int peek();
int read();
void flush();
- void flushTX();
size_t write(const uint8_t c);
- size_t write(const uint8_t* buffer, size_t size);
-
- operator bool() { return true; }
+ size_t write(const uint8_t *buffer, size_t size);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE uint32_t dropped() { return 0; }
@@ -83,4 +81,5 @@ class WebSocketSerial: public Stream {
#endif
};
-extern WebSocketSerial webSocketSerial;
+typedef Serial1Class MSerialWebSocketT;
+extern MSerialWebSocketT webSocketSerial;
diff --git a/Marlin/src/HAL/ESP32/eeprom.cpp b/Marlin/src/HAL/ESP32/eeprom.cpp
index 1bf687c6fe09..cb5f881284ec 100644
--- a/Marlin/src/HAL/ESP32/eeprom.cpp
+++ b/Marlin/src/HAL/ESP32/eeprom.cpp
@@ -44,7 +44,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
for (size_t i = 0; i < size; i++) {
uint8_t c = EEPROM.read(pos++);
if (writing) value[i] = c;
diff --git a/Marlin/src/HAL/ESP32/endstop_interrupts.h b/Marlin/src/HAL/ESP32/endstop_interrupts.h
index 743ccd99c904..4725df921b1a 100644
--- a/Marlin/src/HAL/ESP32/endstop_interrupts.h
+++ b/Marlin/src/HAL/ESP32/endstop_interrupts.h
@@ -59,4 +59,10 @@ void setup_endstop_interrupts() {
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
+ TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
+ TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
+ TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
+ TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
+ TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
+ TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
}
diff --git a/Marlin/src/HAL/ESP32/fastio.h b/Marlin/src/HAL/ESP32/fastio.h
index 2ded3a5f62e8..8db89dca12a1 100644
--- a/Marlin/src/HAL/ESP32/fastio.h
+++ b/Marlin/src/HAL/ESP32/fastio.h
@@ -52,6 +52,9 @@
// 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 (substitution)
+#define SET_INPUT_PULLDOWN SET_INPUT
+
// Set pin as output wrapper
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0)
diff --git a/Marlin/src/HAL/ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp
index 99b2f755e578..c28c00879390 100644
--- a/Marlin/src/HAL/ESP32/i2s.cpp
+++ b/Marlin/src/HAL/ESP32/i2s.cpp
@@ -139,7 +139,7 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) {
I2S0.int_clr.val = I2S0.int_st.val; //clear pending interrupt
}
-void stepperTask(void* parameter) {
+void stepperTask(void *parameter) {
uint32_t remaining = 0;
while (1) {
@@ -184,7 +184,7 @@ int i2s_init() {
// Allocate the array of pointers to the buffers
dma.buffers = (uint32_t **)malloc(sizeof(uint32_t*) * DMA_BUF_COUNT);
- if (dma.buffers == nullptr) return -1;
+ if (!dma.buffers) return -1;
// Allocate each buffer that can be used by the DMA controller
for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) {
@@ -194,7 +194,7 @@ int i2s_init() {
// Allocate the array of DMA descriptors
dma.desc = (lldesc_t**) malloc(sizeof(lldesc_t*) * DMA_BUF_COUNT);
- if (dma.desc == nullptr) return -1;
+ if (!dma.desc) return -1;
// Allocate each DMA descriptor that will be used by the DMA controller
for (int buf_idx = 0; buf_idx < DMA_BUF_COUNT; buf_idx++) {
diff --git a/Marlin/src/HAL/ESP32/inc/SanityCheck.h b/Marlin/src/HAL/ESP32/inc/SanityCheck.h
index f57a6c591028..8bbc68d8715b 100644
--- a/Marlin/src/HAL/ESP32/inc/SanityCheck.h
+++ b/Marlin/src/HAL/ESP32/inc/SanityCheck.h
@@ -30,9 +30,13 @@
#endif
#if HAS_TMC_SW_SERIAL
- #error "TMC220x Software Serial is not supported on this platform."
+ #error "TMC220x Software Serial is not supported on ESP32."
#endif
#if BOTH(WIFISUPPORT, ESP3D_WIFISUPPORT)
#error "Only enable one WiFi option, either WIFISUPPORT or ESP3D_WIFISUPPORT."
#endif
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+ #error "POSTMORTEM_DEBUGGING is not yet supported on ESP32."
+#endif
diff --git a/Marlin/src/HAL/ESP32/spi_pins.h b/Marlin/src/HAL/ESP32/spi_pins.h
index 15f8f2ab6b07..cfe71eee4a75 100644
--- a/Marlin/src/HAL/ESP32/spi_pins.h
+++ b/Marlin/src/HAL/ESP32/spi_pins.h
@@ -18,7 +18,7 @@
*/
#pragma once
-#define SS_PIN SDSS
-#define SCK_PIN 18
-#define MISO_PIN 19
-#define MOSI_PIN 23
+#define SD_SS_PIN SDSS
+#define SD_SCK_PIN 18
+#define SD_MISO_PIN 19
+#define SD_MOSI_PIN 23
diff --git a/Marlin/src/HAL/ESP32/timers.cpp b/Marlin/src/HAL/ESP32/timers.cpp
index 3300aea8a89c..57662a665882 100644
--- a/Marlin/src/HAL/ESP32/timers.cpp
+++ b/Marlin/src/HAL/ESP32/timers.cpp
@@ -45,7 +45,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
{ TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
{ TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM
- { TIMER_GROUP_1, TIMER_1, 1, nullptr }, // 3
+ { TIMER_GROUP_1, TIMER_1, TONE_TIMER_PRESCALE, toneTC_Handler }, // 3 - Tone
};
// ------------------------
diff --git a/Marlin/src/HAL/ESP32/timers.h b/Marlin/src/HAL/ESP32/timers.h
index d722670f33cf..a47697113d5d 100644
--- a/Marlin/src/HAL/ESP32/timers.h
+++ b/Marlin/src/HAL/ESP32/timers.h
@@ -24,15 +24,9 @@
#include
#include
-// Includes needed to get I2S_STEPPER_STREAM. Note that pins.h
-// is included in case this header is being included early.
-#include "../../inc/MarlinConfig.h"
-#include "../../pins/pins.h"
-
// ------------------------
// Defines
// ------------------------
-//
#define FORCE_INLINE __attribute__((always_inline)) inline
typedef uint64_t hal_timer_t;
@@ -50,6 +44,9 @@ typedef uint64_t hal_timer_t;
#ifndef PWM_TIMER_NUM
#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs
#endif
+#ifndef TONE_TIMER_NUM
+ #define TONE_TIMER_NUM 3 // index of timer for beeper tones
+#endif
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
@@ -65,6 +62,8 @@ typedef uint64_t hal_timer_t;
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
+#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here
+
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
@@ -96,10 +95,16 @@ typedef uint64_t hal_timer_t;
#ifndef HAL_PWM_TIMER_ISR
#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler()
#endif
+#ifndef HAL_TONE_TIMER_ISR
+ #define HAL_TONE_TIMER_ISR() extern "C" void toneTC_Handler()
+#endif
-extern "C" void tempTC_Handler();
-extern "C" void stepTC_Handler();
-extern "C" void pwmTC_Handler();
+extern "C" {
+ void tempTC_Handler();
+ void stepTC_Handler();
+ void pwmTC_Handler();
+ void toneTC_Handler();
+}
// ------------------------
// Types
diff --git a/Marlin/src/HAL/ESP32/watchdog.cpp b/Marlin/src/HAL/ESP32/watchdog.cpp
index f6fcfa3182c4..5ec03c46079b 100644
--- a/Marlin/src/HAL/ESP32/watchdog.cpp
+++ b/Marlin/src/HAL/ESP32/watchdog.cpp
@@ -25,6 +25,8 @@
#if ENABLED(USE_WATCHDOG)
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
+
#include "watchdog.h"
void watchdogSetup() {
diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h
index 5eca2f7eacfe..0cd836af2b68 100644
--- a/Marlin/src/HAL/HAL.h
+++ b/Marlin/src/HAL/HAL.h
@@ -23,14 +23,12 @@
#include "platforms.h"
-#include HAL_PATH(.,HAL.h)
-
-#ifdef SERIAL_PORT_2
- #define NUM_SERIAL 2
-#else
- #define NUM_SERIAL 1
+#ifndef GCC_VERSION
+ #define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
+#include HAL_PATH(.,HAL.h)
+
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS
diff --git a/Marlin/src/HAL/LINUX/HAL.cpp b/Marlin/src/HAL/LINUX/HAL.cpp
index d7d7c2d2b4f0..0b679170ef17 100644
--- a/Marlin/src/HAL/LINUX/HAL.cpp
+++ b/Marlin/src/HAL/LINUX/HAL.cpp
@@ -24,21 +24,16 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
-HalSerial usb_serial;
+MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true));
// U8glib required functions
-extern "C" void u8g_xMicroDelay(uint16_t val) {
- DELAY_US(val);
-}
-extern "C" void u8g_MicroDelay() {
- u8g_xMicroDelay(1);
-}
-extern "C" void u8g_10MicroDelay() {
- u8g_xMicroDelay(10);
-}
-extern "C" void u8g_Delay(uint16_t val) {
- delay(val);
+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
@@ -78,4 +73,6 @@ void HAL_pwm_init() {
}
+void HAL_reboot() { /* Reset the application state and GPIO */ }
+
#endif // __PLAT_LINUX__
diff --git a/Marlin/src/HAL/LINUX/HAL.h b/Marlin/src/HAL/LINUX/HAL.h
index 2e545e03d6f3..36906bffc869 100644
--- a/Marlin/src/HAL/LINUX/HAL.h
+++ b/Marlin/src/HAL/LINUX/HAL.h
@@ -23,7 +23,7 @@
#define CPU_32_BIT
-#define F_CPU 100000000
+#define F_CPU 100000000UL
#define SystemCoreClock F_CPU
#include
#include
@@ -60,8 +60,8 @@ uint8_t _getc();
#define SHARED_SERVOS HAS_SERVOS
-extern HalSerial usb_serial;
-#define MYSERIAL0 usb_serial
+extern MSerialT usb_serial;
+#define MYSERIAL1 usb_serial
#define ST7920_DELAY_1 DELAY_NS(600)
#define ST7920_DELAY_2 DELAY_NS(750)
@@ -79,10 +79,16 @@ extern HalSerial usb_serial;
inline void HAL_init() {}
// Utility functions
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
// ADC
#define HAL_ADC_VREF 5.0
@@ -101,14 +107,9 @@ uint16_t HAL_adc_get_result();
inline void HAL_clear_reset_source(void) {}
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot(); // Reset the application state and GPIO
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
Clock::delayCycles(x);
}
-
-// Add strcmp_P if missing
-#ifndef strcmp_P
- #define strcmp_P(a, b) strcmp((a), (b))
-#endif
diff --git a/Marlin/src/HAL/LINUX/eeprom.cpp b/Marlin/src/HAL/LINUX/eeprom.cpp
index 967ca851abc1..532f323c6edb 100644
--- a/Marlin/src/HAL/LINUX/eeprom.cpp
+++ b/Marlin/src/HAL/LINUX/eeprom.cpp
@@ -40,7 +40,7 @@ size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_start() {
const char eeprom_erase_value = 0xFF;
FILE * eeprom_file = fopen(filename, "rb");
- if (eeprom_file == nullptr) return false;
+ if (!eeprom_file) return false;
fseek(eeprom_file, 0L, SEEK_END);
std::size_t file_size = ftell(eeprom_file);
@@ -59,7 +59,7 @@ bool PersistentStore::access_start() {
bool PersistentStore::access_finish() {
FILE * eeprom_file = fopen(filename, "wb");
- if (eeprom_file == nullptr) return false;
+ if (!eeprom_file) return false;
fwrite(buffer, sizeof(uint8_t), sizeof(buffer), eeprom_file);
fclose(eeprom_file);
return true;
@@ -78,7 +78,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return (bytes_written != size); // return true for any error
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
std::size_t bytes_read = 0;
if (writing) {
for (std::size_t i = 0; i < size; i++) {
diff --git a/Marlin/src/HAL/LINUX/hardware/Gpio.h b/Marlin/src/HAL/LINUX/hardware/Gpio.h
index 9255ec1dfc91..f946be648466 100644
--- a/Marlin/src/HAL/LINUX/hardware/Gpio.h
+++ b/Marlin/src/HAL/LINUX/hardware/Gpio.h
@@ -40,7 +40,7 @@ struct GpioEvent {
pin_type pin_id;
GpioEvent::Type event;
- GpioEvent(uint64_t timestamp, pin_type pin_id, GpioEvent::Type event){
+ GpioEvent(uint64_t timestamp, pin_type pin_id, GpioEvent::Type event) {
this->timestamp = timestamp;
this->pin_id = pin_id;
this->event = event;
@@ -86,10 +86,10 @@ class Gpio {
GpioEvent::Type evt_type = value > 1 ? GpioEvent::SET_VALUE : value > pin_map[pin].value ? GpioEvent::RISE : value < pin_map[pin].value ? GpioEvent::FALL : GpioEvent::NOP;
pin_map[pin].value = value;
GpioEvent evt(Clock::nanos(), pin, evt_type);
- if (pin_map[pin].cb != nullptr) {
+ if (pin_map[pin].cb) {
pin_map[pin].cb->interrupt(evt);
}
- if (Gpio::logger != nullptr) Gpio::logger->log(evt);
+ if (Gpio::logger) Gpio::logger->log(evt);
}
static uint16_t get(pin_type pin) {
@@ -105,8 +105,8 @@ class Gpio {
if (!valid_pin(pin)) return;
pin_map[pin].mode = value;
GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETM);
- if (pin_map[pin].cb != nullptr) pin_map[pin].cb->interrupt(evt);
- if (Gpio::logger != nullptr) Gpio::logger->log(evt);
+ if (pin_map[pin].cb) pin_map[pin].cb->interrupt(evt);
+ if (Gpio::logger) Gpio::logger->log(evt);
}
static uint8_t getMode(pin_type pin) {
@@ -118,8 +118,8 @@ class Gpio {
if (!valid_pin(pin)) return;
pin_map[pin].dir = value;
GpioEvent evt(Clock::nanos(), pin, GpioEvent::Type::SETD);
- if (pin_map[pin].cb != nullptr) pin_map[pin].cb->interrupt(evt);
- if (Gpio::logger != nullptr) Gpio::logger->log(evt);
+ if (pin_map[pin].cb) pin_map[pin].cb->interrupt(evt);
+ if (Gpio::logger) Gpio::logger->log(evt);
}
static uint8_t getDir(pin_type pin) {
diff --git a/Marlin/src/HAL/LINUX/hardware/Heater.cpp b/Marlin/src/HAL/LINUX/hardware/Heater.cpp
index 70df8161829a..44f11986c98b 100644
--- a/Marlin/src/HAL/LINUX/hardware/Heater.cpp
+++ b/Marlin/src/HAL/LINUX/hardware/Heater.cpp
@@ -54,7 +54,7 @@ void Heater::update() {
}
void Heater::interrupt(GpioEvent ev) {
- // ununsed
+ // unused
}
#endif // __PLAT_LINUX__
diff --git a/Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp b/Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp
index c5b3ccc98656..e122ef3666c5 100644
--- a/Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp
+++ b/Marlin/src/HAL/LINUX/hardware/LinearAxis.cpp
@@ -51,7 +51,7 @@ void LinearAxis::update() {
}
void LinearAxis::interrupt(GpioEvent ev) {
- if (ev.pin_id == step_pin && !Gpio::pin_map[enable_pin].value){
+ if (ev.pin_id == step_pin && !Gpio::pin_map[enable_pin].value) {
if (ev.event == GpioEvent::RISE) {
last_update = ev.timestamp;
position += -1 + 2 * Gpio::pin_map[dir_pin].value;
diff --git a/Marlin/src/HAL/LINUX/hardware/Timer.h b/Marlin/src/HAL/LINUX/hardware/Timer.h
index 757efdcdbd7e..1b3b800dca3d 100644
--- a/Marlin/src/HAL/LINUX/hardware/Timer.h
+++ b/Marlin/src/HAL/LINUX/hardware/Timer.h
@@ -52,7 +52,7 @@ class Timer {
return (*(intptr_t*)timerid);
}
- static void handler(int sig, siginfo_t *si, void *uc){
+ static void handler(int sig, siginfo_t *si, void *uc) {
Timer* _this = (Timer*)si->si_value.sival_ptr;
_this->avg_error += (Clock::nanos() - _this->start_time) - _this->period; //high_resolution_clock is also limited in precision, but best we have
_this->avg_error /= 2; //very crude precision analysis (actually within +-500ns usually)
diff --git a/Marlin/src/HAL/LINUX/inc/SanityCheck.h b/Marlin/src/HAL/LINUX/inc/SanityCheck.h
index 84167c97a144..45bb2662ace5 100644
--- a/Marlin/src/HAL/LINUX/inc/SanityCheck.h
+++ b/Marlin/src/HAL/LINUX/inc/SanityCheck.h
@@ -35,5 +35,9 @@
#endif
#if HAS_TMC_SW_SERIAL
- #error "TMC220x Software Serial is not supported on this platform."
+ #error "TMC220x Software Serial is not supported on LINUX."
+#endif
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+ #error "POSTMORTEM_DEBUGGING is not yet supported on LINUX."
#endif
diff --git a/Marlin/src/HAL/LINUX/include/Arduino.h b/Marlin/src/HAL/LINUX/include/Arduino.h
index e28b474ede96..d4086e259a2f 100644
--- a/Marlin/src/HAL/LINUX/include/Arduino.h
+++ b/Marlin/src/HAL/LINUX/include/Arduino.h
@@ -67,34 +67,14 @@ void cli(); // Disable
void sei(); // Enable
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
void detachInterrupt(uint32_t pin);
-extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
-extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
-
-// Program Memory
-#define pgm_read_ptr(addr) (*((void**)(addr)))
-#define pgm_read_byte_near(addr) (*((uint8_t*)(addr)))
-#define pgm_read_float_near(addr) (*((float*)(addr)))
-#define pgm_read_word_near(addr) (*((uint16_t*)(addr)))
-#define pgm_read_dword_near(addr) (*((uint32_t*)(addr)))
-#define pgm_read_byte(addr) pgm_read_byte_near(addr)
-#define pgm_read_float(addr) pgm_read_float_near(addr)
-#define pgm_read_word(addr) pgm_read_word_near(addr)
-#define pgm_read_dword(addr) pgm_read_dword_near(addr)
-
-using std::memcpy;
-#define memcpy_P memcpy
-#define sprintf_P sprintf
-#define strstr_P strstr
-#define strncpy_P strncpy
-#define vsnprintf_P vsnprintf
-#define strcpy_P strcpy
-#define snprintf_P snprintf
-#define strlen_P strlen
-// Time functions
extern "C" {
- void delay(const int milis);
+ void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
+ void GpioDisableInt(uint32_t port, uint32_t pin);
}
+
+// Time functions
+extern "C" void delay(const int milis);
void _delay_ms(const int delay);
void delayMicroseconds(unsigned long);
uint32_t millis();
diff --git a/Marlin/src/HAL/LINUX/include/pinmapping.cpp b/Marlin/src/HAL/LINUX/include/pinmapping.cpp
index 870ab3a96e5f..5823668cd50d 100644
--- a/Marlin/src/HAL/LINUX/include/pinmapping.cpp
+++ b/Marlin/src/HAL/LINUX/include/pinmapping.cpp
@@ -25,43 +25,6 @@
#include "../../../gcode/parser.h"
-uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
-
-// Get the digital pin for an analog index
-pin_t analogInputToDigitalPin(const int8_t p) {
- return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
-}
-
-// Return the index of a pin number
-int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
- return pin;
-}
-
-// Test whether the pin is valid
-bool VALID_PIN(const pin_t p) {
- return WITHIN(p, 0, NUM_DIGITAL_PINS);
-}
-
-// Get the analog index for a digital pin
-int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
- return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
-}
-
-// Test whether the pin is PWM
-bool PWM_PIN(const pin_t p) {
- return false;
-}
-
-// Test whether the pin is interruptable
-bool INTERRUPT_PIN(const pin_t p) {
- return false;
-}
-
-// Get the pin number at the given index
-pin_t GET_PIN_MAP_PIN(const int16_t ind) {
- return ind;
-}
-
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
return parser.intval(code, dval);
}
diff --git a/Marlin/src/HAL/LINUX/include/pinmapping.h b/Marlin/src/HAL/LINUX/include/pinmapping.h
index 98f4b812e873..cfac5e3b48e4 100644
--- a/Marlin/src/HAL/LINUX/include/pinmapping.h
+++ b/Marlin/src/HAL/LINUX/include/pinmapping.h
@@ -34,26 +34,32 @@ constexpr uint8_t NUM_ANALOG_INPUTS = 16;
#define HAL_SENSITIVE_PINS
+constexpr uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
+
// Get the digital pin for an analog index
-pin_t analogInputToDigitalPin(const int8_t p);
+constexpr pin_t analogInputToDigitalPin(const int8_t p) {
+ return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
+}
+
+// Get the analog index for a digital pin
+constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
+ return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
+}
// Return the index of a pin number
-int16_t GET_PIN_MAP_INDEX(const pin_t pin);
+constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { return pin; }
// Test whether the pin is valid
-bool VALID_PIN(const pin_t p);
-
-// Get the analog index for a digital pin
-int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p);
+constexpr bool VALID_PIN(const pin_t p) { return WITHIN(p, 0, NUM_DIGITAL_PINS); }
// Test whether the pin is PWM
-bool PWM_PIN(const pin_t p);
+constexpr bool PWM_PIN(const pin_t p) { return false; }
-// Test whether the pin is interruptable
-bool INTERRUPT_PIN(const pin_t p);
+// Test whether the pin is interruptible
+constexpr bool INTERRUPT_PIN(const pin_t p) { return false; }
// Get the pin number at the given index
-pin_t GET_PIN_MAP_PIN(const int16_t ind);
+constexpr pin_t GET_PIN_MAP_PIN(const int16_t ind) { return ind; }
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
diff --git a/Marlin/src/HAL/LINUX/include/serial.h b/Marlin/src/HAL/LINUX/include/serial.h
index e91624938978..ebae066c3a57 100644
--- a/Marlin/src/HAL/LINUX/include/serial.h
+++ b/Marlin/src/HAL/LINUX/include/serial.h
@@ -25,6 +25,7 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../../feature/e_parser.h"
#endif
+#include "../../../core/serial_hook.h"
#include
#include
@@ -73,19 +74,11 @@ template class RingBuffer {
volatile uint32_t index_read;
};
-class HalSerial {
-public:
-
- #if ENABLED(EMERGENCY_PARSER)
- EmergencyParser::State emergency_state;
- static inline bool emergency_parser_enabled() { return true; }
- #endif
-
+struct HalSerial {
HalSerial() { host_connected = true; }
void begin(int32_t) {}
-
- void end() {}
+ void end() {}
int peek() {
uint8_t value;
@@ -100,7 +93,7 @@ class HalSerial {
return transmit_buffer.write(c);
}
- operator bool() { return host_connected; }
+ bool connected() { return host_connected; }
uint16_t available() {
return (uint16_t)receive_buffer.available();
@@ -117,92 +110,9 @@ class HalSerial {
while (transmit_buffer.available()) { /* nada */ }
}
- void printf(const char *format, ...) {
- static char buffer[256];
- va_list vArgs;
- va_start(vArgs, format);
- int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
- va_end(vArgs);
- if (length > 0 && length < 256) {
- if (host_connected) {
- for (int i = 0; i < length;) {
- if (transmit_buffer.write(buffer[i])) {
- ++i;
- }
- }
- }
- }
- }
-
- #define DEC 10
- #define HEX 16
- #define OCT 8
- #define BIN 2
-
- void print_bin(uint32_t value, uint8_t num_digits) {
- uint32_t mask = 1 << (num_digits -1);
- for (uint8_t i = 0; i < num_digits; i++) {
- if (!(i % 4) && i) write(' ');
- if (!(i % 16) && i) write(' ');
- if (value & mask) write('1');
- else write('0');
- value <<= 1;
- }
- }
-
- void print(const char value[]) { printf("%s" , value); }
- void print(char value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 8);
- else if (nbase == OCT) printf("%3o", value);
- else if (nbase == HEX) printf("%2X", value);
- else if (nbase == DEC ) printf("%d", value);
- else printf("%c" , value);
- }
- void print(unsigned char value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 8);
- else if (nbase == OCT) printf("%3o", value);
- else if (nbase == HEX) printf("%2X", value);
- else printf("%u" , value);
- }
- void print(int value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 16);
- else if (nbase == OCT) printf("%6o", value);
- else if (nbase == HEX) printf("%4X", value);
- else printf("%d", value);
- }
- void print(unsigned int value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 16);
- else if (nbase == OCT) printf("%6o", value);
- else if (nbase == HEX) printf("%4X", value);
- else printf("%u" , value);
- }
- void print(long value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 32);
- else if (nbase == OCT) printf("%11o", value);
- else if (nbase == HEX) printf("%8X", value);
- else printf("%ld" , value);
- }
- void print(unsigned long value, int nbase = 0) {
- if (nbase == BIN) print_bin(value, 32);
- else if (nbase == OCT) printf("%11o", value);
- else if (nbase == HEX) printf("%8X", value);
- else printf("%lu" , value);
- }
- void print(float value, int round = 6) { printf("%f" , value); }
- void print(double value, int round = 6) { printf("%f" , value); }
-
- void println(const char value[]) { printf("%s\n" , value); }
- void println(char value, int nbase = 0) { print(value, nbase); println(); }
- void println(unsigned char value, int nbase = 0) { print(value, nbase); println(); }
- void println(int value, int nbase = 0) { print(value, nbase); println(); }
- void println(unsigned int value, int nbase = 0) { print(value, nbase); println(); }
- void println(long value, int nbase = 0) { print(value, nbase); println(); }
- void println(unsigned long value, int nbase = 0) { print(value, nbase); println(); }
- void println(float value, int round = 6) { printf("%f\n" , value); }
- void println(double value, int round = 6) { printf("%f\n" , value); }
- void println() { print('\n'); }
-
volatile RingBuffer receive_buffer;
volatile RingBuffer transmit_buffer;
volatile bool host_connected;
};
+
+typedef Serial1Class MSerialT;
diff --git a/Marlin/src/HAL/LINUX/main.cpp b/Marlin/src/HAL/LINUX/main.cpp
index 481f059030b7..31f6de98ee8e 100644
--- a/Marlin/src/HAL/LINUX/main.cpp
+++ b/Marlin/src/HAL/LINUX/main.cpp
@@ -1,6 +1,5 @@
/**
* Marlin 3D Printer Firmware
- *
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* This program is free software: you can redistribute it and/or modify
@@ -19,22 +18,23 @@
*/
#ifdef __PLAT_LINUX__
-extern void setup();
-extern void loop();
-
-#include
-
-#include
-#include
+//#define GPIO_LOGGING // Full GPIO and Positional Logging
#include "../../inc/MarlinConfig.h"
-#include
-#include
#include "../shared/Delay.h"
#include "hardware/IOLoggerCSV.h"
#include "hardware/Heater.h"
#include "hardware/LinearAxis.h"
+#include
+#include
+#include
+#include
+#include
+
+extern void setup();
+extern void loop();
+
// simple stdout / stdin implementation for fake serial port
void write_serial_thread() {
for (;;) {
@@ -64,8 +64,6 @@ void simulation_loop() {
LinearAxis z_axis(Z_ENABLE_PIN, Z_DIR_PIN, Z_STEP_PIN, Z_MIN_PIN, Z_MAX_PIN);
LinearAxis extruder0(E0_ENABLE_PIN, E0_DIR_PIN, E0_STEP_PIN, P_NC, P_NC);
- //#define GPIO_LOGGING // Full GPIO and Positional Logging
-
#ifdef GPIO_LOGGING
IOLoggerCSV logger("all_gpio_log.csv");
Gpio::attachLogger(&logger);
@@ -88,7 +86,7 @@ void simulation_loop() {
#ifdef GPIO_LOGGING
if (x_axis.position != x || y_axis.position != y || z_axis.position != z) {
- uint64_t update = MAX3(x_axis.last_update, y_axis.last_update, z_axis.last_update);
+ uint64_t update = _MAX(x_axis.last_update, y_axis.last_update, z_axis.last_update);
position_log << update << ", " << x_axis.position << ", " << y_axis.position << ", " << z_axis.position << std::endl;
position_log.flush();
x = x_axis.position;
@@ -107,8 +105,8 @@ int main() {
std::thread write_serial (write_serial_thread);
std::thread read_serial (read_serial_thread);
- #ifdef MYSERIAL0
- MYSERIAL0.begin(BAUDRATE);
+ #ifdef MYSERIAL1
+ MYSERIAL1.begin(BAUDRATE);
SERIAL_ECHOLNPGM("x86_64 Initialized");
SERIAL_FLUSHTX();
#endif
diff --git a/Marlin/src/HAL/LINUX/pinsDebug.h b/Marlin/src/HAL/LINUX/pinsDebug.h
index a93ceddc61c3..8f8543ef5984 100644
--- a/Marlin/src/HAL/LINUX/pinsDebug.h
+++ b/Marlin/src/HAL/LINUX/pinsDebug.h
@@ -26,15 +26,15 @@
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
-#define pwm_details(pin) pin = pin // do nothing // print PWM details
-#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin.
-#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
+#define pwm_details(pin) NOOP // (do nothing)
+#define pwm_status(pin) false // Print a pin's PWM status. Return true if it's currently a PWM pin.
+#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
#define digitalRead_mod(p) digitalRead(p)
#define PRINT_PORT(p)
-#define GET_ARRAY_PIN(p) pin_array[p].pin
+#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("%3d "), p); SERIAL_ECHO(buffer); }while(0)
-#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
+#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
+#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
// active ADC function/mode/code values for PINSEL registers
constexpr int8_t ADC_pin_mode(pin_t pin) {
diff --git a/Marlin/src/HAL/LINUX/spi_pins.h b/Marlin/src/HAL/LINUX/spi_pins.h
index 01ba28e5b604..33136ac9dd80 100644
--- a/Marlin/src/HAL/LINUX/spi_pins.h
+++ b/Marlin/src/HAL/LINUX/spi_pins.h
@@ -24,31 +24,32 @@
#include "../../core/macros.h"
#include "../../inc/MarlinConfigPre.h"
-#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
+#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (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 SCK_PIN P0_07
-//#define MISO_PIN P0_08
-//#define MOSI_PIN P0_09
-//#define SS_PIN P0_06
-/** external */
-#ifndef SCK_PIN
- #define SCK_PIN 50
+// Onboard SD
+//#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 SD
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 50
#endif
-#ifndef MISO_PIN
- #define MISO_PIN 51
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 51
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN 52
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 52
#endif
-#ifndef SS_PIN
- #define SS_PIN 53
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN 53
#endif
#ifndef SDSS
- #define SDSS SS_PIN
+ #define SDSS SD_SS_PIN
#endif
diff --git a/Marlin/src/HAL/LINUX/watchdog.cpp b/Marlin/src/HAL/LINUX/watchdog.cpp
index c15b0e311c56..84202e48b6c5 100644
--- a/Marlin/src/HAL/LINUX/watchdog.cpp
+++ b/Marlin/src/HAL/LINUX/watchdog.cpp
@@ -27,6 +27,8 @@
#include "watchdog.h"
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
+
void watchdog_init() {}
void HAL_watchdog_refresh() {}
diff --git a/Marlin/src/HAL/LINUX/watchdog.h b/Marlin/src/HAL/LINUX/watchdog.h
index 472624cc7845..49a0d9c631d8 100644
--- a/Marlin/src/HAL/LINUX/watchdog.h
+++ b/Marlin/src/HAL/LINUX/watchdog.h
@@ -21,7 +21,5 @@
*/
#pragma once
-#define WDT_TIMEOUT 4000000 // 4 second timeout
-
void watchdog_init();
void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/LPC1768/DebugMonitor.cpp b/Marlin/src/HAL/LPC1768/DebugMonitor.cpp
deleted file mode 100644
index 783b10cfac16..000000000000
--- a/Marlin/src/HAL/LPC1768/DebugMonitor.cpp
+++ /dev/null
@@ -1,322 +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 .
- *
- */
-#ifdef TARGET_LPC1768
-
-#include "../../core/macros.h"
-#include "../../core/serial.h"
-#include
-
-#include "../shared/backtrace/unwinder.h"
-#include "../shared/backtrace/unwmemaccess.h"
-#include "watchdog.h"
-#include
-
-
-// Debug monitor that dumps to the Programming port all status when
-// an exception or WDT timeout happens - And then resets the board
-
-// All the Monitor routines must run with interrupts disabled and
-// under an ISR execution context. That is why we cannot reuse the
-// Serial interrupt routines or any C runtime, as we don't know the
-// state we are when running them
-
-// A SW memory barrier, to ensure GCC does not overoptimize loops
-#define sw_barrier() __asm__ volatile("": : :"memory");
-
-// (re)initialize UART0 as a monitor output to 250000,n,8,1
-static void TXBegin() {
-}
-
-// Send character through UART with no interrupts
-static void TX(char c) {
- _DBC(c);
-}
-
-// Send String through UART
-static void TX(const char* s) {
- while (*s) TX(*s++);
-}
-
-static void TXDigit(uint32_t d) {
- if (d < 10) TX((char)(d+'0'));
- else if (d < 16) TX((char)(d+'A'-10));
- else TX('?');
-}
-
-// Send Hex number thru UART
-static void TXHex(uint32_t v) {
- TX("0x");
- for (uint8_t i = 0; i < 8; i++, v <<= 4)
- TXDigit((v >> 28) & 0xF);
-}
-
-// Send Decimal number thru UART
-static void TXDec(uint32_t v) {
- if (!v) {
- TX('0');
- return;
- }
-
- char nbrs[14];
- char *p = &nbrs[0];
- while (v != 0) {
- *p++ = '0' + (v % 10);
- v /= 10;
- }
- do {
- p--;
- TX(*p);
- } while (p != &nbrs[0]);
-}
-
-// Dump a backtrace entry
-static bool UnwReportOut(void* ctx, const UnwReport* bte) {
- int* p = (int*)ctx;
-
- (*p)++;
- TX('#'); TXDec(*p); TX(" : ");
- TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
- TX('+'); TXDec(bte->address - bte->function);
- TX(" PC:");TXHex(bte->address); TX('\n');
- return true;
-}
-
-#ifdef UNW_DEBUG
- void UnwPrintf(const char* format, ...) {
- char dest[256];
- va_list argptr;
- va_start(argptr, format);
- vsprintf(dest, format, argptr);
- va_end(argptr);
- TX(&dest[0]);
- }
-#endif
-
-/* Table of function pointers for passing to the unwinder */
-static const UnwindCallbacks UnwCallbacks = {
- UnwReportOut,
- UnwReadW,
- UnwReadH,
- UnwReadB
- #ifdef UNW_DEBUG
- ,UnwPrintf
- #endif
-};
-
-
-/**
- * HardFaultHandler_C:
- * This is called from the HardFault_HandlerAsm with a pointer the Fault stack
- * as the parameter. We can then read the values from the stack and place them
- * into local variables for ease of reading.
- * We then read the various Fault Status and Address Registers to help decode
- * cause of the fault.
- * The function ends with a BKPT instruction to force control back into the debugger
- */
-extern "C"
-void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
-
- static const char* causestr[] = {
- "NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
- };
-
- UnwindFrame btf;
-
- // Dump report to the Programming port (interrupts are DISABLED)
- TXBegin();
- TX("\n\n## Software Fault detected ##\n");
- TX("Cause: "); TX(causestr[cause]); TX('\n');
-
- TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
- TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
- TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
- TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
- TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
- TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
- TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
- TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
-
- // Configurable Fault Status Register
- // Consists of MMSR, BFSR and UFSR
- TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
-
- // Hard Fault Status Register
- TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
-
- // Debug Fault Status Register
- TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
-
- // Auxiliary Fault Status Register
- TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
-
- // Read the Fault Address Registers. These may not contain valid values.
- // Check BFARVALID/MMARVALID to see if they are valid values
- // MemManage Fault Address Register
- TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
-
- // Bus Fault Address Register
- TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
-
- TX("ExcLR: "); TXHex(lr); TX('\n');
- TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
-
- btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
- btf.fp = btf.sp;
- btf.lr = ((unsigned long)sp[5]);
- btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
-
- // Perform a backtrace
- TX("\nBacktrace:\n\n");
- int ctr = 0;
- UnwindStart(&btf, &UnwCallbacks, &ctr);
-
- // Disable all NVIC interrupts
- NVIC->ICER[0] = 0xFFFFFFFF;
- NVIC->ICER[1] = 0xFFFFFFFF;
-
- // Relocate VTOR table to default position
- SCB->VTOR = 0;
-
- // Clear cause of reset to prevent entering smoothie bootstrap
- HAL_clear_reset_source();
-
- // Restart watchdog
- #if ENABLED(USE_WATCHDOG)
- //WDT_Restart(WDT);
- watchdog_init();
- #endif
-
- // Reset controller
- NVIC_SystemReset();
-
- // Nothing below here is compiled because NVIC_SystemReset loops forever
-
- for (;;) { TERN_(USE_WATCHDOG, watchdog_init()); }
-}
-
-extern "C" {
-__attribute__((naked)) void NMI_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#0")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void HardFault_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#1")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void MemManage_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#2")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void BusFault_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#3")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void UsageFault_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#4")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void DebugMon_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#5")
- A("b HardFault_HandlerC")
- );
-}
-
-/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
-__attribute__((naked)) void WDT_IRQHandler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#6")
- A("b HardFault_HandlerC")
- );
-}
-
-__attribute__((naked)) void RSTC_Handler() {
- __asm__ __volatile__ (
- ".syntax unified" "\n\t"
- A("tst lr, #4")
- A("ite eq")
- A("mrseq r0, msp")
- A("mrsne r0, psp")
- A("mov r1,lr")
- A("mov r2,#7")
- A("b HardFault_HandlerC")
- );
-}
-}
-#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/HAL.cpp b/Marlin/src/HAL/LPC1768/HAL.cpp
index 939f1e8a9408..cee9cfc5f744 100644
--- a/Marlin/src/HAL/LPC1768/HAL.cpp
+++ b/Marlin/src/HAL/LPC1768/HAL.cpp
@@ -29,21 +29,18 @@
#include "watchdog.h"
#endif
+DefaultSerial1 USBSerial(false, UsbSerial);
+
uint32_t HAL_adc_reading = 0;
// U8glib required functions
-extern "C" void u8g_xMicroDelay(uint16_t val) {
- DELAY_US(val);
-}
-extern "C" void u8g_MicroDelay() {
- u8g_xMicroDelay(1);
-}
-extern "C" void u8g_10MicroDelay() {
- u8g_xMicroDelay(10);
-}
-extern "C" void u8g_Delay(uint16_t val) {
- delay(val);
+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
@@ -66,7 +63,12 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
return ind > -1 ? ind : dval;
}
-void flashFirmware(const int16_t) { NVIC_SystemReset(); }
+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();
+}
void HAL_clear_reset_source(void) {
TERN_(USE_WATCHDOG, watchdog_clear_timeout_flag());
@@ -79,4 +81,6 @@ uint8_t HAL_get_reset_source(void) {
return RST_POWER_ON;
}
+void HAL_reboot() { NVIC_SystemReset(); }
+
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/HAL.h b/Marlin/src/HAL/LPC1768/HAL.h
index cb637e715dda..3f9cd2dfbd02 100644
--- a/Marlin/src/HAL/LPC1768/HAL.h
+++ b/Marlin/src/HAL/LPC1768/HAL.h
@@ -47,9 +47,6 @@ extern "C" volatile uint32_t _millis;
#include
#include
-// i2c uses 8-bit shifted address
-#define I2C_ADDRESS(A) uint8_t((A) << 1)
-
//
// Default graphical display delays
//
@@ -63,35 +60,60 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
+typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
+extern DefaultSerial1 USBSerial;
+
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
-#define MSerial0 MSerial
#if SERIAL_PORT == -1
- #define MYSERIAL0 UsbSerial
+ #define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
- #define MYSERIAL0 MSERIAL(SERIAL_PORT)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
- #error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #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 MYSERIAL1 UsbSerial
+ #define MYSERIAL2 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
- #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
+ #define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
- #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
+ #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
+ #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 -1 to 3. Please update your configuration."
+ #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() MSerial0.available()
#endif
#endif
@@ -107,10 +129,16 @@ extern "C" volatile uint32_t _millis;
//
// Utility functions
//
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
//
// ADC API
@@ -170,7 +198,7 @@ constexpr pin_t GET_PIN_MAP_PIN(const int16_t 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
+#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09,
#define HAL_IDLETASK 1
void HAL_idletask();
@@ -200,9 +228,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255,
void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
-
-// Add strcmp_P if missing
-#ifndef strcmp_P
- #define strcmp_P(a, b) strcmp((a), (b))
-#endif
+void HAL_reboot();
diff --git a/Marlin/src/HAL/LPC1768/HAL_MinSerial.cpp b/Marlin/src/HAL/LPC1768/HAL_MinSerial.cpp
new file mode 100644
index 000000000000..57065c49ac83
--- /dev/null
+++ b/Marlin/src/HAL/LPC1768/HAL_MinSerial.cpp
@@ -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 .
+ *
+ */
+#ifdef TARGET_LPC1768
+
+#include "../../inc/MarlinConfig.h"
+#include "HAL.h"
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+
+#include "../shared/HAL_MinSerial.h"
+#include
+
+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_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
index b3d2908ac93e..29f9b43afef0 100644
--- a/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
+++ b/Marlin/src/HAL/LPC1768/HAL_SPI.cpp
@@ -55,27 +55,29 @@
#include
#include
+#include "../shared/HAL_SPI.h"
+
// ------------------------
// Public functions
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
- #include
-
// Software SPI
- static uint8_t SPI_speed = 0;
+ #include
+
+ static uint8_t SPI_speed = SPI_FULL_SPEED;
static uint8_t spiTransfer(uint8_t b) {
- return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN);
+ return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiBegin() {
- swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN);
+ swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiInit(uint8_t spiRate) {
- SPI_speed = swSpiInit(spiRate, SCK_PIN, MOSI_PIN);
+ SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN);
}
uint8_t spiRec() { return spiTransfer(0xFF); }
@@ -87,12 +89,12 @@
void spiSend(uint8_t b) { (void)spiTransfer(b); }
- void spiSend(const uint8_t* buf, size_t nbyte) {
+ 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 spiSendBlock(uint8_t token, const uint8_t *buf) {
(void)spiTransfer(token);
for (uint16_t i = 0; i < 512; i++)
(void)spiTransfer(buf[i]);
@@ -100,14 +102,18 @@
#else
- void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0
- spiInit(SPI_SPEED);
- }
+ #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 MISO_PIN == BOARD_SPI1_MISO_PIN
+ #if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPI.setModule(1);
- #elif MISO_PIN == BOARD_SPI2_MISO_PIN
+ #elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPI.setModule(2);
#endif
SPI.setDataSize(DATA_SIZE_8BIT);
@@ -123,15 +129,13 @@
void spiSend(uint8_t b) { doio(b); }
- void spiSend(const uint8_t* buf, size_t nbyte) {
+ 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, byte b) {}
- void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
- }
+ void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {}
// Read single byte from SPI
uint8_t spiRec() { return doio(0xFF); }
@@ -143,21 +147,18 @@
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
}
- uint8_t spiTransfer(uint8_t b) {
- return doio(b);
- }
+ uint8_t spiTransfer(uint8_t b) { return doio(b); }
// Write from buffer to SPI
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ 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 */
+ // Begin SPI transaction, set clock, bit order, data mode
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
- // TODO: to be implemented
-
+ // TODO: Implement this method
}
#endif // LPC_SOFTWARE_SPI
@@ -201,6 +202,15 @@ SPIClass::SPIClass(uint8_t device) {
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
+}
+
void SPIClass::begin() {
// Init the SPI pins in the first begin call
if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) ||
@@ -263,8 +273,9 @@ uint16_t SPIClass::transfer16(const uint16_t data) {
}
void SPIClass::end() {
- // SSP_Cmd(_currentSetting->spi_d, DISABLE); // stop device or SSP_DeInit?
- SSP_DeInit(_currentSetting->spi_d);
+ // Neither is needed for Marlin
+ //SSP_Cmd(_currentSetting->spi_d, DISABLE);
+ //SSP_DeInit(_currentSetting->spi_d);
}
void SPIClass::send(uint8_t data) {
@@ -330,25 +341,15 @@ void SPIClass::read(uint8_t *buf, uint32_t len) {
for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF);
}
-void SPIClass::setClock(uint32_t clock) {
- _currentSetting->clock = clock;
-}
+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::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::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
-void SPIClass::setDataMode(uint8_t dataMode) {
- _currentSetting->dataMode = dataMode;
-}
+void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
-void SPIClass::setDataSize(uint32_t ds) {
- _currentSetting->dataSize = ds;
-}
+void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
/**
* Set up/tear down
@@ -356,8 +357,8 @@ void SPIClass::setDataSize(uint32_t ds) {
void SPIClass::updateSettings() {
//SSP_DeInit(_currentSetting->spi_d); //todo: need force de init?!
- // divide PCLK by 2 for SSP0
- CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
+ // Divide PCLK by 2 for SSP0
+ //CLKPWR_SetPCLKDiv(_currentSetting->spi_d == LPC_SSP0 ? CLKPWR_PCLKSEL_SSP0 : CLKPWR_PCLKSEL_SSP1, CLKPWR_PCLKSEL_CCLK_DIV_2);
SSP_CFG_Type HW_SPI_init; // data structure to hold init values
SSP_ConfigStructInit(&HW_SPI_init); // set values for SPI mode
@@ -396,9 +397,9 @@ void SPIClass::updateSettings() {
SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
}
-#if MISO_PIN == BOARD_SPI1_MISO_PIN
+#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPIClass SPI(1);
-#elif MISO_PIN == BOARD_SPI2_MISO_PIN
+#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIClass SPI(2);
#endif
diff --git a/Marlin/src/HAL/LPC1768/MarlinSPI.h b/Marlin/src/HAL/LPC1768/MarlinSPI.h
new file mode 100644
index 000000000000..fab245f904e3
--- /dev/null
+++ b/Marlin/src/HAL/LPC1768/MarlinSPI.h
@@ -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 .
+ *
+ */
+#pragma once
+
+#include
+
+/**
+ * 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;
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
index 5374e005d3da..f2aecf54a050 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
@@ -21,35 +21,51 @@
*/
#ifdef TARGET_LPC1768
-#include "../../inc/MarlinConfigPre.h"
#include "MarlinSerial.h"
-#if USING_SERIAL_0
- MarlinSerial MSerial(LPC_UART0);
- extern "C" void UART0_IRQHandler() {
- MSerial.IRQHandler();
- }
-#endif
+#include "../../inc/MarlinConfig.h"
-#if USING_SERIAL_1
- MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1);
- extern "C" void UART1_IRQHandler() {
- MSerial1.IRQHandler();
- }
+#if USING_HW_SERIAL0
+ MarlinSerial _MSerial0(LPC_UART0);
+ MSerialT MSerial0(true, _MSerial0);
+ extern "C" void UART0_IRQHandler() { _MSerial0.IRQHandler(); }
#endif
-
-#if USING_SERIAL_2
- MarlinSerial MSerial2(LPC_UART2);
- extern "C" void UART2_IRQHandler() {
- MSerial2.IRQHandler();
- }
+#if USING_HW_SERIAL1
+ MarlinSerial _MSerial1((LPC_UART_TypeDef *) LPC_UART1);
+ MSerialT MSerial1(true, _MSerial1);
+ extern "C" void UART1_IRQHandler() { _MSerial1.IRQHandler(); }
+#endif
+#if USING_HW_SERIAL2
+ MarlinSerial _MSerial2(LPC_UART2);
+ MSerialT MSerial2(true, _MSerial2);
+ extern "C" void UART2_IRQHandler() { _MSerial2.IRQHandler(); }
+#endif
+#if USING_HW_SERIAL3
+ MarlinSerial _MSerial3(LPC_UART3);
+ MSerialT MSerial3(true, _MSerial3);
+ extern "C" void UART3_IRQHandler() { _MSerial3.IRQHandler(); }
#endif
-#if USING_SERIAL_3
- MarlinSerial MSerial3(LPC_UART3);
- extern "C" void UART3_IRQHandler() {
- MSerial3.IRQHandler();
+#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;
}
+
#endif
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/MarlinSerial.h b/Marlin/src/HAL/LPC1768/MarlinSerial.h
index 8d6b64378a0a..808d19f8c52a 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.h
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.h
@@ -28,6 +28,7 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
#endif
+#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
@@ -41,27 +42,26 @@
class MarlinSerial : public HardwareSerial {
public:
- MarlinSerial(LPC_UART_TypeDef *UARTx) :
- HardwareSerial(UARTx)
- #if ENABLED(EMERGENCY_PARSER)
- , emergency_state(EmergencyParser::State::EP_RESET)
- #endif
- { }
+ MarlinSerial(LPC_UART_TypeDef *UARTx) : HardwareSerial(UARTx) { }
void end() {}
#if ENABLED(EMERGENCY_PARSER)
- bool recv_callback(const char c) override {
- emergency_parser.update(emergency_state, c);
- return true; // do not discard character
- }
-
- EmergencyParser::State emergency_state;
- static inline bool emergency_parser_enabled() { return true; }
+ bool recv_callback(const char c) override;
#endif
};
-extern MarlinSerial MSerial;
-extern MarlinSerial MSerial1;
-extern MarlinSerial MSerial2;
-extern MarlinSerial MSerial3;
+// 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 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> 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
diff --git a/Marlin/src/HAL/LPC1768/eeprom_flash.cpp b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
index 255848637520..38d2705d519a 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_flash.cpp
@@ -25,7 +25,7 @@
* 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 "levelling" scheme is used that
+ * 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.
@@ -119,7 +119,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
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*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
crc16(crc, buff, size);
diff --git a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
index 9f2475f490ef..70395251df25 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
@@ -83,17 +83,16 @@ bool PersistentStore::access_finish() {
static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) {
PGM_P const rw_str = write ? PSTR("write") : PSTR("read");
SERIAL_CHAR(' ');
- serialprintPGM(rw_str);
- SERIAL_ECHOLNPAIR("_data(", pos, ",", int(value), ",", int(size), ", ...)");
+ SERIAL_ECHOPGM_P(rw_str);
+ SERIAL_ECHOLNPAIR("_data(", pos, ",", value, ",", size, ", ...)");
if (total) {
SERIAL_ECHOPGM(" f_");
- serialprintPGM(rw_str);
- SERIAL_ECHOPAIR("()=", int(s), "\n size=", int(size), "\n bytes_");
- serialprintPGM(write ? PSTR("written=") : PSTR("read="));
- SERIAL_ECHOLN(total);
+ SERIAL_ECHOPGM_P(rw_str);
+ SERIAL_ECHOPAIR("()=", s, "\n size=", size, "\n bytes_");
+ SERIAL_ECHOLNPAIR_P(write ? PSTR("written=") : PSTR("read="), total);
}
else
- SERIAL_ECHOLNPAIR(" f_lseek()=", int(s));
+ SERIAL_ECHOLNPAIR(" f_lseek()=", s);
}
// File function return codes for type FRESULT. This goes away soon, but
@@ -143,7 +142,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return bytes_written != size; // return true for any error
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
if (!eeprom_file_open) return true;
UINT bytes_read = 0;
FRESULT s;
diff --git a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
index 16c15eaf0063..f9286a74ac88 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
@@ -42,33 +42,29 @@ bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ uint16_t written = 0;
while (size--) {
uint8_t v = *value;
-
- // EEPROM has only ~100,000 write cycles,
- // so only write bytes that have changed!
uint8_t * const p = (uint8_t * const)pos;
- if (v != eeprom_read_byte(p)) {
+ if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
+ if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
}
}
-
crc16(crc, &v, 1);
pos++;
value++;
- };
-
+ }
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
do {
// Read from external EEPROM
const uint8_t c = eeprom_read_byte((uint8_t*)pos);
-
if (writing) *value = c;
crc16(crc, &c, 1);
pos++;
diff --git a/Marlin/src/HAL/LPC1768/endstop_interrupts.h b/Marlin/src/HAL/LPC1768/endstop_interrupts.h
index b0d0c0ec5c0a..23bd0cc982b2 100644
--- a/Marlin/src/HAL/LPC1768/endstop_interrupts.h
+++ b/Marlin/src/HAL/LPC1768/endstop_interrupts.h
@@ -46,80 +46,113 @@ void setup_endstop_interrupts() {
#if HAS_X_MAX
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
- #error "X_MAX_PIN is not INTERRUPT-capable."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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."
+ #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
}
diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h
index 5f1c4b16019d..8e7cab185f2a 100644
--- a/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h
+++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_adv.h
@@ -20,3 +20,7 @@
*
*/
#pragma once
+
+#if DISABLED(NO_SD_HOST_DRIVE)
+ #define HAS_SD_HOST_DRIVE 1
+#endif
diff --git a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h
index ce6d3fdde27f..be574a96e4ed 100644
--- a/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h
+++ b/Marlin/src/HAL/LPC1768/inc/Conditionals_post.h
@@ -26,3 +26,9 @@
#elif EITHER(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) && PRINTCOUNTER_SAVE_INTERVAL > 0
+ #define PRINTCOUNTER_SYNC 1
+#endif
diff --git a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
index f5051d32a168..23d797b2ab76 100644
--- a/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
+++ b/Marlin/src/HAL/LPC1768/inc/SanityCheck.h
@@ -24,14 +24,14 @@
#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 < 2005
+#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 && _CAT(P,_PIN) != 2 && _CAT(P,_PIN) != 3
+#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)
@@ -72,7 +72,7 @@ static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are in
//#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 ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI)
+ #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
@@ -92,13 +92,13 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#define ANY_TX(N,V...) DO(IS_TX##N,||,V)
#define ANY_RX(N,V...) DO(IS_RX##N,||,V)
-#if USING_SERIAL_0
+#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 ENABLED(MK2_MULTIPLEXER) && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
- #error "Serial port pins (0) conflict with MK2 multiplexer 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
@@ -106,7 +106,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#undef IS_RX0
#endif
-#if USING_SERIAL_1
+#if USING_HW_SERIAL1
#define IS_TX1(P) (P == P0_15)
#define IS_RX1(P) (P == P0_16)
#define _IS_TX1_1 IS_TX1
@@ -116,8 +116,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#elif HAS_WIRED_LCD
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
- #elif ANY_TX(1, SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK) \
- || ANY_RX(1, LCD_SDSS, LCD_PINS_RS, MISO_PIN, DOGLCD_A0, SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
+ #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
@@ -127,7 +127,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#undef _IS_RX1_1
#endif
-#if USING_SERIAL_2
+#if USING_HW_SERIAL2
#define IS_TX2(P) (P == P0_10)
#define IS_RX2(P) (P == P0_11)
#define _IS_TX2_1 IS_TX2
@@ -144,9 +144,9 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#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_DIR < 0 && IS_TX2(Y_STOP_PIN)
+ #elif Y_HOME_TO_MIN && IS_TX2(Y_STOP_PIN)
#error "Serial port pins (2) conflict with Y endstop pin!"
- #elif HAS_CUSTOM_PROBE_PIN && IS_TX2(Z_MIN_PROBE_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!"
@@ -161,7 +161,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#undef _IS_RX2_1
#endif
-#if USING_SERIAL_3
+#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)
@@ -205,8 +205,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "SDA0 overlaps with BEEPER_PIN!"
#elif IS_SCL0(BTN_ENC)
#error "SCL0 overlaps with Encoder Button!"
- #elif IS_SCL0(SS_PIN)
- #error "SCL0 overlaps with SS_PIN!"
+ #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
@@ -237,7 +237,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#define PIN_IS_SCL2(P) (P##_PIN == P0_11)
#if PIN_IS_SDA2(Y_STOP)
#error "i2c SDA2 overlaps with Y endstop pin!"
- #elif HAS_CUSTOM_PROBE_PIN && PIN_IS_SDA2(Z_MIN_PROBE)
+ #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!"
@@ -270,7 +270,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
- #error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
+ #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 this platform."
+ #error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x."
#endif
diff --git a/Marlin/src/HAL/LPC1768/include/SPI.h b/Marlin/src/HAL/LPC1768/include/SPI.h
index 9da2a32556e7..ecd91f6a3b73 100644
--- a/Marlin/src/HAL/LPC1768/include/SPI.h
+++ b/Marlin/src/HAL/LPC1768/include/SPI.h
@@ -37,13 +37,14 @@
#define DATA_SIZE_8BIT SSP_DATABIT_8
#define DATA_SIZE_16BIT SSP_DATABIT_16
-#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_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
@@ -125,6 +126,11 @@ class SPIClass {
*/
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
*/
diff --git a/Marlin/src/HAL/LPC1768/main.cpp b/Marlin/src/HAL/LPC1768/main.cpp
index 0b4045cb9927..ef0dc42c78ca 100644
--- a/Marlin/src/HAL/LPC1768/main.cpp
+++ b/Marlin/src/HAL/LPC1768/main.cpp
@@ -31,20 +31,23 @@
#include
#include
-extern "C" {
- #include
-}
-
-#include "../../sd/cardreader.h"
#include "../../inc/MarlinConfig.h"
#include "../../core/millis_t.h"
+#include "../../sd/cardreader.h"
+
extern uint32_t MSC_SD_Init(uint8_t pdrv);
-extern "C" int isLPC1769();
-extern "C" void disk_timerproc();
+
+extern "C" {
+ #include
+ extern "C" int isLPC1769();
+ extern "C" void disk_timerproc();
+}
void SysTick_Callback() { disk_timerproc(); }
+TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
+
void HAL_init() {
// Init LEDs
@@ -89,11 +92,11 @@ void HAL_init() {
//debug_frmwrk_init();
//_DBG("\n\nDebug running\n");
// Initialize the SD card chip select pins as soon as possible
- #if PIN_EXISTS(SS)
- OUT_WRITE(SS_PIN, HIGH);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
- #if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SS_PIN
+ #if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH);
#endif
@@ -114,17 +117,15 @@ void HAL_init() {
PinCfg.Pinmode = 2; // no pull-up/pull-down
PINSEL_ConfigPin(&PinCfg);
// now set CLKOUT_EN bit
- LPC_SC->CLKOUTCFG |= (1<<8);
+ SBI(LPC_SC->CLKOUTCFG, 8);
#endif
USB_Init(); // USB Initialization
- USB_Connect(FALSE); // USB clear connection
+ USB_Connect(false); // USB clear connection
delay(1000); // Give OS time to notice
- USB_Connect(TRUE);
+ USB_Connect(true);
- #if DISABLED(NO_SD_HOST_DRIVE)
- MSC_SD_Init(0); // Enable USB SD card access
- #endif
+ TERN_(HAS_SD_HOST_DRIVE, MSC_SD_Init(0)); // Enable USB SD card access
const millis_t usb_timeout = millis() + 2000;
while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
@@ -136,6 +137,8 @@ void HAL_init() {
}
HAL_timer_init();
+
+ TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
// HAL idle task
diff --git a/Marlin/src/HAL/LPC1768/spi_pins.h b/Marlin/src/HAL/LPC1768/spi_pins.h
index b4da5d4df234..e7d774742f42 100644
--- a/Marlin/src/HAL/LPC1768/spi_pins.h
+++ b/Marlin/src/HAL/LPC1768/spi_pins.h
@@ -23,7 +23,7 @@
#include "../../core/macros.h"
-#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
+#if BOTH(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
@@ -31,24 +31,24 @@
#endif
/** onboard SD card */
-//#define SCK_PIN P0_07
-//#define MISO_PIN P0_08
-//#define MOSI_PIN P0_09
-//#define SS_PIN P0_06
+//#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 SCK_PIN
- #define SCK_PIN P0_15
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN P0_15
#endif
-#ifndef MISO_PIN
- #define MISO_PIN P0_17
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN P0_17
#endif
-#ifndef MOSI_PIN
- #define MOSI_PIN P0_18
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN P0_18
#endif
-#ifndef SS_PIN
- #define SS_PIN P1_23
+#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 SS_PIN
+ #define SDSS SD_SS_PIN
#endif
diff --git a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
index 84907acd0702..a2cb66ab5bfd 100644
--- a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
@@ -89,7 +89,7 @@ void TFT_SPI::Init() {
#elif TFT_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIx.setModule(2);
#endif
- SPIx.setClock(SPI_CLOCK_MAX);
+ SPIx.setClock(SPI_CLOCK_MAX_TFT);
SPIx.setBitOrder(MSBFIRST);
SPIx.setDataMode(SPI_MODE0);
}
@@ -125,7 +125,7 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
}
DataTransferEnd();
- SPIx.setClock(SPI_CLOCK_MAX);
+ SPIx.setClock(SPI_CLOCK_MAX_TFT);
#endif
return data >> 7;
diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
index 5f96630043c1..9c1e158981da 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * 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
@@ -19,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
-#if HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046
+#if HAS_TFT_XPT2046 || HAS_RES_TOUCH_BUTTONS
#include "xpt2046.h"
#include
diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.h b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
index 019f75efce12..aba0799e445f 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.h
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * 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
@@ -25,16 +28,16 @@
#endif
#ifndef TOUCH_MISO_PIN
- #define TOUCH_MISO_PIN MISO_PIN
+ #define TOUCH_MISO_PIN SD_MISO_PIN
#endif
#ifndef TOUCH_MOSI_PIN
- #define TOUCH_MOSI_PIN MOSI_PIN
+ #define TOUCH_MOSI_PIN SD_MOSI_PIN
#endif
#ifndef TOUCH_SCK_PIN
- #define TOUCH_SCK_PIN SCK_PIN
+ #define TOUCH_SCK_PIN SD_SCK_PIN
#endif
#ifndef TOUCH_CS_PIN
- #define TOUCH_CS_PIN CS_PIN
+ #define TOUCH_CS_PIN SD_SS_PIN
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
@@ -51,7 +54,7 @@ enum XPTCoordinate : uint8_t {
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
};
-#if !defined(XPT2046_Z1_THRESHOLD)
+#ifndef XPT2046_Z1_THRESHOLD
#define XPT2046_Z1_THRESHOLD 10
#endif
diff --git a/Marlin/src/HAL/LPC1768/timers.h b/Marlin/src/HAL/LPC1768/timers.h
index e6744fb005bf..4b638546856f 100644
--- a/Marlin/src/HAL/LPC1768/timers.h
+++ b/Marlin/src/HAL/LPC1768/timers.h
@@ -152,7 +152,7 @@ FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// This function is missing from CMSIS
FORCE_INLINE static bool NVIC_GetEnableIRQ(IRQn_Type IRQn) {
- return (NVIC->ISER[((uint32_t)IRQn) >> 5] & (1 << ((uint32_t)IRQn) & 0x1F)) != 0;
+ return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
index 057e10e0f545..0118f92847de 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_hw_spi.cpp
@@ -59,13 +59,16 @@
#if HAS_MARLINUI_U8GLIB
-#include
+#include
#include "../../shared/HAL_SPI.h"
-void spiBegin();
-void spiInit(uint8_t spiRate);
-void spiSend(uint8_t b);
-void spiSend(const uint8_t* buf, size_t n);
+#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) {
@@ -81,10 +84,7 @@ uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
u8g_SetPIOutput(u8g, U8G_PI_RESET);
u8g_Delay(5);
spiBegin();
- #ifndef SPI_SPEED
- #define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
- #endif
- spiInit(SPI_SPEED);
+ spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
index 6f7efba4ae20..bf76eaf0f491 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_ssd_hw_i2c.cpp
@@ -79,7 +79,7 @@
#if HAS_MARLINUI_U8GLIB
-#include
+#include
#define I2C_SLA (0x3C*2)
//#define I2C_CMD_MODE 0x080
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
index 592e27f6c006..ce7b33801931 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_hw_spi.cpp
@@ -59,14 +59,14 @@
#if HAS_MARLINUI_U8GLIB
-#include
+#include
#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);
+void spiSend(const uint8_t *buf, size_t n);
static uint8_t rs_last_state = 255;
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
index 10d84941625f..039fa6769bbe 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_st7920_sw_spi.cpp
@@ -59,12 +59,14 @@
#if ENABLED(U8GLIB_ST7920)
-#include
+#include
#include
#include "../../shared/Delay.h"
+#include "../../shared/HAL_SPI.h"
-#undef SPI_SPEED
-#define SPI_SPEED 3 // About 1 MHz
+#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;
@@ -92,7 +94,7 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
u8g_Delay(5);
- SPI_speed = swSpiInit(SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
+ 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);
diff --git a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
index ca9d6ecfbe25..3308d03e79f9 100644
--- a/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/u8g/u8g_com_HAL_LPC1768_sw_spi.cpp
@@ -60,16 +60,18 @@
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#include
+#include "../../shared/HAL_SPI.h"
-#undef SPI_SPEED
-#define SPI_SPEED 2 // About 2 MHz
+#ifndef LCD_SPI_SPEED
+ #define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz
+#endif
#include
#include
#include
#include
-#include
+#include
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 ) {
@@ -145,7 +147,7 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
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(SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
+ 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;
diff --git a/Marlin/src/HAL/LPC1768/upload_extra_script.py b/Marlin/src/HAL/LPC1768/upload_extra_script.py
index 9b0d0617a0c9..fb3aaef7cd38 100755
--- a/Marlin/src/HAL/LPC1768/upload_extra_script.py
+++ b/Marlin/src/HAL/LPC1768/upload_extra_script.py
@@ -8,9 +8,7 @@
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
-import os
-import getpass
-import platform
+import os,getpass,platform
current_OS = platform.system()
Import("env")
@@ -22,124 +20,104 @@ def print_error(e):
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
%(e, env.get('PIOENV')))
-try:
- if current_OS == 'Windows':
+def before_upload(source, target, env):
+ try:
#
- # platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
- # Windows - doesn't care about the disk's name, only cares about the drive letter
+ # Find a disk for upload
#
-
- #
- # get all drives on this computer
- #
- import subprocess
- # typical result (string): 'Drives: C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
- driveStr = str(subprocess.check_output("fsutil fsinfo drives"))
- # typical result (string): 'C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
- # driveStr = driveStr.strip().lstrip('Drives: ') <- Doesn't work in other Languages as English. In German is "Drives:" = "Laufwerke:"
- FirstFound = driveStr.find(':',0,-1) # Find the first ":" and
- driveStr = driveStr[FirstFound + 1 : -1] # truncate to the rest
- # typical result (array of stings): ['C:\\', 'D:\\', 'E:\\', 'F:\\',
- # 'G:\\', 'H:\\', 'I:\\', 'J:\\', 'K:\\', 'L:\\', 'M:\\', 'Y:\\', 'Z:\\']
- drives = driveStr.split()
-
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
- for drive in drives:
- final_drive_name = drive.strip().rstrip('\\') # typical result (string): 'C:'
- try:
- volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
- except Exception as e:
- continue
- else:
- if target_drive in volume_info and target_file_found == False: # set upload if not found target file yet
- target_drive_found = True
- upload_disk = final_drive_name
- if target_filename in volume_info:
- if target_file_found == False:
+ if current_OS == 'Windows':
+ #
+ # platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
+ # Windows - doesn't care about the disk's name, only cares about the drive letter
+ import subprocess,string
+ from ctypes import windll
+
+ # getting list of drives
+ # https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
+ drives = []
+ bitmask = windll.kernel32.GetLogicalDrives()
+ for letter in string.ascii_uppercase:
+ if bitmask & 1:
+ drives.append(letter)
+ bitmask >>= 1
+
+ for drive in drives:
+ final_drive_name = drive + ':\\'
+ # print ('disc check: {}'.format(final_drive_name))
+ try:
+ volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
+ except Exception as e:
+ print ('error:{}'.format(e))
+ continue
+ else:
+ if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
+ target_drive_found = True
upload_disk = final_drive_name
- target_file_found = True
+ if target_filename in volume_info:
+ if not target_file_found:
+ upload_disk = final_drive_name
+ target_file_found = True
- #
- # set upload_port to drive if found
- #
+ elif current_OS == 'Linux':
+ #
+ # platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
+ #
+ drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
+ if target_drive in drives: # If target drive is found, use it.
+ target_drive_found = True
+ upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
+ else:
+ for drive in drives:
+ try:
+ files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
+ except:
+ continue
+ else:
+ if target_filename in files:
+ upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
+ target_file_found = True
+ break
+ #
+ # set upload_port to drive if found
+ #
- if target_file_found == True or target_drive_found == True:
- env.Replace(
- UPLOAD_PORT=upload_disk
- )
- print('upload disk: ', upload_disk)
- else:
- print_error('Autodetect Error')
+ if target_file_found or target_drive_found:
+ env.Replace(
+ UPLOAD_FLAGS="-P$UPLOAD_PORT"
+ )
- elif current_OS == 'Linux':
- #
- # platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
- #
- upload_disk = 'Disk not found'
- target_file_found = False
- target_drive_found = False
- drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
- if target_drive in drives: # If target drive is found, use it.
- target_drive_found = True
- upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
- else:
+ elif current_OS == 'Darwin': # MAC
+ #
+ # platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
+ #
+ drives = os.listdir('/Volumes') # human readable names
+ if target_drive in drives and not target_file_found: # set upload if not found target file yet
+ target_drive_found = True
+ upload_disk = '/Volumes/' + target_drive + '/'
for drive in drives:
try:
- files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
+ filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
except:
continue
else:
- if target_filename in files:
- upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
+ if target_filename in filenames:
+ if not target_file_found:
+ upload_disk = '/Volumes/' + drive + '/'
target_file_found = True
- break
+
#
- # set upload_port to drive if found
+ # Set upload_port to drive if found
#
-
if target_file_found or target_drive_found:
- env.Replace(
- UPLOAD_FLAGS="-P$UPLOAD_PORT",
- UPLOAD_PORT=upload_disk
- )
- print('upload disk: ', upload_disk)
+ env.Replace(UPLOAD_PORT=upload_disk)
+ print('\nUpload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
- elif current_OS == 'Darwin': # MAC
- #
- # platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
- #
- upload_disk = 'Disk not found'
- drives = os.listdir('/Volumes') # human readable names
- target_file_found = False
- target_drive_found = False
- if target_drive in drives and target_file_found == False: # set upload if not found target file yet
- target_drive_found = True
- upload_disk = '/Volumes/' + target_drive + '/'
- for drive in drives:
- try:
- filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
- except:
- continue
- else:
- if target_filename in filenames:
- if target_file_found == False:
- upload_disk = '/Volumes/' + drive + '/'
- target_file_found = True
- #
- # set upload_port to drive if found
- #
-
- if target_file_found == True or target_drive_found == True:
- env.Replace(
- UPLOAD_PORT=upload_disk
- )
- print('\nupload disk: ', upload_disk, '\n')
- else:
- print_error('Autodetect Error')
+ except Exception as e:
+ print_error(str(e))
-except Exception as e:
- print_error(str(e))
+env.AddPreAction("upload", before_upload)
diff --git a/Marlin/src/HAL/LPC1768/usb_serial.cpp b/Marlin/src/HAL/LPC1768/usb_serial.cpp
index d225ce418860..3c1fce54f95f 100644
--- a/Marlin/src/HAL/LPC1768/usb_serial.cpp
+++ b/Marlin/src/HAL/LPC1768/usb_serial.cpp
@@ -29,8 +29,8 @@
EmergencyParser::State emergency_state;
-bool CDC_RecvCallback(const char buffer) {
- emergency_parser.update(emergency_state, buffer);
+bool CDC_RecvCallback(const char c) {
+ emergency_parser.update(emergency_state, c);
return true;
}
diff --git a/Marlin/src/HAL/LPC1768/watchdog.cpp b/Marlin/src/HAL/LPC1768/watchdog.cpp
index 3cd22d665168..f23ccf5b512d 100644
--- a/Marlin/src/HAL/LPC1768/watchdog.cpp
+++ b/Marlin/src/HAL/LPC1768/watchdog.cpp
@@ -28,6 +28,8 @@
#include
#include "watchdog.h"
+#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
+
void watchdog_init() {
#if ENABLED(WATCHDOG_RESET_MANUAL)
// We enable the watchdog timer, but only for the interrupt.
@@ -52,7 +54,7 @@ void watchdog_init() {
#else
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
#endif
- WDT_Start(WDT_TIMEOUT);
+ WDT_Start(WDT_TIMEOUT_US);
}
void HAL_watchdog_refresh() {
diff --git a/Marlin/src/HAL/LPC1768/watchdog.h b/Marlin/src/HAL/LPC1768/watchdog.h
index cc170881f375..c843f0ed5571 100644
--- a/Marlin/src/HAL/LPC1768/watchdog.h
+++ b/Marlin/src/HAL/LPC1768/watchdog.h
@@ -21,8 +21,6 @@
*/
#pragma once
-#define WDT_TIMEOUT 4000000 // 4 second timeout
-
void watchdog_init();
void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/NATIVE_SIM/HAL.h b/Marlin/src/HAL/NATIVE_SIM/HAL.h
new file mode 100644
index 000000000000..d5c5782c36c3
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/HAL.h
@@ -0,0 +1,217 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2021 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 .
+ *
+ */
+#pragma once
+
+#define CPU_32_BIT
+#define HAL_IDLETASK
+void HAL_idletask();
+
+#define F_CPU 100000000
+#define SystemCoreClock F_CPU
+#include
+#include
+
+#undef min
+#undef max
+
+#include
+#include "pinmapping.h"
+
+void _printf (const char *format, ...);
+void _putc(uint8_t c);
+uint8_t _getc();
+
+//extern "C" volatile uint32_t _millis;
+
+//arduino: Print.h
+#define DEC 10
+#define HEX 16
+#define OCT 8
+#define BIN 2
+//arduino: binary.h (weird defines)
+#define B01 1
+#define B10 2
+
+#include "../shared/Marduino.h"
+#include "../shared/math_32bit.h"
+#include "../shared/HAL_SPI.h"
+#include "fastio.h"
+#include "watchdog.h"
+#include "serial.h"
+
+#define SHARED_SERVOS HAS_SERVOS
+
+extern MSerialT serial_stream_0;
+extern MSerialT serial_stream_1;
+extern MSerialT serial_stream_2;
+extern MSerialT serial_stream_3;
+
+#define _MSERIAL(X) serial_stream_##X
+#define MSERIAL(X) _MSERIAL(X)
+
+#if WITHIN(SERIAL_PORT, 0, 3)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT)
+#else
+ #error "SERIAL_PORT must be from 0 to 3. Please update your configuration."
+#endif
+
+#ifdef SERIAL_PORT_2
+ #if WITHIN(SERIAL_PORT_2, 0, 3)
+ #define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
+ #else
+ #error "SERIAL_PORT_2 must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
+#ifdef MMU2_SERIAL_PORT
+ #if WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
+#ifdef LCD_SERIAL_PORT
+ #if WITHIN(LCD_SERIAL_PORT, 0, 3)
+ #define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
+ #else
+ #error "LCD_SERIAL_PORT must be from 0 to 3. Please update your configuration."
+ #endif
+#endif
+
+
+#define ST7920_DELAY_1 DELAY_NS(600)
+#define ST7920_DELAY_2 DELAY_NS(750)
+#define ST7920_DELAY_3 DELAY_NS(750)
+
+//
+// Interrupts
+//
+#define CRITICAL_SECTION_START()
+#define CRITICAL_SECTION_END()
+#define ISRS_ENABLED()
+#define ENABLE_ISRS()
+#define DISABLE_ISRS()
+
+inline void HAL_init() {}
+
+// Utility functions
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
+int freeMemory();
+#pragma GCC diagnostic pop
+
+// ADC
+#define HAL_ADC_VREF 5.0
+#define HAL_ADC_RESOLUTION 10
+#define HAL_ANALOG_SELECT(ch) HAL_adc_enable_channel(ch)
+#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
+#define HAL_READ_ADC() HAL_adc_get_result()
+#define HAL_ADC_READY() true
+
+void HAL_adc_init();
+void HAL_adc_enable_channel(const uint8_t ch);
+void HAL_adc_start_conversion(const uint8_t ch);
+uint16_t HAL_adc_get_result();
+
+// Reset source
+inline void HAL_clear_reset_source(void) {}
+inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
+
+/* ---------------- Delay in cycles */
+
+#define DELAY_CYCLES(x) Kernel::delayCycles(x)
+#define SYSTEM_YIELD() Kernel::yield()
+
+// Maple Compatibility
+typedef void (*systickCallback_t)(void);
+void systick_attach_callback(systickCallback_t cb);
+extern volatile uint32_t systick_uptime_millis;
+
+// Marlin uses strstr in constexpr context, this is not supported, workaround by defining constexpr versions of the required functions.
+#define strstr(a, b) strstr_constexpr((a), (b))
+
+constexpr inline std::size_t strlen_constexpr(const char* str) {
+ // https://github.com/gcc-mirror/gcc/blob/5c7634a0e5f202935aa6c11b6ea953b8bf80a00a/libstdc%2B%2B-v3/include/bits/char_traits.h#L329
+ if (str != nullptr) {
+ std::size_t i = 0;
+ while (str[i] != '\0') {
+ ++i;
+ }
+
+ return i;
+ }
+
+ return 0;
+}
+
+constexpr inline int strncmp_constexpr(const char* lhs, const char* rhs, std::size_t count) {
+ // https://github.com/gcc-mirror/gcc/blob/13b9cbfc32fe3ac4c81c4dd9c42d141c8fb95db4/libstdc%2B%2B-v3/include/bits/char_traits.h#L655
+ if (lhs == nullptr || rhs == nullptr) {
+ return rhs != nullptr ? -1 : 1;
+ }
+
+ for (std::size_t i = 0; i < count; ++i) {
+ if (lhs[i] != rhs[i]) {
+ return lhs[i] < rhs[i] ? -1 : 1;
+ } else if (lhs[i] == '\0') {
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+constexpr inline const char* strstr_constexpr(const char* str, const char* target) {
+ // https://github.com/freebsd/freebsd/blob/master/sys/libkern/strstr.c
+ if (char c = target != nullptr ? *target++ : '\0'; c != '\0' && str != nullptr) {
+ std::size_t len = strlen_constexpr(target);
+ do {
+ char sc = {};
+ do {
+ if ((sc = *str++) == '\0') {
+ return nullptr;
+ }
+ } while (sc != c);
+ } while (strncmp_constexpr(str, target, len) != 0);
+ --str;
+ }
+
+ return str;
+}
+
+constexpr inline char* strstr_constexpr(char* str, const char* target) {
+ // https://github.com/freebsd/freebsd/blob/master/sys/libkern/strstr.c
+ if (char c = target != nullptr ? *target++ : '\0'; c != '\0' && str != nullptr) {
+ std::size_t len = strlen_constexpr(target);
+ do {
+ char sc = {};
+ do {
+ if ((sc = *str++) == '\0') {
+ return nullptr;
+ }
+ } while (sc != c);
+ } while (strncmp_constexpr(str, target, len) != 0);
+ --str;
+ }
+ return str;
+}
diff --git a/Marlin/src/HAL/NATIVE_SIM/MarlinSPI.h b/Marlin/src/HAL/NATIVE_SIM/MarlinSPI.h
new file mode 100644
index 000000000000..b5cc6f02a45a
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2021 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 .
+ *
+ */
+#pragma once
+
+#include
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/NATIVE_SIM/fastio.h b/Marlin/src/HAL/NATIVE_SIM/fastio.h
new file mode 100644
index 000000000000..de8013b1e542
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/fastio.h
@@ -0,0 +1,111 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+/**
+ * Fast I/O Routines for X86_64
+ */
+
+#include "../shared/Marduino.h"
+#include
+
+#define SET_DIR_INPUT(IO) Gpio::setDir(IO, 1)
+#define SET_DIR_OUTPUT(IO) Gpio::setDir(IO, 0)
+
+#define SET_MODE(IO, mode) Gpio::setMode(IO, mode)
+
+#define WRITE_PIN_SET(IO) Gpio::set(IO)
+#define WRITE_PIN_CLR(IO) Gpio::clear(IO)
+
+#define READ_PIN(IO) Gpio::get(IO)
+#define WRITE_PIN(IO,V) 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 http://gcc.gnu.org/onlinedocs/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) _WRITE(IO, !READ(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)
+
+// hg42: all pins can be input or output (I hope)
+// hg42: undefined pins create compile error (IO, is no pin)
+// hg42: currently not used, but was used by pinsDebug
+
+/// check if pin is an input
+#define _IS_INPUT(IO) (IO >= 0)
+
+/// check if pin is an output
+#define _IS_OUTPUT(IO) (IO >= 0)
+
+/// 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(IO) SET_OUTPUT(IO)
+
+/// 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)
diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
similarity index 82%
rename from Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h
rename to Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
index a9f1b5822215..1ac02f118285 100644
--- a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_LCD.h
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -20,7 +20,3 @@
*
*/
#pragma once
-
-#if HAS_SPI_TFT || HAS_FSMC_TFT
- #error "Sorry! TFT displays are not available for HAL/STM32F4_F7."
-#endif
diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
similarity index 77%
rename from Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h
rename to Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
index 5f1c4b16019d..69b6b4848f6e 100644
--- a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_adv.h
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -20,3 +20,12 @@
*
*/
#pragma once
+
+// Add strcmp_P if missing
+#ifndef strcmp_P
+ #define strcmp_P(a, b) strcmp((a), (b))
+#endif
+
+#ifndef strcat_P
+ #define strcat_P(dest, src) strcat((dest), (src))
+#endif
diff --git a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
similarity index 76%
rename from Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h
rename to Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
index b5d808e21acc..1ac02f118285 100644
--- a/Marlin/src/HAL/STM32_F4_F7/inc/Conditionals_post.h
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -20,10 +20,3 @@
*
*/
#pragma once
-
-#if ENABLED(EEPROM_SETTINGS) && defined(STM32F7)
- #undef USE_WIRED_EEPROM
- #undef SRAM_EEPROM_EMULATION
- #undef SDCARD_EEPROM_EMULATION
- #define FLASH_EEPROM_EMULATION
-#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h b/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
new file mode 100644
index 000000000000..104af9af5b20
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/SanityCheck.h
@@ -0,0 +1,43 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+/**
+ * Test X86_64-specific configuration values for errors at compile-time.
+ */
+
+// Emulating RAMPS
+#if ENABLED(SPINDLE_LASER_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 ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
+ #error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on LINUX."
+#endif
+
+#if HAS_TMC_SW_SERIAL
+ #error "TMC220x Software Serial is not supported on LINUX."
+#endif
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+ #error "POSTMORTEM_DEBUGGING is not yet supported on LINUX."
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
new file mode 100644
index 000000000000..7ba14574d0c7
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h
@@ -0,0 +1,61 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * 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 .
+ *
+ */
+
+/**
+ * Support routines for X86_64
+ */
+
+#pragma once
+
+/**
+ * Translation of routines & variables used by pinsDebug.h
+ */
+
+#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
+#define pwm_details(pin) pin = pin // do nothing // print PWM details
+#define pwm_status(pin) false //Print a pin's PWM status. Return true if it's currently a PWM pin.
+#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
+#define digitalRead_mod(p) digitalRead(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("%3d "), p); SERIAL_ECHO(buffer); }while(0)
+#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
+
+// active ADC function/mode/code values for PINSEL registers
+inline constexpr int8_t ADC_pin_mode(pin_t pin) {
+ return (-1);
+}
+
+inline int8_t get_pin_mode(pin_t pin) {
+ if (!VALID_PIN(pin)) return -1;
+ return 0;
+}
+
+inline bool GET_PINMODE(pin_t pin) {
+ int8_t pin_mode = get_pin_mode(pin);
+ if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin
+ return false;
+
+ return (Gpio::getMode(pin) != 0); //input/output state
+}
+
+inline bool GET_ARRAY_IS_DIGITAL(pin_t pin) {
+ return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
+}
diff --git a/Marlin/src/HAL/NATIVE_SIM/servo_private.h b/Marlin/src/HAL/NATIVE_SIM/servo_private.h
new file mode 100644
index 000000000000..06be1893f6eb
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/servo_private.h
@@ -0,0 +1,80 @@
+/**
+ * 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 .
+ *
+ */
+#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
+ */
+
+/**
+ * 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
+
+// Macros
+//values in microseconds
+#define MIN_PULSE_WIDTH 544 // the shortest pulse sent to a servo
+#define MAX_PULSE_WIDTH 2400 // the longest pulse sent to a servo
+#define DEFAULT_PULSE_WIDTH 1500 // default pulse width when servo is attached
+#define REFRESH_INTERVAL 20000 // minimum time to refresh servos in microseconds
+
+#define MAX_SERVOS 4
+
+#define INVALID_SERVO 255 // flag indicating an invalid servo index
+
+
+// Types
+
+typedef struct {
+ uint8_t nbr : 8 ; // a pin number from 0 to 254 (255 signals invalid pin)
+ uint8_t isActive : 1 ; // true if this channel is enabled, pin not pulsed if false
+} ServoPin_t;
+
+typedef struct {
+ ServoPin_t Pin;
+ unsigned int pulse_width; // pulse width in microseconds
+} ServoInfo_t;
+
+// Global variables
+
+extern uint8_t ServoCount;
+extern ServoInfo_t servo_info[MAX_SERVOS];
diff --git a/Marlin/src/HAL/NATIVE_SIM/spi_pins.h b/Marlin/src/HAL/NATIVE_SIM/spi_pins.h
new file mode 100644
index 000000000000..a5138e0ccbe8
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/spi_pins.h
@@ -0,0 +1,55 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+#include "../../core/macros.h"
+#include "../../inc/MarlinConfigPre.h"
+
+#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (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
+//#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 SD
+#ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 50
+#endif
+#ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 51
+#endif
+#ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 52
+#endif
+#ifndef SD_SS_PIN
+ #define SD_SS_PIN 53
+#endif
+#ifndef SDSS
+ #define SDSS SD_SS_PIN
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/tft/tft_spi.h b/Marlin/src/HAL/NATIVE_SIM/tft/tft_spi.h
new file mode 100644
index 000000000000..b3e622f19ac4
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/tft/tft_spi.h
@@ -0,0 +1,64 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+#include "../../../inc/MarlinConfig.h"
+
+#ifndef LCD_READ_ID
+ #define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
+#endif
+#ifndef LCD_READ_ID4
+ #define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
+#endif
+
+#define DATASIZE_8BIT 8
+#define DATASIZE_16BIT 16
+#define TFT_IO_DRIVER TFT_SPI
+
+#define DMA_MINC_ENABLE 1
+#define DMA_MINC_DISABLE 0
+
+class TFT_SPI {
+private:
+ static uint32_t ReadID(uint16_t Reg);
+ static void Transmit(uint16_t Data);
+ static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
+
+public:
+ // static SPIClass SPIx;
+
+ static void Init();
+ static uint32_t GetID();
+ static bool isBusy();
+ static void Abort();
+
+ static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT);
+ static void DataTransferEnd();
+ static void DataTransferAbort();
+
+ static void WriteData(uint16_t Data);
+ static void WriteReg(uint16_t Reg);
+
+ static void WriteSequence(uint16_t *Data, uint16_t Count);
+ // static void WriteMultiple(uint16_t Color, uint16_t Count);
+ static void WriteMultiple(uint16_t Color, uint32_t Count);
+};
diff --git a/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h b/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h
new file mode 100644
index 000000000000..9ef1816c7b16
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/tft/xpt2046.h
@@ -0,0 +1,80 @@
+/**
+ * Marlin 3D Printer Firmware
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ *
+ * 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 .
+ *
+ */
+#pragma once
+
+#include "../../../inc/MarlinConfig.h"
+
+#if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ #include
+#endif
+
+#ifndef TOUCH_MISO_PIN
+ #define TOUCH_MISO_PIN SD_MISO_PIN
+#endif
+#ifndef TOUCH_MOSI_PIN
+ #define TOUCH_MOSI_PIN SD_MOSI_PIN
+#endif
+#ifndef TOUCH_SCK_PIN
+ #define TOUCH_SCK_PIN SD_SCK_PIN
+#endif
+#ifndef TOUCH_CS_PIN
+ #define TOUCH_CS_PIN SD_SS_PIN
+#endif
+#ifndef TOUCH_INT_PIN
+ #define TOUCH_INT_PIN -1
+#endif
+
+#define XPT2046_DFR_MODE 0x00
+#define XPT2046_SER_MODE 0x04
+#define XPT2046_CONTROL 0x80
+
+enum XPTCoordinate : uint8_t {
+ XPT2046_X = 0x10 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+ XPT2046_Y = 0x50 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+ XPT2046_Z1 = 0x30 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+ XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
+};
+
+#if !defined(XPT2046_Z1_THRESHOLD)
+ #define XPT2046_Z1_THRESHOLD 10
+#endif
+
+class XPT2046 {
+private:
+ static bool isBusy() { return false; }
+
+ static uint16_t getRawData(const XPTCoordinate coordinate);
+ static bool isTouched();
+
+ static inline void DataTransferBegin();
+ static inline void DataTransferEnd();
+ #if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ static uint16_t HardwareIO(uint16_t data);
+ #endif
+ static uint16_t SoftwareIO(uint16_t data);
+ static uint16_t IO(uint16_t data = 0);
+
+public:
+ #if ENABLED(TOUCH_BUTTONS_HW_SPI)
+ static SPIClass SPIx;
+ #endif
+
+ static void Init();
+ static bool getRawPoint(int16_t *x, int16_t *y);
+};
diff --git a/Marlin/src/HAL/NATIVE_SIM/timers.h b/Marlin/src/HAL/NATIVE_SIM/timers.h
new file mode 100644
index 000000000000..c61eb29e76cf
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/timers.h
@@ -0,0 +1,91 @@
+/**
+ * Marlin 3D Printer Firmware
+ *
+ * Copyright (c) 2021 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 .
+ *
+ */
+#pragma once
+
+/**
+ * HAL timers for Linux X86_64
+ */
+
+#include
+
+// ------------------------
+// Defines
+// ------------------------
+
+#define FORCE_INLINE __attribute__((always_inline)) inline
+
+typedef uint64_t hal_timer_t;
+#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFF
+
+#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
+
+#ifndef STEP_TIMER_NUM
+ #define STEP_TIMER_NUM 0 // Timer Index for Stepper
+#endif
+#ifndef PULSE_TIMER_NUM
+ #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#endif
+#ifndef TEMP_TIMER_NUM
+ #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
+#endif
+#ifndef SYSTICK_TIMER_NUM
+ #define SYSTICK_TIMER_NUM 2 // Timer Index for Systick
+#endif
+#define SYSTICK_TIMER_FREQUENCY 1000
+
+#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(STEP_TIMER_NUM)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
+
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+
+#ifndef HAL_STEP_TIMER_ISR
+ #define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler()
+#endif
+#ifndef HAL_TEMP_TIMER_ISR
+ #define HAL_TEMP_TIMER_ISR() extern "C" void TIMER1_IRQHandler()
+#endif
+
+void HAL_timer_init();
+void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
+
+void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare);
+hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
+hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
+
+void HAL_timer_enable_interrupt(const uint8_t timer_num);
+void HAL_timer_disable_interrupt(const uint8_t timer_num);
+bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
+
+#define HAL_timer_isr_prologue(TIMER_NUM)
+#define HAL_timer_isr_epilogue(TIMER_NUM)
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp
new file mode 100644
index 000000000000..745454394aae
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.cpp
@@ -0,0 +1,52 @@
+/**
+ * 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 .
+ *
+ */
+
+// 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 __PLAT_NATIVE_SIM__
+
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+uint8_t u8g_i2c_start(const uint8_t sla) {
+ return 1;
+}
+
+void u8g_i2c_init(const uint8_t clock_option) {
+}
+
+uint8_t u8g_i2c_send_byte(uint8_t data) {
+ return 1;
+}
+
+void u8g_i2c_stop() {
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h
new file mode 100644
index 000000000000..6d5f91d3ba45
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_I2C_routines.h
@@ -0,0 +1,37 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+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();
+
+#ifdef __cplusplus
+ }
+#endif
+
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_defines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_defines.h
new file mode 100644
index 000000000000..44ffbfeb90e5
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_defines.h
@@ -0,0 +1,44 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+void usleep(uint64_t microsec);
+// The following are optional depending on the platform.
+
+// definitions of HAL specific com and device drivers.
+uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+uint8_t u8g_com_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
+
+// connect U8g com generic com names to the desired driver
+#define U8G_COM_SW_SPI u8g_com_sw_spi_fn
+#define U8G_COM_ST7920_SW_SPI u8g_com_ST7920_sw_spi_fn
+
+// let these default for now
+#define U8G_COM_HW_SPI u8g_com_null_fn
+#define U8G_COM_ST7920_HW_SPI u8g_com_null_fn
+#define U8G_COM_SSD_I2C u8g_com_null_fn
+#define U8G_COM_PARALLEL u8g_com_null_fn
+#define U8G_COM_T6963 u8g_com_null_fn
+#define U8G_COM_FAST_PARALLEL u8g_com_null_fn
+#define U8G_COM_UC_I2C u8g_com_null_fn
+
+
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_delay.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_delay.h
new file mode 100644
index 000000000000..297361cd448f
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_delay.h
@@ -0,0 +1,43 @@
+/**
+ * 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 .
+ *
+ */
+#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
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp
new file mode 100644
index 000000000000..3b5acc1656cd
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.cpp
@@ -0,0 +1,52 @@
+/**
+ * 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 .
+ *
+ */
+
+/**
+ * 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 __PLAT_NATIVE_SIM__
+
+#include "../fastio.h"
+#include "LCD_pin_routines.h"
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+void u8g_SetPinOutput(uint8_t internal_pin_number){SET_DIR_OUTPUT(internal_pin_number);}
+void u8g_SetPinInput(uint8_t internal_pin_number){SET_DIR_INPUT(internal_pin_number);}
+void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status){WRITE_PIN(pin, pin_status);}
+uint8_t u8g_GetPinLevel(uint8_t pin){return READ_PIN(pin);}
+void usleep(uint64_t microsec){
+assert(false); // why we here?
+}
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h
new file mode 100644
index 000000000000..c27c84e8c398
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/LCD_pin_routines.h
@@ -0,0 +1,46 @@
+/**
+ * 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 .
+ *
+ */
+#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.
+ */
+
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+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);
+
+#ifdef __cplusplus
+ }
+#endif
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
new file mode 100644
index 000000000000..c77c3d30f09a
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_st7920_sw_spi.cpp
@@ -0,0 +1,171 @@
+/**
+ * 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 .
+ *
+ */
+
+/**
+ * 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 __PLAT_NATIVE_SIM__
+
+#include "../../../inc/MarlinConfig.h"
+
+#if ENABLED(U8GLIB_ST7920)
+
+#include
+#include "../../shared/Delay.h"
+
+#undef SPI_SPEED
+#define SPI_SPEED 6
+#define SPI_DELAY_CYCLES (1 + SPI_SPEED * 10)
+
+static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
+static uint8_t SPI_speed = 0;
+
+static 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++) {
+ WRITE_PIN(mosi_pin, !!(b & 0x80));
+ DELAY_CYCLES(SPI_SPEED);
+ WRITE_PIN(sck_pin, HIGH);
+ DELAY_CYCLES(SPI_SPEED);
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+ WRITE_PIN(sck_pin, LOW);
+ DELAY_CYCLES(SPI_SPEED);
+ }
+ return b;
+}
+
+static uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) {
+ WRITE_PIN(mosi_pin, HIGH);
+ WRITE_PIN(sck_pin, LOW);
+ return spiRate;
+}
+
+static void u8g_com_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);
+}
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+uint8_t u8g_com_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(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_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_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_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
+ arg_val--;
+ }
+ }
+ break;
+ }
+ return 1;
+}
+#ifdef __cplusplus
+ }
+#endif
+
+#endif // U8GLIB_ST7920
+#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
new file mode 100644
index 000000000000..085954803cf2
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
@@ -0,0 +1,215 @@
+/**
+ * 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 .
+ *
+ */
+
+/**
+ * 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 __PLAT_NATIVE_SIM__
+
+#include "../../../inc/MarlinConfig.h"
+
+#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
+
+#undef SPI_SPEED
+#define SPI_SPEED 2 // About 2 MHz
+
+#include
+#include
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+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) {
+ WRITE_PIN(mosi_pin, !!(b & 0x80));
+ WRITE_PIN(sck_pin, HIGH);
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+ WRITE_PIN(sck_pin, LOW);
+ }
+ else {
+ const uint8_t state = (b & 0x80) ? HIGH : LOW;
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(mosi_pin, state);
+
+ LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
+ WRITE_PIN(sck_pin, HIGH);
+
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(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) {
+ WRITE_PIN(sck_pin, LOW);
+ WRITE_PIN(mosi_pin, state);
+ WRITE_PIN(mosi_pin, state); // need some setup time
+ WRITE_PIN(sck_pin, HIGH);
+ }
+ else {
+ LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
+ WRITE_PIN(sck_pin, LOW);
+
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(mosi_pin, state);
+
+ LOOP_L_N(j, spi_speed)
+ WRITE_PIN(sck_pin, HIGH);
+ }
+ b <<= 1;
+ if (miso_pin >= 0 && READ_PIN(miso_pin)) b |= 1;
+ }
+
+ return b;
+}
+
+static uint8_t SPI_speed = 0;
+
+static uint8_t swSpiInit(const uint8_t spi_speed, const uint8_t clk_pin, const uint8_t mosi_pin) {
+ return spi_speed;
+}
+
+static void u8g_sw_spi_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
+ #if EITHER(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_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(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 EITHER(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_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_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_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;
+}
+
+#ifdef __cplusplus
+ }
+#endif
+
+#elif !ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI, HAS_MARLINUI_HD44780) && HAS_MARLINUI_U8GLIB
+ #include
+ uint8_t u8g_com_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {return 0;}
+#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/STM32_F4_F7/watchdog.h b/Marlin/src/HAL/NATIVE_SIM/watchdog.h
similarity index 88%
rename from Marlin/src/HAL/STM32_F4_F7/watchdog.h
rename to Marlin/src/HAL/NATIVE_SIM/watchdog.h
index 3dbc2d08c139..4e404c3887da 100644
--- a/Marlin/src/HAL/STM32_F4_F7/watchdog.h
+++ b/Marlin/src/HAL/NATIVE_SIM/watchdog.h
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
- * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
+ * Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -21,7 +21,7 @@
*/
#pragma once
-extern IWDG_HandleTypeDef hiwdg;
+#define WDT_TIMEOUT 4000000 // 4 second timeout
void watchdog_init();
void HAL_watchdog_refresh();
diff --git a/Marlin/src/HAL/SAMD51/HAL.cpp b/Marlin/src/HAL/SAMD51/HAL.cpp
index 9f24d30071a6..8baad31bc751 100644
--- a/Marlin/src/HAL/SAMD51/HAL.cpp
+++ b/Marlin/src/HAL/SAMD51/HAL.cpp
@@ -24,6 +24,24 @@
#include
#include
+#ifdef ADAFRUIT_GRAND_CENTRAL_M4
+ #if USING_HW_SERIALUSB
+ DefaultSerial1 MSerial0(false, Serial);
+ #endif
+ #if USING_HW_SERIAL0
+ DefaultSerial2 MSerial1(false, Serial1);
+ #endif
+ #if USING_HW_SERIAL1
+ DefaultSerial3 MSerial2(false, Serial2);
+ #endif
+ #if USING_HW_SERIAL2
+ DefaultSerial4 MSerial3(false, Serial3);
+ #endif
+ #if USING_HW_SERIAL3
+ DefaultSerial5 MSerial4(false, Serial4);
+ #endif
+#endif
+
// ------------------------
// Local defines
// ------------------------
@@ -39,6 +57,7 @@
#define GET_PROBE_ADC() TERN(HAS_TEMP_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1)
#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1)
#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1)
+#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1)
#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1)
#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1)
@@ -48,6 +67,7 @@
|| GET_PROBE_ADC() == n \
|| GET_BED_ADC() == n \
|| GET_CHAMBER_ADC() == n \
+ || GET_COOLER_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n \
|| GET_BUTTONS_ADC() == n \
)
@@ -78,7 +98,7 @@
// Struct must be 32 bits aligned because of DMA accesses but fields needs to be 8 bits packed
typedef struct __attribute__((aligned(4), packed)) {
ADC_INPUTCTRL_Type INPUTCTRL;
- } HAL_DMA_DAC_Registers; // DMA transfered registers
+ } HAL_DMA_DAC_Registers; // DMA transferred registers
#endif
@@ -126,6 +146,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 0
TEMP_CHAMBER_PIN,
#endif
+ #if GET_COOLER_ADC() == 0
+ TEMP_COOLER_PIN,
+ #endif
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH_PIN,
#endif
@@ -166,6 +189,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 1
TEMP_CHAMBER_PIN,
#endif
+ #if GET_COOLER_ADC() == 1
+ TEMP_COOLER_PIN,
+ #endif
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH_PIN,
#endif
@@ -214,6 +240,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
+ #if GET_COOLER_ADC() == 0
+ { PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
+ #endif
#if GET_FILAMENT_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
@@ -263,6 +292,9 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
+ #if GET_COOLER_ADC() == 1
+ { PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
+ #endif
#if GET_FILAMENT_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
@@ -300,7 +332,7 @@ uint16_t HAL_adc_result;
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_SRC // STEPSEL
);
- if (descriptor != nullptr)
+ if (descriptor)
descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
adc0DMAProgram.startJob();
}
@@ -337,7 +369,7 @@ uint16_t HAL_adc_result;
DMA_ADDRESS_INCREMENT_STEP_SIZE_1, // STEPSIZE
DMA_STEPSEL_SRC // STEPSEL
);
- if (descriptor != nullptr)
+ if (descriptor)
descriptor->BTCTRL.bit.EVOSEL = DMA_EVENT_OUTPUT_BEAT;
adc1DMAProgram.startJob();
}
@@ -404,6 +436,8 @@ uint8_t HAL_get_reset_source() {
}
#pragma pop_macro("WDT")
+void HAL_reboot() { NVIC_SystemReset(); }
+
extern "C" {
void * _sbrk(int incr);
diff --git a/Marlin/src/HAL/SAMD51/HAL.h b/Marlin/src/HAL/SAMD51/HAL.h
index 7cb3635bd7c9..491c3f82c4a6 100644
--- a/Marlin/src/HAL/SAMD51/HAL.h
+++ b/Marlin/src/HAL/SAMD51/HAL.h
@@ -32,38 +32,56 @@
#include "MarlinSerial_AGCM4.h"
// Serial ports
-
- // MYSERIAL0 required before MarlinSerial includes!
-
- #define __MSERIAL(X) Serial##X
+ typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
+ typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
+ typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
+ typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
+ typedef ForwardSerial1Class< decltype(Serial4) > DefaultSerial5;
+ extern DefaultSerial1 MSerial0;
+ extern DefaultSerial2 MSerial1;
+ extern DefaultSerial3 MSerial2;
+ extern DefaultSerial4 MSerial3;
+ extern DefaultSerial5 MSerial4;
+
+ #define __MSERIAL(X) MSerial##X
#define _MSERIAL(X) __MSERIAL(X)
#define MSERIAL(X) _MSERIAL(INCREMENT(X))
#if SERIAL_PORT == -1
- #define MYSERIAL0 Serial
+ #define MYSERIAL1 MSerial0
#elif WITHIN(SERIAL_PORT, 0, 3)
- #define MYSERIAL0 MSERIAL(SERIAL_PORT)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
- #error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #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 MYSERIAL1 Serial
+ #define MYSERIAL2 MSerial0
#elif WITHIN(SERIAL_PORT_2, 0, 3)
- #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
+ #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 MMU2_SERIAL_PORT
+ #if MMU2_SERIAL_PORT == -1
+ #define MMU2_SERIAL MSerial0
+ #elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
- #error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
+ #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 Serial
+ #define LCD_SERIAL MSerial0
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
@@ -89,7 +107,7 @@ typedef int8_t pin_t;
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot();
//
// ADC
@@ -135,10 +153,16 @@ void HAL_idletask();
//
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wunused-function"
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic push
+ #pragma GCC diagnostic ignored "-Wunused-function"
+#endif
+
int freeMemory();
-#pragma GCC diagnostic pop
+
+#if GCC_VERSION <= 50000
+ #pragma GCC diagnostic pop
+#endif
#ifdef __cplusplus
extern "C" {
diff --git a/Marlin/src/HAL/SAMD51/HAL_SPI.cpp b/Marlin/src/HAL/SAMD51/HAL_SPI.cpp
index c3acd38237c6..77f4d5ecd513 100644
--- a/Marlin/src/HAL/SAMD51/HAL_SPI.cpp
+++ b/Marlin/src/HAL/SAMD51/HAL_SPI.cpp
@@ -103,7 +103,7 @@
* @param nbyte Number of bytes to receive.
* @return Nothing
*/
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
if (nbyte == 0) return;
memset(buf, 0xFF, nbyte);
sdSPI.beginTransaction(spiConfig);
@@ -132,7 +132,7 @@
*
* @details Uses DMA
*/
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
sdSPI.beginTransaction(spiConfig);
sdSPI.transfer(token);
sdSPI.transfer((uint8_t*)buf, nullptr, 512);
diff --git a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp
index abc5f3acbf77..a16ea2f75821 100644
--- a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp
+++ b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.cpp
@@ -21,30 +21,30 @@
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
/**
- * Framework doesn't define some serial to save sercom resources
+ * Framework doesn't define some serials to save sercom resources
* hence if these are used I need to define them
*/
#include "../../inc/MarlinConfig.h"
-#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1
- Uart Serial2(&sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
+#if USING_HW_SERIAL1
+ UartT Serial2(false, &sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
void SERCOM4_0_Handler() { Serial2.IrqHandler(); }
void SERCOM4_1_Handler() { Serial2.IrqHandler(); }
void SERCOM4_2_Handler() { Serial2.IrqHandler(); }
void SERCOM4_3_Handler() { Serial2.IrqHandler(); }
#endif
-#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2
- Uart Serial3(&sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
+#if USING_HW_SERIAL2
+ UartT Serial3(false, &sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
void SERCOM1_0_Handler() { Serial3.IrqHandler(); }
void SERCOM1_1_Handler() { Serial3.IrqHandler(); }
void SERCOM1_2_Handler() { Serial3.IrqHandler(); }
void SERCOM1_3_Handler() { Serial3.IrqHandler(); }
#endif
-#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3
- Uart Serial4(&sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
+#if USING_HW_SERIAL3
+ UartT Serial4(false, &sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
void SERCOM5_0_Handler() { Serial4.IrqHandler(); }
void SERCOM5_1_Handler() { Serial4.IrqHandler(); }
void SERCOM5_2_Handler() { Serial4.IrqHandler(); }
diff --git a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h
index f3821d8d5a84..ac5a3793983e 100644
--- a/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h
+++ b/Marlin/src/HAL/SAMD51/MarlinSerial_AGCM4.h
@@ -20,6 +20,10 @@
*/
#pragma once
-extern Uart Serial2;
-extern Uart Serial3;
-extern Uart Serial4;
+#include "../../core/serial_hook.h"
+
+typedef Serial1Class UartT;
+
+extern UartT Serial2;
+extern UartT Serial3;
+extern UartT Serial4;
diff --git a/Marlin/src/HAL/SAMD51/QSPIFlash.cpp b/Marlin/src/HAL/SAMD51/QSPIFlash.cpp
index 307eb3fd45f2..fc21a1ad8c80 100644
--- a/Marlin/src/HAL/SAMD51/QSPIFlash.cpp
+++ b/Marlin/src/HAL/SAMD51/QSPIFlash.cpp
@@ -35,10 +35,10 @@ uint8_t QSPIFlash::_buf[SFLASH_SECTOR_SIZE];
uint32_t QSPIFlash::_addr = INVALID_ADDR;
void QSPIFlash::begin() {
- if (_flashBase != nullptr) return;
+ if (_flashBase) return;
_flashBase = new Adafruit_SPIFlashBase(new Adafruit_FlashTransport_QSPI());
- _flashBase->begin(NULL);
+ _flashBase->begin(nullptr);
}
size_t QSPIFlash::size() {
diff --git a/Marlin/src/HAL/SAMD51/eeprom_flash.cpp b/Marlin/src/HAL/SAMD51/eeprom_flash.cpp
index 429ef1c2d4f7..871bf22b7fc4 100644
--- a/Marlin/src/HAL/SAMD51/eeprom_flash.cpp
+++ b/Marlin/src/HAL/SAMD51/eeprom_flash.cpp
@@ -79,7 +79,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
SYNC(NVMCTRL->SEESTAT.bit.BUSY);
uint8_t c = ((volatile uint8_t *)SEEPROM_ADDR)[pos];
diff --git a/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp b/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp
index b403f7939fb9..faa763719707 100644
--- a/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp
+++ b/Marlin/src/HAL/SAMD51/eeprom_qspi.cpp
@@ -56,7 +56,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = qspi.readByte(pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/SAMD51/eeprom_wired.cpp b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
index 3283195897b0..3481fe539c3e 100644
--- a/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
+++ b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
@@ -41,12 +41,13 @@ bool PersistentStore::access_start() { eeprom_init(); return true; }
bool PersistentStore::access_finish() { return true; }
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
+ uint16_t written = 0;
while (size--) {
const uint8_t v = *value;
uint8_t * const p = (uint8_t * const)pos;
- if (v != eeprom_read_byte(p)) {
+ if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
eeprom_write_byte(p, v);
- delay(2);
+ if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
if (eeprom_read_byte(p) != v) {
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
return true;
@@ -59,7 +60,7 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
return false;
}
-bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
+bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
while (size--) {
uint8_t c = eeprom_read_byte((uint8_t*)pos);
if (writing) *value = c;
diff --git a/Marlin/src/HAL/SAMD51/endstop_interrupts.h b/Marlin/src/HAL/SAMD51/endstop_interrupts.h
index daac7733875b..c46b6e072f90 100644
--- a/Marlin/src/HAL/SAMD51/endstop_interrupts.h
+++ b/Marlin/src/HAL/SAMD51/endstop_interrupts.h
@@ -47,80 +47,38 @@
#include "../../module/endstops.h"
-#define MATCH_EILINE(P1,P2) (P1 != P2 && PIN_TO_EILINE(P1) == PIN_TO_EILINE(P2))
-#if HAS_X_MAX
- #define MATCH_X_MAX_EILINE(P) MATCH_EILINE(P, X_MAX_PIN)
-#else
- #define MATCH_X_MAX_EILINE(P) false
-#endif
-#if HAS_X_MIN
- #define MATCH_X_MIN_EILINE(P) MATCH_EILINE(P, X_MIN_PIN)
-#else
- #define MATCH_X_MIN_EILINE(P) false
-#endif
-#if HAS_Y_MAX
- #define MATCH_Y_MAX_EILINE(P) MATCH_EILINE(P, Y_MAX_PIN)
-#else
- #define MATCH_Y_MAX_EILINE(P) false
-#endif
-#if HAS_Y_MIN
- #define MATCH_Y_MIN_EILINE(P) MATCH_EILINE(P, Y_MIN_PIN)
-#else
- #define MATCH_Y_MIN_EILINE(P) false
-#endif
-#if HAS_Z_MAX
- #define MATCH_Z_MAX_EILINE(P) MATCH_EILINE(P, Z_MAX_PIN)
-#else
- #define MATCH_Z_MAX_EILINE(P) false
-#endif
-#if HAS_Z_MIN
- #define MATCH_Z_MIN_EILINE(P) MATCH_EILINE(P, Z_MIN_PIN)
-#else
- #define MATCH_Z_MIN_EILINE(P) false
-#endif
-#if HAS_Z2_MAX
- #define MATCH_Z2_MAX_EILINE(P) MATCH_EILINE(P, Z2_MAX_PIN)
-#else
- #define MATCH_Z2_MAX_EILINE(P) false
-#endif
-#if HAS_Z2_MIN
- #define MATCH_Z2_MIN_EILINE(P) MATCH_EILINE(P, Z2_MIN_PIN)
-#else
- #define MATCH_Z2_MIN_EILINE(P) false
-#endif
-#if HAS_Z3_MAX
- #define MATCH_Z3_MAX_EILINE(P) MATCH_EILINE(P, Z3_MAX_PIN)
-#else
- #define MATCH_Z3_MAX_EILINE(P) false
-#endif
-#if HAS_Z3_MIN
- #define MATCH_Z3_MIN_EILINE(P) MATCH_EILINE(P, Z3_MIN_PIN)
-#else
- #define MATCH_Z3_MIN_EILINE(P) false
-#endif
-#if HAS_Z4_MAX
- #define MATCH_Z4_MAX_EILINE(P) MATCH_EILINE(P, Z4_MAX_PIN)
-#else
- #define MATCH_Z4_MAX_EILINE(P) false
-#endif
-#if HAS_Z4_MIN
- #define MATCH_Z4_MIN_EILINE(P) MATCH_EILINE(P, Z4_MIN_PIN)
-#else
- #define MATCH_Z4_MIN_EILINE(P) false
-#endif
-#if HAS_Z_MIN_PROBE_PIN
- #define MATCH_Z_MIN_PROBE_EILINE(P) MATCH_EILINE(P, Z_MIN_PROBE_PIN)
-#else
- #define MATCH_Z_MIN_PROBE_EILINE(P) false
-#endif
-#define AVAILABLE_EILINE(P) (PIN_TO_EILINE(P) != -1 \
- && !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \
- && !MATCH_Y_MAX_EILINE(P) && !MATCH_Y_MIN_EILINE(P) \
- && !MATCH_Z_MAX_EILINE(P) && !MATCH_Z_MIN_EILINE(P) \
- && !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \
- && !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \
- && !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \
- && !MATCH_Z_MIN_PROBE_EILINE(P))
+#define MATCH_EILINE(P1,P2) (P1 != P2 && PIN_TO_EILINE(P1) == PIN_TO_EILINE(P2))
+#define MATCH_X_MAX_EILINE(P) TERN0(HAS_X_MAX, DEFER4(MATCH_EILINE)(P, X_MAX_PIN))
+#define MATCH_X_MIN_EILINE(P) TERN0(HAS_X_MIN, DEFER4(MATCH_EILINE)(P, X_MIN_PIN))
+#define MATCH_Y_MAX_EILINE(P) TERN0(HAS_Y_MAX, DEFER4(MATCH_EILINE)(P, Y_MAX_PIN))
+#define MATCH_Y_MIN_EILINE(P) TERN0(HAS_Y_MIN, DEFER4(MATCH_EILINE)(P, Y_MIN_PIN))
+#define MATCH_Z_MAX_EILINE(P) TERN0(HAS_Z_MAX, DEFER4(MATCH_EILINE)(P, Z_MAX_PIN))
+#define MATCH_Z_MIN_EILINE(P) TERN0(HAS_Z_MIN, DEFER4(MATCH_EILINE)(P, Z_MIN_PIN))
+#define MATCH_I_MAX_EILINE(P) TERN0(HAS_I_MAX, DEFER4(MATCH_EILINE)(P, I_MAX_PIN))
+#define MATCH_I_MIN_EILINE(P) TERN0(HAS_I_MIN, DEFER4(MATCH_EILINE)(P, I_MIN_PIN))
+#define MATCH_J_MAX_EILINE(P) TERN0(HAS_J_MAX, DEFER4(MATCH_EILINE)(P, J_MAX_PIN))
+#define MATCH_J_MIN_EILINE(P) TERN0(HAS_J_MIN, DEFER4(MATCH_EILINE)(P, J_MIN_PIN))
+#define MATCH_K_MAX_EILINE(P) TERN0(HAS_K_MAX, DEFER4(MATCH_EILINE)(P, K_MAX_PIN))
+#define MATCH_K_MIN_EILINE(P) TERN0(HAS_K_MIN, DEFER4(MATCH_EILINE)(P, K_MIN_PIN))
+#define MATCH_Z2_MAX_EILINE(P) TERN0(HAS_Z2_MAX, DEFER4(MATCH_EILINE)(P, Z2_MAX_PIN))
+#define MATCH_Z2_MIN_EILINE(P) TERN0(HAS_Z2_MIN, DEFER4(MATCH_EILINE)(P, Z2_MIN_PIN))
+#define MATCH_Z3_MAX_EILINE(P) TERN0(HAS_Z3_MAX, DEFER4(MATCH_EILINE)(P, Z3_MAX_PIN))
+#define MATCH_Z3_MIN_EILINE(P) TERN0(HAS_Z3_MIN, DEFER4(MATCH_EILINE)(P, Z3_MIN_PIN))
+#define MATCH_Z4_MAX_EILINE(P) TERN0(HAS_Z4_MAX, DEFER4(MATCH_EILINE)(P, Z4_MAX_PIN))
+#define MATCH_Z4_MIN_EILINE(P) TERN0(HAS_Z4_MIN, DEFER4(MATCH_EILINE)(P, Z4_MIN_PIN))
+#define MATCH_Z_MIN_PROBE_EILINE(P) TERN0(HAS_Z_MIN_PROBE_PIN, DEFER4(MATCH_EILINE)(P, Z_MIN_PROBE_PIN))
+
+#define AVAILABLE_EILINE(P) ( PIN_TO_EILINE(P) != -1 \
+ && !MATCH_X_MAX_EILINE(P) && !MATCH_X_MIN_EILINE(P) \
+ && !MATCH_Y_MAX_EILINE(P) && !MATCH_Y_MIN_EILINE(P) \
+ && !MATCH_Z_MAX_EILINE(P) && !MATCH_Z_MIN_EILINE(P) \
+ && !MATCH_I_MAX_EILINE(P) && !MATCH_I_MIN_EILINE(P) \
+ && !MATCH_J_MAX_EILINE(P) && !MATCH_J_MIN_EILINE(P) \
+ && !MATCH_K_MAX_EILINE(P) && !MATCH_K_MIN_EILINE(P) \
+ && !MATCH_Z2_MAX_EILINE(P) && !MATCH_Z2_MIN_EILINE(P) \
+ && !MATCH_Z3_MAX_EILINE(P) && !MATCH_Z3_MIN_EILINE(P) \
+ && !MATCH_Z4_MAX_EILINE(P) && !MATCH_Z4_MIN_EILINE(P) \
+ && !MATCH_Z_MIN_PROBE_EILINE(P) )
// One ISR for all EXT-Interrupts
void endstop_ISR() { endstops.update(); }
@@ -204,5 +162,37 @@ void setup_endstop_interrupts() {
#error "Z_MIN_PROBE_PIN has no EXTINT line available."
#endif
_ATTACH(Z_MIN_PROBE_PIN);
+ #elif HAS_I_MAX
+ #if !AVAILABLE_EILINE(I_MAX_PIN)
+ #error "I_MAX_PIN has no EXTINT line available."
+ #endif
+ attachInterrupt(I_MAX_PIN, endstop_ISR, CHANGE);
+ #elif HAS_I_MIN
+ #if !AVAILABLE_EILINE(I_MIN_PIN)
+ #error "I_MIN_PIN has no EXTINT line available."
+ #endif
+ attachInterrupt(I_MIN_PIN, endstop_ISR, CHANGE);
+ #endif
+ #if HAS_J_MAX
+ #if !AVAILABLE_EILINE(J_MAX_PIN)
+ #error "J_MAX_PIN has no EXTINT line available."
+ #endif
+ attachInterrupt(J_MAX_PIN, endstop_ISR, CHANGE);
+ #elif HAS_J_MIN
+ #if !AVAILABLE_EILINE(J_MIN_PIN)
+ #error "J_MIN_PIN has no EXTINT line available."
+ #endif
+ attachInterrupt(J_MIN_PIN, endstop_ISR, CHANGE);
+ #endif
+ #if HAS_K_MAX
+ #if !AVAILABLE_EILINE(K_MAX_PIN)
+ #error "K_MAX_PIN has no EXTINT line available."
+ #endif
+ attachInterrupt(K_MAX_PIN, endstop_ISR, CHANGE);
+ #elif HAS_K_MIN
+ #if !AVAILABLE_EILINE(K_MIN_PIN)
+ #error "K_MIN_PIN has no EXTINT line available."
+ #endif
+ attachInterrupt(K_MIN_PIN, endstop_ISR, CHANGE);
#endif
}
diff --git a/Marlin/src/HAL/SAMD51/fastio.h b/Marlin/src/HAL/SAMD51/fastio.h
index c456dfce30cb..79aede579044 100644
--- a/Marlin/src/HAL/SAMD51/fastio.h
+++ b/Marlin/src/HAL/SAMD51/fastio.h
@@ -31,7 +31,7 @@
*/
#ifndef MASK
- #define MASK(PIN) (1 << PIN)
+ #define MASK(PIN) _BV(PIN)
#endif
/**
@@ -131,7 +131,7 @@
*/
#define PWM_PIN(P) (WITHIN(P, 2, 13) || WITHIN(P, 22, 23) || WITHIN(P, 44, 45) || P == 48)
- // Return fullfilled ADCx->INPUTCTRL.reg
+ // Return fulfilled ADCx->INPUTCTRL.reg
#define PIN_TO_INPUTCTRL(P) ( (PIN_TO_AIN(P) == 0) ? ADC_INPUTCTRL_MUXPOS_AIN0 \
: (PIN_TO_AIN(P) == 1) ? ADC_INPUTCTRL_MUXPOS_AIN1 \
: (PIN_TO_AIN(P) == 2) ? ADC_INPUTCTRL_MUXPOS_AIN2 \
diff --git a/Marlin/src/HAL/SAMD51/inc/SanityCheck.h b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h
index 5d610acac85c..38c6dd9e08de 100644
--- a/Marlin/src/HAL/SAMD51/inc/SanityCheck.h
+++ b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h
@@ -31,7 +31,8 @@
#error "No custom SD drive cable defined for this board."
#endif
-#if defined(MAX6675_SCK_PIN) && defined(MAX6675_DO_PIN) && (MAX6675_SCK_PIN == SCK1 || MAX6675_DO_PIN == MISO1)
+#if (defined(TEMP_0_SCK_PIN) && defined(TEMP_0_MISO_PIN) && (TEMP_0_SCK_PIN == SCK1 || TEMP_0_MISO_PIN == MISO1)) || \
+ (defined(TEMP_1_SCK_PIN) && defined(TEMP_1_MISO_PIN) && (TEMP_1_SCK_PIN == SCK1 || TEMP_1_MISO_PIN == MISO1))
#error "OnBoard SPI BUS can't be shared with other devices."
#endif
@@ -50,3 +51,7 @@
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on SAMD51."
#endif
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+ #error "POSTMORTEM_DEBUGGING is not yet supported on AGCM4."
+#endif
diff --git a/Marlin/src/HAL/SAMD51/spi_pins.h b/Marlin/src/HAL/SAMD51/spi_pins.h
index 5a9b1275ef88..2a667bcaa1ce 100644
--- a/Marlin/src/HAL/SAMD51/spi_pins.h
+++ b/Marlin/src/HAL/SAMD51/spi_pins.h
@@ -30,16 +30,16 @@
* SPI | 53 52 50 51 |
* SPI1 | 83 81 80 82 |
* +-------------------------+
- * Any pin can be used for Chip Select (SS_PIN)
+ * Any pin can be used for Chip Select (SD_SS_PIN)
*/
- #ifndef SCK_PIN
- #define SCK_PIN 52
+ #ifndef SD_SCK_PIN
+ #define SD_SCK_PIN 52
#endif
- #ifndef MISO_PIN
- #define MISO_PIN 50
+ #ifndef SD_MISO_PIN
+ #define SD_MISO_PIN 50
#endif
- #ifndef MOSI_PIN
- #define MOSI_PIN 51
+ #ifndef SD_MOSI_PIN
+ #define SD_MOSI_PIN 51
#endif
#ifndef SDSS
#define SDSS 53
@@ -51,4 +51,4 @@
#endif
-#define SS_PIN SDSS
+#define SD_SS_PIN SDSS
diff --git a/Marlin/src/HAL/SAMD51/timers.cpp b/Marlin/src/HAL/SAMD51/timers.cpp
index a68af2e074ae..7a535299db9a 100644
--- a/Marlin/src/HAL/SAMD51/timers.cpp
+++ b/Marlin/src/HAL/SAMD51/timers.cpp
@@ -107,7 +107,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
tc->COUNT32.INTENCLR.reg = TC_INTENCLR_OVF; // disable overflow interrupt
// TCn clock setup
- const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num]; // TC clock are preceeded by TCC ones
+ const uint8_t clockID = GCLK_CLKCTRL_IDs[TCC_INST_NUM + timer_num]; // TC clock are preceded by TCC ones
GCLK->PCHCTRL[clockID].bit.CHEN = false;
SYNC(GCLK->PCHCTRL[clockID].bit.CHEN);
GCLK->PCHCTRL[clockID].reg = GCLK_PCHCTRL_GEN_GCLK0 | GCLK_PCHCTRL_CHEN; // 120MHz startup code programmed
@@ -157,7 +157,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
- return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
+ return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
diff --git a/Marlin/src/HAL/SAMD51/watchdog.cpp b/Marlin/src/HAL/SAMD51/watchdog.cpp
index ebc8dffe1300..9de451836aeb 100644
--- a/Marlin/src/HAL/SAMD51/watchdog.cpp
+++ b/Marlin/src/HAL/SAMD51/watchdog.cpp
@@ -24,28 +24,30 @@
#if ENABLED(USE_WATCHDOG)
- #include "watchdog.h"
+#include "watchdog.h"
- void watchdog_init() {
- // The low-power oscillator used by the WDT runs at 32,768 Hz with
- // a 1:32 prescale, thus 1024 Hz, though probably not super precise.
+#define WDT_TIMEOUT_REG TERN(WATCHDOG_DURATION_8S, WDT_CONFIG_PER_CYC8192, WDT_CONFIG_PER_CYC4096) // 4 or 8 second timeout
- // Setup WDT clocks
- MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
- MCLK->APBAMASK.bit.WDT_ = true;
- OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
+void watchdog_init() {
+ // The low-power oscillator used by the WDT runs at 32,768 Hz with
+ // a 1:32 prescale, thus 1024 Hz, though probably not super precise.
- WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
- SYNC(WDT->SYNCBUSY.bit.ENABLE);
+ // Setup WDT clocks
+ MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
+ MCLK->APBAMASK.bit.WDT_ = true;
+ OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
- WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
- WDT->CONFIG.reg = WDT_CONFIG_PER_CYC4096; // Set at least 4s period for chip reset
+ WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
+ SYNC(WDT->SYNCBUSY.bit.ENABLE);
- HAL_watchdog_refresh();
+ WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
+ WDT->CONFIG.reg = WDT_TIMEOUT_REG; // Set a 4s or 8s period for chip reset
- WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
- SYNC(WDT->SYNCBUSY.bit.ENABLE);
- }
+ HAL_watchdog_refresh();
+
+ WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
+ SYNC(WDT->SYNCBUSY.bit.ENABLE);
+}
#endif // USE_WATCHDOG
diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp
index 83604b1104bb..a04a24c1123c 100644
--- a/Marlin/src/HAL/STM32/HAL.cpp
+++ b/Marlin/src/HAL/STM32/HAL.cpp
@@ -20,7 +20,9 @@
* along with this program. If not, see .
*
*/
-#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+#include "../platforms.h"
+
+#ifdef HAL_STM32
#include "HAL.h"
#include "usb_serial.h"
@@ -28,6 +30,10 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
+#ifdef USBCON
+ DefaultSerial1 MSerial0(false, SerialUSB);
+#endif
+
#if ENABLED(SRAM_EEPROM_EMULATION)
#if STM32F7xx
#include
@@ -38,6 +44,11 @@
#endif
#endif
+#if HAS_SD_HOST_DRIVE
+ #include "msc_sd.h"
+ #include "usbd_cdc_if.h"
+#endif
+
// ------------------------
// Public Variables
// ------------------------
@@ -48,20 +59,15 @@ uint16_t HAL_adc_result;
// Public functions
// ------------------------
-// Needed for DELAY_NS() / DELAY_US() on CORTEX-M7
-#if (defined(__arm__) || defined(__thumb__)) && __CORTEX_M == 7
- // HAL pre-initialization task
- // Force the preinit function to run between the premain() and main() function
- // of the STM32 arduino core
- __attribute__((constructor (102)))
- void HAL_preinit() {
- enableCycleCounter();
- }
-#endif
+TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
// HAL initialization task
void HAL_init() {
- FastIO_init();
+ // Ensure F_CPU is a constant expression.
+ // If the compiler breaks here, it means that delay code that should compute at compile time will not work.
+ // So better safe than sorry here.
+ constexpr int cpuFreq = F_CPU;
+ UNUSED(cpuFreq);
#if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT) && (defined(SDSS) && SDSS != -1)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
@@ -81,7 +87,28 @@ void HAL_init() {
SetTimerInterruptPriorities();
- TERN_(EMERGENCY_PARSER, USB_Hook_init());
+ #if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
+ USB_Hook_init();
+ #endif
+
+ TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
+
+ TERN_(HAS_SD_HOST_DRIVE, MSC_SD_init()); // Enable USB SD card access
+
+ #if PIN_EXISTS(USB_CONNECT)
+ OUT_WRITE(USB_CONNECT_PIN, !USB_CONNECT_INVERTING); // USB clear connection
+ delay(1000); // Give OS time to notice
+ WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING);
+ #endif
+}
+
+// HAL idle task
+void HAL_idletask() {
+ #if HAS_SHARED_MEDIA
+ // Stm32duino currently doesn't have a "loop/idle" method
+ CDC_resume_receive();
+ CDC_continue_transmit();
+ #endif
}
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
@@ -110,6 +137,8 @@ uint8_t HAL_get_reset_source() {
;
}
+void HAL_reboot() { NVIC_SystemReset(); }
+
void _delay_ms(const int delay_ms) { delay(delay_ms); }
extern "C" {
@@ -124,12 +153,16 @@ extern "C" {
void HAL_adc_start_conversion(const uint8_t adc_pin) { HAL_adc_result = analogRead(adc_pin); }
uint16_t HAL_adc_get_result() { return HAL_adc_result; }
-// Reset the system (to initiate a firmware flash)
-void flashFirmware(const int16_t) { NVIC_SystemReset(); }
+// Reset the system to initiate a firmware flash
+void flashFirmware(const int16_t) { HAL_reboot(); }
// Maple Compatibility
+volatile uint32_t systick_uptime_millis = 0;
systickCallback_t systick_user_callback;
void systick_attach_callback(systickCallback_t cb) { systick_user_callback = cb; }
-void HAL_SYSTICK_Callback() { if (systick_user_callback) systick_user_callback(); }
+void HAL_SYSTICK_Callback() {
+ systick_uptime_millis++;
+ if (systick_user_callback) systick_user_callback();
+}
-#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+#endif // HAL_STM32
diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h
index a1f7515d6b98..02bee57ba3ac 100644
--- a/Marlin/src/HAL/STM32/HAL.h
+++ b/Marlin/src/HAL/STM32/HAL.h
@@ -29,6 +29,7 @@
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
+#include "Servo.h"
#include "watchdog.h"
#include "MarlinSerial.h"
@@ -36,41 +37,64 @@
#include
+//
+// Serial Ports
+//
#ifdef USBCON
#include
+ #include "../../core/serial_hook.h"
+ typedef ForwardSerial1Class< decltype(SerialUSB) > DefaultSerial1;
+ extern DefaultSerial1 MSerial0;
#endif
-// ------------------------
-// Defines
-// ------------------------
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
- #define MYSERIAL0 SerialUSB
+ #define MYSERIAL1 MSerial0
#elif WITHIN(SERIAL_PORT, 1, 6)
- #define MYSERIAL0 MSERIAL(SERIAL_PORT)
+ #define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
- #error "SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
+ #error "SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
- #define MYSERIAL1 SerialUSB
+ #define MYSERIAL2 MSerial0
#elif WITHIN(SERIAL_PORT_2, 1, 6)
- #define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
+ #define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
- #error "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration."
+ #error "SERIAL_PORT_2 must be from 1 to 6. You can also use -1 if the board supports Native USB."
+ #endif
+#endif
+
+#ifdef SERIAL_PORT_3
+ #if SERIAL_PORT_3 == -1
+ #define MYSERIAL3 MSerial0
+ #elif WITHIN(SERIAL_PORT_3, 1, 6)
+ #define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
+ #else
+ #error "SERIAL_PORT_3 must be from 1 to 6. 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 MSerial0
+ #elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
+ #define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
+ #else
+ #error "MMU2_SERIAL_PORT must be from 1 to 6. 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 SerialUSB
+ #define LCD_SERIAL MSerial0
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
- #error "LCD_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
+ #error "LCD_SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
#endif
#if HAS_DGUS_LCD
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
@@ -95,14 +119,6 @@
// On AVR this is in math.h?
#define square(x) ((x)*(x))
-#ifndef strncpy_P
- #define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
-#endif
-
-// Fix bug in pgm_read_ptr
-#undef pgm_read_ptr
-#define pgm_read_ptr(addr) (*(addr))
-
// ------------------------
// Types
// ------------------------
@@ -110,6 +126,8 @@
typedef int16_t pin_t;
#define HAL_SERVO_LIB libServo
+#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
+#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
// ------------------------
// Public Variables
@@ -127,6 +145,8 @@ extern uint16_t HAL_adc_result;
// Enable hooks into setup for HAL
void HAL_init();
+#define HAL_IDLETASK 1
+void HAL_idletask();
// Clear reset reason
void HAL_clear_reset_source();
@@ -134,7 +154,7 @@ void HAL_clear_reset_source();
// Reset reason
uint8_t HAL_get_reset_source();
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot();
void _delay_ms(const int delay);
@@ -156,14 +176,14 @@ static inline int freeMemory() {
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
-inline void HAL_adc_init() {}
-
#define HAL_ADC_VREF 3.3
-#define HAL_ADC_RESOLUTION 10
+#define HAL_ADC_RESOLUTION ADC_RESOLUTION // 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+inline void HAL_adc_init() { analogReadResolution(HAL_ADC_RESOLUTION); }
+
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
@@ -175,6 +195,7 @@ uint16_t HAL_adc_get_result();
#ifdef STM32F1xx
#define JTAG_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_JTAGDISABLE)
#define JTAGSWD_DISABLE() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_DISABLE)
+ #define JTAGSWD_RESET() AFIO_DBGAFR_CONFIG(AFIO_MAPR_SWJ_CFG_RESET); // Reset: FULL SWD+JTAG
#endif
#define PLATFORM_M997_SUPPORT
@@ -184,3 +205,22 @@ void flashFirmware(const int16_t);
typedef void (*systickCallback_t)(void);
void systick_attach_callback(systickCallback_t cb);
void HAL_SYSTICK_Callback();
+
+extern volatile uint32_t systick_uptime_millis;
+
+#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
+
+/**
+ * set_pwm_frequency
+ * Set the frequency of the timer corresponding to the provided pin
+ * All Timer PWM pins run at the same frequency
+ */
+void set_pwm_frequency(const pin_t pin, int f_desired);
+
+/**
+ * set_pwm_duty
+ * Set the PWM duty cycle of the provided pin to the provided value
+ * Optionally allows inverting the duty cycle [default = false]
+ * Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
+ */
+void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
diff --git a/Marlin/src/HAL/STM32/HAL_MinSerial.cpp b/Marlin/src/HAL/STM32/HAL_MinSerial.cpp
new file mode 100644
index 000000000000..29826a890de4
--- /dev/null
+++ b/Marlin/src/HAL/STM32/HAL_MinSerial.cpp
@@ -0,0 +1,154 @@
+/**
+ * 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
+ * Copyright (c) 2017 Victor Perez
+ *
+ * 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 .
+ *
+ */
+#include "../platforms.h"
+
+#ifdef HAL_STM32
+
+#include "../../inc/MarlinConfigPre.h"
+
+#if ENABLED(POSTMORTEM_DEBUGGING)
+
+#include "../shared/HAL_MinSerial.h"
+#include "watchdog.h"
+
+/* Instruction Synchronization Barrier */
+#define isb() __asm__ __volatile__ ("isb" : : : "memory")
+
+/* Data Synchronization Barrier */
+#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
+
+// Dumb mapping over the registers of a USART device on STM32
+struct USARTMin {
+ volatile uint32_t SR;
+ volatile uint32_t DR;
+ volatile uint32_t BRR;
+ volatile uint32_t CR1;
+ volatile uint32_t CR2;
+};
+
+#if WITHIN(SERIAL_PORT, 1, 6)
+ // Depending on the CPU, the serial port is different for USART1
+ static const uintptr_t regsAddr[] = {
+ TERN(STM32F1xx, 0x40013800, 0x40011000), // USART1
+ 0x40004400, // USART2
+ 0x40004800, // USART3
+ 0x40004C00, // UART4_BASE
+ 0x40005000, // UART5_BASE
+ 0x40011400 // USART6
+ };
+ static USARTMin * regs = (USARTMin*)regsAddr[SERIAL_PORT - 1];
+#endif
+
+static void TXBegin() {
+ #if !WITHIN(SERIAL_PORT, 1, 6)
+ #warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error."
+ #warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port."
+ #else
+ // This is common between STM32F1/STM32F2 and STM32F4
+ const int nvicUART[] = { /* NVIC_USART1 */ 37, /* NVIC_USART2 */ 38, /* NVIC_USART3 */ 39, /* NVIC_UART4 */ 52, /* NVIC_UART5 */ 53, /* NVIC_USART6 */ 71 };
+ int nvicIndex = nvicUART[SERIAL_PORT - 1];
+
+ struct NVICMin {
+ volatile uint32_t ISER[32];
+ volatile uint32_t ICER[32];
+ };
+
+ NVICMin *nvicBase = (NVICMin*)0xE000E100;
+ SBI32(nvicBase->ICER[nvicIndex >> 5], nvicIndex & 0x1F);
+
+ // 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();
+
+ // Example for USART1 disable: (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN))
+ // Too difficult to reimplement here, let's query the STM32duino macro here
+ #if SERIAL_PORT == 1
+ __HAL_RCC_USART1_CLK_DISABLE();
+ __HAL_RCC_USART1_CLK_ENABLE();
+ #elif SERIAL_PORT == 2
+ __HAL_RCC_USART2_CLK_DISABLE();
+ __HAL_RCC_USART2_CLK_ENABLE();
+ #elif SERIAL_PORT == 3
+ __HAL_RCC_USART3_CLK_DISABLE();
+ __HAL_RCC_USART3_CLK_ENABLE();
+ #elif SERIAL_PORT == 4
+ __HAL_RCC_UART4_CLK_DISABLE(); // BEWARE: UART4 and not USART4 here
+ __HAL_RCC_UART4_CLK_ENABLE();
+ #elif SERIAL_PORT == 5
+ __HAL_RCC_UART5_CLK_DISABLE(); // BEWARE: UART5 and not USART5 here
+ __HAL_RCC_UART5_CLK_ENABLE();
+ #elif SERIAL_PORT == 6
+ __HAL_RCC_USART6_CLK_DISABLE();
+ __HAL_RCC_USART6_CLK_ENABLE();
+ #endif
+
+ uint32_t brr = regs->BRR;
+ regs->CR1 = 0; // Reset the USART
+ regs->CR2 = 0; // 1 stop bit
+
+ // If we don't touch the BRR (baudrate register), we don't need to recompute.
+ regs->BRR = brr;
+
+ regs->CR1 = _BV(3) | _BV(13); // 8 bits, no parity, 1 stop bit (TE | UE)
+ #endif
+}
+
+// A SW memory barrier, to ensure GCC does not overoptimize loops
+#define sw_barrier() __asm__ volatile("": : :"memory");
+static void TX(char c) {
+ #if WITHIN(SERIAL_PORT, 1, 6)
+ constexpr uint32_t usart_sr_txe = _BV(7);
+ while (!(regs->SR & usart_sr_txe)) {
+ TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
+ sw_barrier();
+ }
+ regs->DR = c;
+ #else
+ // Let's hope a mystical guru will fix this, one day by writing interrupt-free USB CDC ACM code (or, at least, by polling the registers since interrupt will be queued but will never trigger)
+ // For now, it's completely lost to oblivion.
+ #endif
+}
+
+void install_min_serial() {
+ HAL_min_serial_init = &TXBegin;
+ HAL_min_serial_out = &TX;
+}
+
+#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't jump to a symbol that's too far from the current function, so we work around this in exception_arm.cpp
+extern "C" {
+ __attribute__((naked)) void JumpHandler_ASM() {
+ __asm__ __volatile__ (
+ "b CommonHandler_ASM\n"
+ );
+ }
+ void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) HardFault_Handler();
+ void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) BusFault_Handler();
+ void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) UsageFault_Handler();
+ void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) MemManage_Handler();
+ void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) NMI_Handler();
+}
+#endif
+
+#endif // POSTMORTEM_DEBUGGING
+#endif // HAL_STM32
diff --git a/Marlin/src/HAL/STM32/HAL_SPI.cpp b/Marlin/src/HAL/STM32/HAL_SPI.cpp
index f947e6ef3272..85a5238b54af 100644
--- a/Marlin/src/HAL/STM32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/STM32/HAL_SPI.cpp
@@ -20,7 +20,9 @@
* along with this program. If not, see .
*
*/
-#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+#include "../platforms.h"
+
+#ifdef HAL_STM32
#include "../../inc/MarlinConfig.h"
@@ -45,24 +47,34 @@ static SPISettings spiConfig;
#include "../shared/Delay.h"
void spiBegin(void) {
- OUT_WRITE(SS_PIN, HIGH);
- OUT_WRITE(SCK_PIN, HIGH);
- SET_INPUT(MISO_PIN);
- OUT_WRITE(MOSI_PIN, HIGH);
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ OUT_WRITE(SD_SCK_PIN, HIGH);
+ SET_INPUT(SD_MISO_PIN);
+ OUT_WRITE(SD_MOSI_PIN, HIGH);
}
- static uint16_t delay_STM32_soft_spi;
+ // Use function with compile-time value so we can actually reach the desired frequency
+ // Need to adjust this a little bit: on a 72MHz clock, we have 14ns/clock
+ // and we'll use ~3 cycles to jump to the method and going back, so it'll take ~40ns from the given clock here
+ #define CALLING_COST_NS (3U * 1000000000U) / (F_CPU)
+ void (*delaySPIFunc)();
+ void delaySPI_125() { DELAY_NS(125 - CALLING_COST_NS); }
+ void delaySPI_250() { DELAY_NS(250 - CALLING_COST_NS); }
+ void delaySPI_500() { DELAY_NS(500 - CALLING_COST_NS); }
+ void delaySPI_1000() { DELAY_NS(1000 - CALLING_COST_NS); }
+ void delaySPI_2000() { DELAY_NS(2000 - CALLING_COST_NS); }
+ void delaySPI_4000() { DELAY_NS(4000 - CALLING_COST_NS); }
void spiInit(uint8_t spiRate) {
// Use datarates Marlin uses
switch (spiRate) {
- case SPI_FULL_SPEED: delay_STM32_soft_spi = 125; break; // desired: 8,000,000 actual: ~1.1M
- case SPI_HALF_SPEED: delay_STM32_soft_spi = 125; break; // desired: 4,000,000 actual: ~1.1M
- case SPI_QUARTER_SPEED:delay_STM32_soft_spi = 250; break; // desired: 2,000,000 actual: ~890K
- case SPI_EIGHTH_SPEED: delay_STM32_soft_spi = 500; break; // desired: 1,000,000 actual: ~590K
- case SPI_SPEED_5: delay_STM32_soft_spi = 1000; break; // desired: 500,000 actual: ~360K
- case SPI_SPEED_6: delay_STM32_soft_spi = 2000; break; // desired: 250,000 actual: ~210K
- default: delay_STM32_soft_spi = 4000; break; // desired: 125,000 actual: ~123K
+ case SPI_FULL_SPEED: delaySPIFunc = &delaySPI_125; break; // desired: 8,000,000 actual: ~1.1M
+ case SPI_HALF_SPEED: delaySPIFunc = &delaySPI_125; break; // desired: 4,000,000 actual: ~1.1M
+ case SPI_QUARTER_SPEED:delaySPIFunc = &delaySPI_250; break; // desired: 2,000,000 actual: ~890K
+ case SPI_EIGHTH_SPEED: delaySPIFunc = &delaySPI_500; break; // desired: 1,000,000 actual: ~590K
+ case SPI_SPEED_5: delaySPIFunc = &delaySPI_1000; break; // desired: 500,000 actual: ~360K
+ case SPI_SPEED_6: delaySPIFunc = &delaySPI_2000; break; // desired: 250,000 actual: ~210K
+ default: delaySPIFunc = &delaySPI_4000; break; // desired: 125,000 actual: ~123K
}
SPI.begin();
}
@@ -72,15 +84,15 @@ static SPISettings spiConfig;
uint8_t HAL_SPI_STM32_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
for (uint8_t bits = 8; bits--;) {
- WRITE(SCK_PIN, LOW);
- WRITE(MOSI_PIN, b & 0x80);
+ WRITE(SD_SCK_PIN, LOW);
+ WRITE(SD_MOSI_PIN, b & 0x80);
- DELAY_NS(delay_STM32_soft_spi);
- WRITE(SCK_PIN, HIGH);
- DELAY_NS(delay_STM32_soft_spi);
+ delaySPIFunc();
+ WRITE(SD_SCK_PIN, HIGH);
+ delaySPIFunc();
b <<= 1; // little setup time
- b |= (READ(MISO_PIN) != 0);
+ b |= (READ(SD_MISO_PIN) != 0);
}
DELAY_NS(125);
return b;
@@ -132,8 +144,8 @@ static SPISettings spiConfig;
* @details Only configures SS pin since stm32duino creates and initialize the SPI object
*/
void spiBegin() {
- #if PIN_EXISTS(SS)
- OUT_WRITE(SS_PIN, HIGH);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
}
@@ -153,12 +165,9 @@ static SPISettings spiConfig;
}
spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
- #if ENABLED(CUSTOM_SPI_PINS)
- SPI.setMISO(MISO_PIN);
- SPI.setMOSI(MOSI_PIN);
- SPI.setSCLK(SCK_PIN);
- SPI.setSSEL(SS_PIN);
- #endif
+ SPI.setMISO(SD_MISO_PIN);
+ SPI.setMOSI(SD_MOSI_PIN);
+ SPI.setSCLK(SD_SCK_PIN);
SPI.begin();
}
@@ -184,7 +193,7 @@ static SPISettings spiConfig;
*
* @details Uses DMA
*/
- void spiRead(uint8_t* buf, uint16_t nbyte) {
+ void spiRead(uint8_t *buf, uint16_t nbyte) {
if (nbyte == 0) return;
memset(buf, 0xFF, nbyte);
SPI.transfer(buf, nbyte);
@@ -209,7 +218,7 @@ static SPISettings spiConfig;
*
* @details Use DMA
*/
- void spiSendBlock(uint8_t token, const uint8_t* buf) {
+ void spiSendBlock(uint8_t token, const uint8_t *buf) {
uint8_t rxBuf[512];
SPI.transfer(token);
SPI.transfer((uint8_t*)buf, &rxBuf, 512);
@@ -217,4 +226,4 @@ static SPISettings spiConfig;
#endif // SOFTWARE_SPI
-#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+#endif // HAL_STM32
diff --git a/Marlin/src/HAL/STM32/MarlinSPI.cpp b/Marlin/src/HAL/STM32/MarlinSPI.cpp
new file mode 100644
index 000000000000..e1be50820f65
--- /dev/null
+++ b/Marlin/src/HAL/STM32/MarlinSPI.cpp
@@ -0,0 +1,170 @@
+/**
+ * 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 .
+ *
+ */
+#include "../platforms.h"
+
+#if defined(HAL_STM32) && !defined(STM32H7xx)
+
+#include "MarlinSPI.h"
+
+static void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb, uint32_t dataSize) {
+ spi_init(obj, speed, mode, msb);
+ // spi_init set 8bit always
+ // TODO: copy the code from spi_init and handle data size, to avoid double init always!!
+ if (dataSize != SPI_DATASIZE_8BIT) {
+ obj->handle.Init.DataSize = dataSize;
+ HAL_SPI_Init(&obj->handle);
+ __HAL_SPI_ENABLE(&obj->handle);
+ }
+}
+
+void MarlinSPI::setClockDivider(uint8_t _div) {
+ _speed = spi_getClkFreq(&_spi);// / _div;
+ _clockDivider = _div;
+}
+
+void MarlinSPI::begin(void) {
+ //TODO: only call spi_init if any parameter changed!!
+ spi_init(&_spi, _speed, _dataMode, _bitOrder, _dataSize);
+}
+
+void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc) {
+ _dmaHandle.Init.Direction = direction;
+ _dmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
+ _dmaHandle.Init.Mode = DMA_NORMAL;
+ _dmaHandle.Init.Priority = DMA_PRIORITY_LOW;
+ _dmaHandle.Init.MemInc = minc ? DMA_MINC_ENABLE : DMA_MINC_DISABLE;
+
+ if (_dataSize == DATA_SIZE_8BIT) {
+ _dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
+ _dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
+ }
+ else {
+ _dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
+ _dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
+ }
+ #ifdef STM32F4xx
+ _dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
+ #endif
+
+ // start DMA hardware
+ // TODO: check if hardware is already enabled
+ #ifdef SPI1_BASE
+ if (_spiHandle.Instance == SPI1) {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_3;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0;
+ #endif
+ }
+ #endif
+ #ifdef SPI2_BASE
+ if (_spiHandle.Instance == SPI2) {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3;
+ #endif
+ }
+ #endif
+ #ifdef SPI3_BASE
+ if (_spiHandle.Instance == SPI3) {
+ #ifdef STM32F1xx
+ __HAL_RCC_DMA2_CLK_ENABLE();
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
+ #elif defined(STM32F4xx)
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2;
+ #endif
+ }
+ #endif
+
+ HAL_DMA_Init(&_dmaHandle);
+}
+
+byte MarlinSPI::transfer(uint8_t _data) {
+ uint8_t rxData = 0xFF;
+ HAL_SPI_TransmitReceive(&_spi.handle, &_data, &rxData, 1, HAL_MAX_DELAY);
+ return rxData;
+}
+
+uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) {
+ const uint8_t ff = 0xFF;
+
+ //if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) //only enable if disabled
+ __HAL_SPI_ENABLE(&_spi.handle);
+
+ if (receiveBuf) {
+ setupDma(_spi.handle, _dmaRx, DMA_PERIPH_TO_MEMORY, true);
+ HAL_DMA_Start(&_dmaRx, (uint32_t)&(_spi.handle.Instance->DR), (uint32_t)receiveBuf, length);
+ SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_RXDMAEN); /* Enable Rx DMA Request */
+ }
+
+ // check for 2 lines transfer
+ bool mincTransmit = true;
+ if (transmitBuf == nullptr && _spi.handle.Init.Direction == SPI_DIRECTION_2LINES && _spi.handle.Init.Mode == SPI_MODE_MASTER) {
+ transmitBuf = &ff;
+ mincTransmit = false;
+ }
+
+ if (transmitBuf) {
+ setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, mincTransmit);
+ HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
+ SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
+ }
+
+ if (transmitBuf) {
+ HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ HAL_DMA_Abort(&_dmaTx);
+ HAL_DMA_DeInit(&_dmaTx);
+ }
+
+ // while ((_spi.handle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
+
+ if (receiveBuf) {
+ HAL_DMA_PollForTransfer(&_dmaRx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ HAL_DMA_Abort(&_dmaRx);
+ HAL_DMA_DeInit(&_dmaRx);
+ }
+
+ return 1;
+}
+
+uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc) {
+ setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, minc);
+ HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
+ __HAL_SPI_ENABLE(&_spi.handle);
+ SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
+ HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
+ HAL_DMA_Abort(&_dmaTx);
+ // DeInit objects
+ HAL_DMA_DeInit(&_dmaTx);
+ return 1;
+}
+
+#endif // HAL_STM32 && !STM32H7xx
diff --git a/Marlin/src/HAL/STM32/MarlinSPI.h b/Marlin/src/HAL/STM32/MarlinSPI.h
new file mode 100644
index 000000000000..fbd3585ff447
--- /dev/null
+++ b/Marlin/src/HAL/STM32/MarlinSPI.h
@@ -0,0 +1,107 @@
+/**
+ * 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 .
+ *
+ */
+#pragma once
+
+#include "HAL.h"
+#include
+
+extern "C" {
+ #include
+}
+
+/**
+ * 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.
+ *
+ */
+
+#define DATA_SIZE_8BIT SPI_DATASIZE_8BIT
+#define DATA_SIZE_16BIT SPI_DATASIZE_16BIT
+
+class MarlinSPI {
+public:
+ MarlinSPI() : MarlinSPI(NC, NC, NC, NC) {}
+
+ MarlinSPI(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)NC) : _mosiPin(mosi), _misoPin(miso), _sckPin(sclk), _ssPin(ssel) {
+ _spi.pin_miso = digitalPinToPinName(_misoPin);
+ _spi.pin_mosi = digitalPinToPinName(_mosiPin);
+ _spi.pin_sclk = digitalPinToPinName(_sckPin);
+ _spi.pin_ssel = digitalPinToPinName(_ssPin);
+ _dataSize = DATA_SIZE_8BIT;
+ _bitOrder = MSBFIRST;
+ _dataMode = SPI_MODE_0;
+ _spi.handle.State = HAL_SPI_STATE_RESET;
+ setClockDivider(SPI_SPEED_CLOCK_DIV2_MHZ);
+ }
+
+ void begin(void);
+ void end(void) {}
+
+ byte transfer(uint8_t _data);
+ uint8_t dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length);
+ uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = true);
+
+ /* These methods are deprecated and kept for compatibility.
+ * Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
+ */
+ void setBitOrder(BitOrder _order) { _bitOrder = _order; }
+
+ void setDataMode(uint8_t _mode) {
+ switch (_mode) {
+ case SPI_MODE0: _dataMode = SPI_MODE_0; break;
+ case SPI_MODE1: _dataMode = SPI_MODE_1; break;
+ case SPI_MODE2: _dataMode = SPI_MODE_2; break;
+ case SPI_MODE3: _dataMode = SPI_MODE_3; break;
+ }
+ }
+
+ void setClockDivider(uint8_t _div);
+
+private:
+ void setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc = false);
+
+ spi_t _spi;
+ DMA_HandleTypeDef _dmaTx;
+ DMA_HandleTypeDef _dmaRx;
+ BitOrder _bitOrder;
+ spi_mode_e _dataMode;
+ uint8_t _clockDivider;
+ uint32_t _speed;
+ uint32_t _dataSize;
+ pin_t _mosiPin;
+ pin_t _misoPin;
+ pin_t _sckPin;
+ pin_t _ssPin;
+};
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp
index a146664366df..3caedc72eb26 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp
@@ -16,8 +16,9 @@
* along with this program. If not, see