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/.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
new file mode 100644
index 000000000000..3f5d6fe5517d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,20 @@
+blank_issues_enabled: false
+contact_links:
+ - name: 📖 Marlin Documentation
+ url: http://marlinfw.org/
+ about: Lots of documentation on installing and using Marlin.
+ - name: 👤 MarlinFirmware Facebook group
+ url: https://www.facebook.com/groups/1049718498464482
+ about: Please ask and answer questions here.
+ - name: 🕹 Marlin on Discord
+ url: https://discord.gg/n5NJ59y
+ about: Join the Discord server for support and discussion.
+ - 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
+ 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.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/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
new file mode 100644
index 000000000000..5539941ed179
--- /dev/null
+++ b/.github/workflows/bump-date.yml
@@ -0,0 +1,38 @@
+#
+# bump-date.yml
+# Bump the distribution date once per day
+#
+
+name: Bump Distribution Date
+
+on:
+ schedule:
+ - cron: '0 */6 * * *'
+
+jobs:
+ bump_date:
+ name: Bump Distribution Date
+ if: github.repository == 'MarlinFirmware/Marlin'
+
+ runs-on: ubuntu-latest
+
+ steps:
+
+ - name: Check out bugfix-2.0.x
+ uses: actions/checkout@v2
+ with:
+ ref: bugfix-2.0.x
+
+ - name: Bump Distribution Date
+ run: |
+ # Inline Bump Script
+ if [[ ! "$( git log -1 --pretty=%B )" =~ ^\[cron\] ]]; then
+ 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 . && \
+ git commit -m "[cron] Bump distribution date ($DIST)" && \
+ git push
+ fi
diff --git a/.github/workflows/check-pr.yml b/.github/workflows/check-pr.yml
new file mode 100644
index 000000000000..93a110f270d3
--- /dev/null
+++ b/.github/workflows/check-pr.yml
@@ -0,0 +1,33 @@
+#
+# check-pr.yml
+# Close PRs directed at release branches
+#
+
+name: PR Bad Target
+
+on:
+ pull_request_target:
+ types: [opened]
+ branches:
+ - 1.0.x
+ - 1.1.x
+ - 2.0.x
+
+jobs:
+ bad_target:
+ name: PR Bad Target
+ if: github.repository == 'MarlinFirmware/Marlin'
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: superbrothers/close-pull-request@v3
+ with:
+ 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.
+
+ Please redo this PR starting with the `bugfix-2.0.x` branch and be careful to target `bugfix-2.0.x` when resubmitting the PR.
+
+ It may help to set your fork's default branch to `bugfix-2.0.x`.
+
+ See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions.
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
new file mode 100644
index 000000000000..f017907d2934
--- /dev/null
+++ b/.github/workflows/close-stale.yml
@@ -0,0 +1,28 @@
+#
+# close-stale.yml
+# Close open issues after a period of inactivity
+#
+
+name: Close Stale Issues
+
+on:
+ schedule:
+ - cron: "22 1 * * *"
+
+jobs:
+ stale:
+ name: Close Stale Issues
+ if: github.repository == 'MarlinFirmware/Marlin'
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/stale@v3
+ with:
+ repo-token: ${{ secrets.GITHUB_TOKEN }}
+ 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-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
new file mode 100644
index 000000000000..81145688288b
--- /dev/null
+++ b/.github/workflows/lock-closed.yml
@@ -0,0 +1,32 @@
+#
+# lock-closed.yml
+# Lock closed issues after a period of inactivity
+#
+
+name: Lock Closed Issues
+
+on:
+ schedule:
+ - cron: '0 1/13 * * *'
+
+jobs:
+ lock:
+ name: Lock Closed Issues
+ if: github.repository == 'MarlinFirmware/Marlin'
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: dessant/lock-threads@v2
+ with:
+ github-token: ${{ github.token }}
+ process-only: 'issues'
+ issue-lock-inactive-days: '60'
+ issue-exclude-created-before: '2017-07-01T00:00:00Z'
+ issue-exclude-labels: 'no-locking'
+ issue-lock-labels: ''
+ issue-lock-comment: >
+ This issue has been automatically locked since there
+ has not been any recent activity after it was closed.
+ Please open a new issue for related bugs.
+ issue-lock-reason: ''
diff --git a/.github/workflows/test-builds.yml b/.github/workflows/test-builds.yml
index 53ffbe0c08b1..f5ce466d9051 100644
--- a/.github/workflows/test-builds.yml
+++ b/.github/workflows/test-builds.yml
@@ -48,7 +48,7 @@ jobs:
# Extended AVR Environments
- - FYSETC_F6_13
+ - FYSETC_F6
- mega1280
- rambo
- sanguino1284p
@@ -56,28 +56,33 @@ jobs:
# STM32F1 (Maple) Environments
- - STM32F103RC_btt
- - STM32F103RC_btt_USB
- - STM32F103RE_btt
- - STM32F103RE_btt_USB
- - STM32F103RC_fysetc
+ #- STM32F103RC_btt_maple
+ - STM32F103RC_btt_USB_maple
+ - STM32F103RC_fysetc_maple
- STM32F103RC_meeb
- - jgaurora_a5s_a1
- - STM32F103VE_longer
- - mks_robin
- - mks_robin_lite
- - mks_robin_pro
- - STM32F103RET6_creality
- - mks_robin_nano35
+ - 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
+ - STM32F103RE_btt
+ - STM32F103RE_btt_USB
+ - STM32F103RET6_creality
+ - STM32F103VE_longer
- STM32F407VE_black
- STM32F401VE_STEVAL
- BIGTREE_BTT002
- BIGTREE_SKR_PRO
- BIGTREE_GTR_V1_0
- - mks_robin_stm32
+ - mks_robin
- ARMED
- FYSETC_S6
- STM32F070CB_malyan
@@ -86,9 +91,13 @@ jobs:
- FLYF407ZG
- rumba32
- LERDGEX
- - mks_robin_nano35_stm32
+ - LERDGEK
+ - mks_robin_nano35
- NUCLEO_F767ZI
- REMRAM_V1
+ - BTT_SKR_SE_BX
+ - chitu_f103
+ - Index_Mobo_Rev03
# Put lengthy tests last
@@ -98,12 +107,30 @@ jobs:
# Non-working environment tests
#- at90usb1286_cdc
#- 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
@@ -113,9 +140,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: |
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
diff --git a/.github/workflows/unlock-reopened.yml b/.github/workflows/unlock-reopened.yml
new file mode 100644
index 000000000000..614ef3fab297
--- /dev/null
+++ b/.github/workflows/unlock-reopened.yml
@@ -0,0 +1,22 @@
+#
+# unlock-reopened.yml
+# Unlock an issue whenever it is re-opened
+#
+
+name: "Unlock reopened issue"
+
+on:
+ issues:
+ types: [reopened]
+
+jobs:
+ unlock:
+ name: Unlock Reopened
+ if: github.repository == 'MarlinFirmware/Marlin'
+
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: OSDKDev/unlock-issues@v1.1
+ with:
+ repo-token: "${{ secrets.GITHUB_TOKEN }}"
diff --git a/.gitignore b/.gitignore
index 62f73a7c0d00..0b852d767325 100755
--- a/.gitignore
+++ b/.gitignore
@@ -19,15 +19,19 @@
# 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
+marlin_config.json
+mczip.h
+*.gen
+*.sublime-workspace
#
# OS
#
applet/
-*.DS_Store
+.DS_Store
#
# Misc
@@ -37,7 +41,6 @@ applet/
*.rej
*.bak
*.idea
-*.s
*.i
*.ii
*.swp
@@ -122,29 +125,6 @@ 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
@@ -160,16 +140,19 @@ __vm/
vc-fileutils.settings
# Visual Studio Code
-.vscode
-.vscode/.browse.c_cpp.db*
-.vscode/c_cpp_properties.json
-.vscode/launch.json
-.vscode/*.db
+.vscode/*
+!.vscode/extensions.json
+
+#Simulation
+imgui.ini
+eeprom.dat
+spi_flash.bin
-# cmake
+#cmake
CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
+build/
# CLion
cmake-build-*
@@ -186,7 +169,3 @@ __pycache__
# IOLogger logs
*_log.csv
-
-# Simulation / Native
-eeprom.dat
-imgui.ini
diff --git a/.vscode/extensions.json b/.vscode/extensions.json
new file mode 100644
index 000000000000..7226831cb182
--- /dev/null
+++ b/.vscode/extensions.json
@@ -0,0 +1,8 @@
+{
+ // See http://go.microsoft.com/fwlink/?LinkId=827846
+ // for the documentation about the extensions.json format
+ "recommendations": [
+ "marlinfirmware.auto-build",
+ "platformio.platformio-ide"
+ ]
+}
diff --git a/Makefile b/Makefile
index 8e1c77aa9935..ebcdf25e2d6a 100644
--- a/Makefile
+++ b/Makefile
@@ -27,8 +27,6 @@ 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
- chmod +x buildroot/bin/*
- chmod +x buildroot/tests/*
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
@@ -40,8 +38,6 @@ tests-single-local-docker:
.PHONY: tests-single-local-docker
tests-all-local:
- chmod +x buildroot/bin/*
- chmod +x buildroot/tests/*
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
diff --git a/Marlin/Configuration.h b/Marlin/Configuration.h
index 5fb90b2f05ee..da7075e66811 100644
--- a/Marlin/Configuration.h
+++ b/Marlin/Configuration.h
@@ -37,37 +37,36 @@
*
* Advanced settings can be found in Configuration_adv.h
*/
-#define CONFIGURATION_H_VERSION 020008
+#define CONFIGURATION_H_VERSION 02000903
//===========================================================================
//============================= 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
-// from /~https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
//
-
-//===========================================================================
-//============================= SCARA Printer ===============================
-//===========================================================================
-// For a SCARA printer, start with one of the configuration files in the config/examples/SCARA directory
-// from /~https://github.com/MarlinFirmware/Configurations/branches/all 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
@@ -97,6 +96,11 @@
// @section machine
+// Choose the name from boards.h that matches your setup
+#ifndef MOTHERBOARD
+ #define MOTHERBOARD BOARD_RAMPS_14_EFB
+#endif
+
/**
* Select the serial port on the board to use for communication with the host.
* This allows the connection of wireless adapters (for instance) to non-default port pins.
@@ -108,14 +112,9 @@
#define SERIAL_PORT 2
/**
- * 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.
@@ -123,16 +122,28 @@
*
* :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
*/
-#define BAUDRATE 115200
+#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
-// Choose the name from boards.h that matches your setup
-#ifndef MOTHERBOARD
- #define MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V2_0
-#endif
-
// Name displayed in the LCD "Ready" message and Info menu
#define CUSTOM_MACHINE_NAME "Ender-3 Pro"
@@ -140,6 +151,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
@@ -163,11 +213,11 @@
* Multi-Material Unit
* Set to one of these predefined models:
*
- * 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)
- * SMUFF_EMU_MMU2 : Technik Gegg SMUFF (Průša MMU2 emulation mode)
- * SMUFF_EMU_MMU2S : Technik Gegg SMUFF (Průša MMU2S emulation mode)
+ * 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.
* See additional options in Configuration_adv.h.
@@ -212,7 +262,6 @@
#define PARKING_EXTRUDER_PARKING_X { -78, 184 } // X positions for parking the extruders
#define PARKING_EXTRUDER_GRAB_DISTANCE 1 // (mm) Distance to move beyond the parking point to grab the extruder
- //#define MANUAL_SOLENOID_CONTROL // Manual control of docking solenoids with M380 S / M381
#if ENABLED(PARKING_EXTRUDER)
@@ -294,6 +343,7 @@
#define MIXING_VIRTUAL_TOOLS 16 // Use the Virtual Tool method with M163 and M164
//#define DIRECT_MIXING_IN_G1 // Allow ABCDHI mix factors in G1 movement commands
//#define GRADIENT_MIX // Support for gradient mixing with M166 and LCD
+ //#define MIXING_PRESETS // Assign 8 default V-tool presets for 2 or 3 MIXING_STEPPERS
#if ENABLED(GRADIENT_MIX)
//#define GRADIENT_VTOOL // Add M166 T to use a V-tool index as a Gradient alias
#endif
@@ -318,6 +368,9 @@
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
+ //#define MKS_PWC // Using the MKS PWC add-on
+ //#define PS_OFF_CONFIRM // Confirm dialog when power off
+ //#define PS_OFF_SOUND // Beep 1s when power off
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
@@ -332,8 +385,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
@@ -345,70 +400,93 @@
// @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
+ * 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor
+ *
+ * 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 Thermal Sensors
+ * ------
* 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 mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
- * NOTES: (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.
- * 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
@@ -421,29 +499,47 @@
#define TEMP_SENSOR_BED 1
#define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 0
+#define TEMP_SENSOR_COOLER 0
+#define TEMP_SENSOR_BOARD 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 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_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 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_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.
+ *
+ * For selecting source/target use: COOLER, PROBE, BOARD, CHAMBER, BED, E0, E1, E2, E3, E4, E5, E6, E7
+ */
+#if TEMP_SENSOR_REDUNDANT
+ #define TEMP_SENSOR_REDUNDANT_SOURCE E1 // The sensor that will provide the redundant reading.
+ #define TEMP_SENSOR_REDUNDANT_TARGET E0 // 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.
@@ -456,6 +552,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.
@@ -468,7 +565,18 @@
#define HEATER_5_MAXTEMP 275
#define HEATER_6_MAXTEMP 275
#define HEATER_7_MAXTEMP 275
-#define BED_MAXTEMP 125
+#define BED_MAXTEMP 120
+#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 ================================
@@ -489,11 +597,11 @@
// Creality Ender-3 Pro
#if ENABLED(PID_PARAMS_PER_HOTEND)
- // Specify between 1 and HOTENDS values per array.
- // If fewer than EXTRUDER values are provided, the last element will be repeated.
- #define DEFAULT_Kp_LIST { 21.73, 21.73 }
- #define DEFAULT_Ki_LIST { 1.54, 1.54 }
- #define DEFAULT_Kd_LIST { 76.55, 76.55 }
+ // Specify up to one value per hotend here, according to your setup.
+ // If there are fewer values, the last one applies to the remaining hotends.
+ #define DEFAULT_Kp_LIST { 22.20, 22.20 }
+ #define DEFAULT_Ki_LIST { 1.08, 1.08 }
+ #define DEFAULT_Kd_LIST { 114.00, 114.00 }
#else
#define DEFAULT_Kp 21.73
#define DEFAULT_Ki 1.54
@@ -542,7 +650,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
@@ -589,6 +741,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 =========================
@@ -605,6 +758,17 @@
//#define COREZX
//#define COREZY
//#define MARKFORGED_XY // MarkForged. See https://reprap.org/forum/read.php?152,504042
+//#define MARKFORGED_YX
+
+// Enable for a belt style printer with endless "Z" motion
+//#define BELTPRINTER
+
+// Enable for Polargraph Kinematics
+//#define POLARGRAPH
+#if ENABLED(POLARGRAPH)
+ #define POLARGRAPH_MAX_BELT_LEN 1035.0
+ #define POLAR_SEGMENTS_PER_SECOND 5
+#endif
//===========================================================================
//============================== Endstop Settings ===========================
@@ -618,20 +782,32 @@
#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
#if DISABLED(ENDSTOPPULLUPS)
// Disable ENDSTOPPULLUPS to set pullups individually
- //#define ENDSTOPPULLUP_XMAX
- //#define ENDSTOPPULLUP_YMAX
- //#define ENDSTOPPULLUP_ZMAX
//#define ENDSTOPPULLUP_XMIN
//#define ENDSTOPPULLUP_YMIN
//#define ENDSTOPPULLUP_ZMIN
+ //#define ENDSTOPPULLUP_IMIN
+ //#define ENDSTOPPULLUP_JMIN
+ //#define ENDSTOPPULLUP_KMIN
+ //#define ENDSTOPPULLUP_XMAX
+ //#define ENDSTOPPULLUP_YMAX
+ //#define ENDSTOPPULLUP_ZMAX
+ //#define ENDSTOPPULLUP_IMAX
+ //#define ENDSTOPPULLUP_JMAX
+ //#define ENDSTOPPULLUP_KMAX
//#define ENDSTOPPULLUP_ZMIN_PROBE
#endif
@@ -639,12 +815,18 @@
//#define ENDSTOPPULLDOWNS
#if DISABLED(ENDSTOPPULLDOWNS)
// Disable ENDSTOPPULLDOWNS to set pulldowns individually
- //#define ENDSTOPPULLDOWN_XMAX
- //#define ENDSTOPPULLDOWN_YMAX
- //#define ENDSTOPPULLDOWN_ZMAX
//#define ENDSTOPPULLDOWN_XMIN
//#define ENDSTOPPULLDOWN_YMIN
//#define ENDSTOPPULLDOWN_ZMIN
+ //#define ENDSTOPPULLDOWN_IMIN
+ //#define ENDSTOPPULLDOWN_JMIN
+ //#define ENDSTOPPULLDOWN_KMIN
+ //#define ENDSTOPPULLDOWN_XMAX
+ //#define ENDSTOPPULLDOWN_YMAX
+ //#define ENDSTOPPULLDOWN_ZMAX
+ //#define ENDSTOPPULLDOWN_IMAX
+ //#define ENDSTOPPULLDOWN_JMAX
+ //#define ENDSTOPPULLDOWN_KMAX
//#define ENDSTOPPULLDOWN_ZMIN_PROBE
#endif
@@ -652,9 +834,15 @@
#define X_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING false // 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.
/**
@@ -683,6 +871,9 @@
//#define Z2_DRIVER_TYPE A4988
//#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 TMC2209
//#define E1_DRIVER_TYPE A4988
//#define E2_DRIVER_TYPE A4988
@@ -736,14 +927,14 @@
/**
* 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, 80, 400, 412 }
/**
* 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 { 500, 500, 20, 2*60 }
@@ -756,7 +947,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 { 1000, 1000, 100, 5000 }
@@ -790,6 +981,9 @@
#define DEFAULT_XJERK 10.0
#define DEFAULT_YJERK 10.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
@@ -873,7 +1067,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.
@@ -904,11 +1097,6 @@
*/
#define BLTOUCH
-/**
- * Pressure sensor with a BLTouch-like interface
- */
-//#define CREALITY_TOUCH
-
/**
* Touch-MI Probe by hotends.fr
*
@@ -941,7 +1129,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
@@ -965,14 +1153,14 @@
* 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.
* - 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.
@@ -1006,13 +1194,49 @@
#define PROBING_MARGIN 10
// X and Y axis travel speed (mm/min) between probes
-#define XY_PROBE_SPEED (100*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 / 4)
+#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
+
+/**
+ * Probe Enable / Disable
+ * The probe only provides a triggered signal when enabled.
+ */
+//#define PROBE_ENABLE_DISABLE
+#if ENABLED(PROBE_ENABLE_DISABLE)
+ //#define PROBE_ENABLE_PIN -1 // Override the default pin here
+#endif
/**
* Multiple Probing
@@ -1070,23 +1294,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
@@ -1102,6 +1341,9 @@
#define INVERT_X_DIR true
#define INVERT_Y_DIR true
#define INVERT_Z_DIR false
+//#define INVERT_I_DIR false
+//#define INVERT_J_DIR false
+//#define INVERT_K_DIR false
// @section extruder
@@ -1119,7 +1361,13 @@
//#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.
@@ -1131,6 +1379,9 @@
#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
@@ -1145,6 +1396,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
@@ -1161,6 +1418,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
@@ -1169,6 +1429,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)
@@ -1196,6 +1459,8 @@
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#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
@@ -1230,8 +1495,9 @@
//#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
@@ -1292,17 +1558,19 @@
//#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 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
+ #define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
#define LEVELING_BED_TEMP 50
#endif
@@ -1313,6 +1581,11 @@
*/
//#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.
@@ -1334,10 +1607,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 200 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool.
- #define MESH_TEST_BED_TEMP 55 // (°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
@@ -1382,12 +1656,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)
//===========================================================================
@@ -1428,6 +1706,25 @@
#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
/**
@@ -1446,16 +1743,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)
@@ -1464,8 +1762,7 @@
#endif
// Homing speeds (mm/min)
-#define HOMING_FEEDRATE_XY (20*60)
-#define HOMING_FEEDRATE_Z (4*60)
+#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) }
// Validate that endstops are triggered on homing moves
#define VALIDATE_HOMING_ENDSTOPS
@@ -1547,7 +1844,8 @@
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
- #define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
+ //#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
+ //#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
#endif
//
@@ -1572,15 +1870,19 @@
// @section temperature
-// Preheat Constants
+//
+// Preheat Constants - Up to 5 are supported without changes
+//
#define PREHEAT_1_LABEL "PLA"
#define PREHEAT_1_TEMP_HOTEND 200
#define PREHEAT_1_TEMP_BED 55
+#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 55
+#define PREHEAT_2_TEMP_HOTEND 230
+#define PREHEAT_2_TEMP_BED 60
+#define PREHEAT_2_TEMP_CHAMBER 35
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
/**
@@ -1673,6 +1975,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"
@@ -1681,11 +1987,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
+ * 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
*
- * 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
+ * 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:
*
@@ -1708,6 +2023,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
@@ -1751,10 +2069,10 @@
*
* 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
+ * en, an, bg, ca, cz, da, de, el, el_CY, es, eu, fi, fr, gl, hr, hu, it,
+ * 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 (Greece)', 'el_CY':'Greek (Cyprus)', '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
@@ -1797,16 +2115,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
*
@@ -1876,6 +2184,7 @@
// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu.
//
//#define INDIVIDUAL_AXIS_HOMING_MENU
+//#define INDIVIDUAL_AXIS_HOMING_SUBMENU
//
// SPEAKER/BUZZER
@@ -1908,6 +2217,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/
@@ -2058,6 +2375,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
@@ -2072,6 +2394,11 @@
//#define VIKI2
//#define miniVIKI
+//
+// Alfawise Ex8 printer LCD marked as WYH L12864 COG
+//
+//#define WYH_L12864
+
//
// MakerLab Mini Panel with graphic
// controller and SD support - https://reprap.org/wiki/Mini_panel
@@ -2119,11 +2446,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
@@ -2135,6 +2468,11 @@
//#define FYSETC_MINI_12864_2_1 // Type A/B. NeoPixel RGB Backlight
//#define FYSETC_GENERIC_12864_1_1 // Larger display with basic ON/OFF backlight.
+//
+// BigTreeTech Mini 12864 V1.0 is an alias for FYSETC_MINI_12864_2_1. Type A/B. NeoPixel RGB Backlight.
+//
+//#define BTT_MINI_12864_V1
+
//
// Factory display for Creality CR-10
// https://www.aliexpress.com/item/32833148327.html
@@ -2195,7 +2533,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
@@ -2204,7 +2542,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)
@@ -2221,10 +2559,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 ===========================
//=============================================================================
@@ -2233,10 +2576,42 @@
// 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.
+//
+// RELOADED (T5UID1)
+// - Download /~https://github.com/Desuuuu/DGUS-reloaded/releases
+// - 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
+//#define DGUS_LCD_UI_RELOADED
+#if ENABLED(DGUS_LCD_UI_MKS)
+ #define USE_MKS_GREEN_UI
+#endif
//
// CR-6 OEM touch screen. A DWIN display with touch.
@@ -2267,6 +2642,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'.
@@ -2287,32 +2670,32 @@
*/
//
-// 480x320, 3.5", SPI Display From MKS
-// Normally used in MKS Robin Nano V2
+// 480x320, 3.5", SPI Display with Rotary Encoder from MKS
+// Usually paired with MKS Robin Nano V2 & V3
//
//#define MKS_TS35_V2_0
//
// 320x240, 2.4", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT24
//
// 320x240, 2.8", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT28
//
// 320x240, 3.2", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT32
//
// 480x320, 3.5", FSMC Display From MKS
-// Normally used in MKS Robin Nano V1.2
+// Usually paired with MKS Robin Nano V1.2
//
//#define MKS_ROBIN_TFT35
@@ -2323,7 +2706,7 @@
//
// 320x240, 3.2", FSMC Display From MKS
-// Normally used in MKS Robin
+// Usually paired with MKS Robin
//
//#define MKS_ROBIN_TFT_V1_1R
@@ -2342,6 +2725,26 @@
//
//#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 with Rotary Encoder from BIQU-BX
+//
+//#define BIQU_BX_TFT70
+
+//
+// 480x320, 3.5", SPI Stock Display with Rotary Encoder from BIQU B1 SE Series
+//
+//#define BTT_TFT35_SPI_V1_0
+
//
// Generic TFT with detailed options
//
@@ -2358,6 +2761,7 @@
//#define TFT_RES_320x240
//#define TFT_RES_480x272
//#define TFT_RES_480x320
+ //#define TFT_RES_1024x600
#endif
/**
@@ -2374,6 +2778,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:
*
@@ -2391,22 +2799,33 @@
//
// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder.
//
-//#define DWIN_CREALITY_LCD
+//#define DWIN_CREALITY_LCD // Creality UI
+//#define DWIN_CREALITY_LCD_ENHANCED // Enhanced UI
+//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers
+//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation)
+//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation)
//
-// ADS7843/XPT2046 ADC Touchscreen such as ILI9341 2.8
+// Touch Screen Settings
//
//#define TOUCH_SCREEN
#if ENABLED(TOUCH_SCREEN)
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
+ //#define TOUCH_IDLE_SLEEP 300 // (secs) Turn off the TFT backlight if set (5mn)
+
#define TOUCH_SCREEN_CALIBRATION
//#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
@@ -2420,6 +2839,11 @@
//#define REPRAPWORLD_KEYPAD
//#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0 // (mm) Distance to move per key-press
+//
+// EasyThreeD ET-4000+ with button input and status LED
+//
+//#define EASYTHREED_UI
+
//=============================================================================
//=============================== Extra Features ==============================
//=============================================================================
@@ -2430,9 +2854,6 @@
// :[1,2,3,4,5,6,7,8]
//#define NUM_M106_FANS 1
-// Increase the FAN PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino
-//#define FAST_PWM_FAN
-
// Use software PWM to drive the fan, as for the heaters. This uses a very low frequency
// which is not as annoying as with the hardware PWM. On the other hand, if this frequency
// is too low, you should also increment SOFT_PWM_SCALE.
@@ -2503,7 +2924,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.)
@@ -2521,9 +2942,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
/**
@@ -2548,9 +2971,9 @@
* Set this manually if there are extra servos needing manual control.
* Set to 0 to turn off servo support.
*/
-//#define NUM_SERVOS 3 // Servo index starts with 0 for M280 command
+//#define NUM_SERVOS 3 // Note: Servo index starts with 0 for M280-M282 commands
-// (ms) Delay before the next move will start, to give the servo time to reach its target angle.
+// (ms) Delay before the next move will start, to give the servo time to reach its target angle.
// 300ms is a good value but you can try less delay.
// If the servo can't reach the requested position, increase it.
#define SERVO_DELAY { 300 }
@@ -2560,3 +2983,6 @@
// Edit servo angles with M281 and save to EEPROM with M500
//#define EDITABLE_SERVO_ANGLES
+
+// Disable servo with M282 to reduce power consumption, noise, and heat when not in use
+//#define SERVO_DETACH_GCODE
diff --git a/Marlin/Configuration_adv.h b/Marlin/Configuration_adv.h
index 727b2e3c6946..c4ea0f389afd 100644
--- a/Marlin/Configuration_adv.h
+++ b/Marlin/Configuration_adv.h
@@ -32,7 +32,7 @@
*
* Basic settings can be found in Configuration.h
*/
-#define CONFIGURATION_ADV_H_VERSION 020008
+#define CONFIGURATION_ADV_H_VERSION 02000903
//===========================================================================
//============================= Thermal Settings ============================
@@ -115,10 +115,54 @@
#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_BOARD == 1000
+ #define BOARD_PULLUP_RESISTOR_OHMS 4700 // Pullup resistor
+ #define BOARD_RESISTANCE_25C_OHMS 100000 // Resistance at 25C
+ #define BOARD_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.
+ * MAX31865_USE_READ_ERROR_DETECTION: Detects random read errors from value spikes (a 20°C difference in less than 1sec)
+ * MAX31865_USE_AUTO_MODE: Faster and more frequent reads than 1-shot, but bias voltage always on, slightly affecting RTD temperature.
+ * MAX31865_MIN_SAMPLING_TIME_MSEC: in 1-shot mode, the minimum time between subsequent reads. This reduces the effect of bias voltage by leaving the sensor unpowered for longer intervals.
+ * MAX31865_WIRE_OHMS: In 2-wire configurations, manually set the wire resistance for more accurate readings
+ */
+//#define TEMP_SENSOR_FORCE_HW_SPI
+//#define MAX31865_SENSOR_WIRES_0 2
+//#define MAX31865_SENSOR_WIRES_1 2
+//#define MAX31865_50HZ_FILTER
+//#define MAX31865_USE_READ_ERROR_DETECTION
+//#define MAX31865_USE_AUTO_MODE
+//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100
+//#define MAX31865_WIRE_OHMS_0 0.0f
+//#define MAX31865_WIRE_OHMS_1 0.0f
+
+/**
+ * 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
@@ -139,17 +183,22 @@
//
// 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_INDEX 2 // Index of a fan to repurpose as the chamber fan. (Default: first unused fan)
+ #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
@@ -158,6 +207,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
@@ -165,12 +217,57 @@
#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
+
+//
+// Motherboard Sensor options
+//
+#if TEMP_SENSOR_BOARD
+ #define THERMAL_PROTECTION_BOARD // Halt the printer if the board sensor leaves the temp range below.
+ #define BOARD_MINTEMP 8 // (°C)
+ #define BOARD_MAXTEMP 70 // (°C)
+ #ifndef TEMP_BOARD_PIN
+ //#define TEMP_BOARD_PIN -1 // Board temp sensor pin, if not set in pins file.
+ #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
@@ -208,7 +305,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
@@ -240,6 +337,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.
@@ -286,8 +397,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
@@ -315,7 +426,7 @@
*/
#define AUTOTEMP
#if ENABLED(AUTOTEMP)
- #define AUTOTEMP_OLDWEIGHT 0.98
+ #define AUTOTEMP_OLDWEIGHT 0.98 // Factor used to weight previous readings (0.0 < value < 1.0)
// Turn on AUTOTEMP on M104/M109 by default using proportions set here
//#define AUTOTEMP_PROPORTIONAL
#if ENABLED(AUTOTEMP_PROPORTIONAL)
@@ -333,7 +444,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.
@@ -399,16 +510,20 @@
*/
#define USE_CONTROLLER_FAN
#if ENABLED(USE_CONTROLLER_FAN)
- #define CONTROLLER_FAN_PIN FAN1_PIN // Set a custom pin for the controller fan
- //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered
- //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled.
- #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.)
- #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled
- #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled
- #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors
- #define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings
+ #define CONTROLLER_FAN_PIN FAN1_PIN // Set a custom pin for the controller fan
+ //#define CONTROLLER_FAN_USE_Z_ONLY // With this option only the Z axis is considered
+ //#define CONTROLLER_FAN_IGNORE_Z // Ignore Z stepper. Useful when stepper timeout is disabled.
+ #define CONTROLLERFAN_SPEED_MIN 0 // (0-255) Minimum speed. (If set below this value the fan is turned off.)
+ #define CONTROLLERFAN_SPEED_ACTIVE 255 // (0-255) Active speed, used when any motor is enabled
+ #define CONTROLLERFAN_SPEED_IDLE 0 // (0-255) Idle speed, used when motors are disabled
+ #define CONTROLLERFAN_IDLE_TIME 60 // (seconds) Extra time to keep the fan running after disabling motors
+
+ // Use TEMP_SENSOR_BOARD as a trigger for enabling the controller fan
+ //#define CONTROLLER_FAN_MIN_BOARD_TEMP 40 // (°C) Turn on the fan if the board reaches this temperature
+
+ //#define CONTROLLER_FAN_EDITABLE // Enable M710 configurable settings
#if ENABLED(CONTROLLER_FAN_EDITABLE)
- #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu
+ #define CONTROLLER_FAN_MENU // Enable the Controller Fan submenu
#endif
#endif
@@ -436,18 +551,21 @@
//#define FAN_MAX_PWM 128
/**
- * FAST PWM FAN Settings
+ * Fan Fast PWM
*
- * Use to change the FAST FAN PWM frequency (if enabled in Configuration.h)
- * Combinations of PWM Modes, prescale values and TOP resolutions are used internally to produce a
- * frequency as close as possible to the desired frequency.
+ * Combinations of PWM Modes, prescale values and TOP resolutions are used internally
+ * to produce a frequency as close as possible to the desired frequency.
*
- * FAST_PWM_FAN_FREQUENCY [undefined by default]
+ * FAST_PWM_FAN_FREQUENCY
* Set this to your desired frequency.
- * If left undefined this defaults to F = F_CPU/(2*255*1)
- * i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers.
- * These defaults are the same as with the old FAST_PWM_FAN implementation - no migration is required
+ * For AVR, if left undefined this defaults to F = F_CPU/(2*255*1)
+ * i.e., F = 31.4kHz on 16MHz microcontrollers or F = 39.2kHz on 20MHz microcontrollers.
+ * For non AVR, if left undefined this defaults to F = 1Khz.
+ * This F value is only to protect the hardware from an absence of configuration
+ * and not to complete it when users are not aware that the frequency must be specifically set to support the target board.
+ *
* NOTE: Setting very low frequencies (< 10 Hz) may result in unexpected timer behavior.
+ * Setting very high frequencies can damage your hardware.
*
* USE_OCR2A_AS_TOP [undefined by default]
* Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2:
@@ -457,11 +575,24 @@
* PWM on pin OC2A. Only use this option if you don't need PWM on 0C2A. (Check your schematic.)
* USE_OCR2A_AS_TOP sacrifices duty cycle control resolution to achieve this broader range of frequencies.
*/
+//#define FAST_PWM_FAN // Increase the fan PWM frequency. Removes the PWM noise but increases heating in the FET/Arduino
#if ENABLED(FAST_PWM_FAN)
- //#define FAST_PWM_FAN_FREQUENCY 31400
+ //#define FAST_PWM_FAN_FREQUENCY 31400 // Define here to override the defaults below
//#define USE_OCR2A_AS_TOP
+ #ifndef FAST_PWM_FAN_FREQUENCY
+ #ifdef __AVR__
+ #define FAST_PWM_FAN_FREQUENCY ((F_CPU) / (2 * 255 * 1))
+ #else
+ #define FAST_PWM_FAN_FREQUENCY 1000U
+ #endif
+ #endif
#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 +616,49 @@
#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
+
+/**
+ * Hotend Cooling Fans tachometers
+ *
+ * Define one or more tachometer pins to enable fan speed
+ * monitoring, and reporting of fan speeds with M123.
+ *
+ * NOTE: Only works with fans up to 7000 RPM.
+ */
+//#define FOURWIRES_FANS // Needed with AUTO_FAN when 4-wire PWM fans are installed
+//#define E0_FAN_TACHO_PIN -1
+//#define E0_FAN_TACHO_PULLUP
+//#define E0_FAN_TACHO_PULLDOWN
+//#define E1_FAN_TACHO_PIN -1
+//#define E1_FAN_TACHO_PULLUP
+//#define E1_FAN_TACHO_PULLDOWN
+//#define E2_FAN_TACHO_PIN -1
+//#define E2_FAN_TACHO_PULLUP
+//#define E2_FAN_TACHO_PULLDOWN
+//#define E3_FAN_TACHO_PIN -1
+//#define E3_FAN_TACHO_PULLUP
+//#define E3_FAN_TACHO_PULLDOWN
+//#define E4_FAN_TACHO_PIN -1
+//#define E4_FAN_TACHO_PULLUP
+//#define E4_FAN_TACHO_PULLDOWN
+//#define E5_FAN_TACHO_PIN -1
+//#define E5_FAN_TACHO_PULLUP
+//#define E5_FAN_TACHO_PULLDOWN
+//#define E6_FAN_TACHO_PIN -1
+//#define E6_FAN_TACHO_PULLUP
+//#define E6_FAN_TACHO_PULLDOWN
+//#define E7_FAN_TACHO_PIN -1
+//#define E7_FAN_TACHO_PULLUP
+//#define E7_FAN_TACHO_PULLDOWN
/**
* Part-Cooling Fan Multiplexer
@@ -511,12 +680,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 +728,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 +738,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 +752,11 @@
#define NUM_Z_STEPPER_DRIVERS 1 // (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 +772,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
*
@@ -656,7 +841,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)
@@ -725,12 +910,14 @@
//#define BLTOUCH_FORCE_MODE_SET
/**
- * Use "HIGH SPEED" mode for probing.
+ * Enable "HIGH SPEED" option 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.
+ *
+ * Set the default state here, change with 'M401 S' or UI, use M500 to save, M502 to reset.
*/
- //#define BLTOUCH_HS_MODE
+ //#define BLTOUCH_HS_MODE true
// Safety: Enable voltage mode settings in the LCD menu.
//#define BLTOUCH_LCD_VOLTAGE_MENU
@@ -803,10 +990,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"
@@ -815,8 +1002,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
/**
@@ -840,6 +1027,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
/**
@@ -851,11 +1041,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
-
// 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.
@@ -894,9 +1084,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)
@@ -914,7 +1107,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
@@ -962,6 +1155,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
@@ -1024,7 +1224,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 +1255,7 @@
// @section lcd
-#if EITHER(IS_ULTIPANEL, EXTENSIBLE_UI)
+#if ANY(HAS_LCD_MENU, EXTENSIBLE_UI, HAS_DWIN_E3V2)
#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 FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines
#if IS_ULTIPANEL
@@ -1094,6 +1294,22 @@
// 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
+
+ #if ENABLED(AUTO_BED_LEVELING_BILINEAR)
+ // Add a calibration procedure in the Probe Offsets menu
+ // to compensate for twist in the X-axis.
+ //#define X_AXIS_TWIST_COMPENSATION
+ #if ENABLED(X_AXIS_TWIST_COMPENSATION)
+ /**
+ * 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 XATC_START_Z 0.0
+ #define XATC_MAX_POINTS 3 // Number of points to probe in the wizard
+ #define XATC_Y_POSITION Y_CENTER // (mm) Y position to probe
+ #endif
+ #endif
#endif
// Include a page of printer information in the LCD Main Menu
@@ -1105,9 +1321,6 @@
// BACK menu items keep the highlight at the top
//#define TURBO_BACK_MENU_ITEM
- // Add a mute option to the LCD menu
- //#define SOUND_MENU_ITEM
-
/**
* LED Control Menu
* Add LED Control to the LCD menu
@@ -1134,35 +1347,50 @@
#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 ANY(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED, DWIN_CREALITY_LCD_JYERSUI)
+ //#define SOUND_MENU_ITEM // Add a mute option to the LCD menu
+#endif
+
+#if EITHER(HAS_DISPLAY, DWIN_CREALITY_LCD_ENHANCED)
+ // 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 CAN_SHOW_REMAINING_TIME
+ //#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
@@ -1179,6 +1407,16 @@
#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.
@@ -1203,6 +1441,8 @@
//#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)
@@ -1221,7 +1461,6 @@
#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
@@ -1233,6 +1472,12 @@
// 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
/**
@@ -1321,9 +1566,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
*
@@ -1334,7 +1576,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
/**
@@ -1353,6 +1606,14 @@
#define SD_FIRMWARE_UPDATE_INACTIVE_VALUE 0xFF
#endif
+ /**
+ * Enable this option if you have more than ~3K of unused flash space.
+ * Marlin will embed all settings in the firmware binary as compressed data.
+ * Use 'M503 C' to write the settings out to the SD Card as 'mc.zip'.
+ * See docs/ConfigEmbedding.md for details on how to use 'mc-apply.py'.
+ */
+ //#define CONFIGURATION_EMBEDDING
+
// Add an optimized binary file transfer mode, initiated with 'M28 B1'
//#define BINARY_FILE_TRANSFER
@@ -1360,13 +1621,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 ONBOARD
+ // 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
/**
@@ -1388,16 +1661,10 @@
* printing performance versus fast display updates.
*/
#if HAS_MARLINUI_U8GLIB
- // Show SD percentage next to the progress bar
- //#define DOGM_SD_PERCENT
-
// Save many cycles by drawing a hollow frame or no frame on the Info Screen
//#define XYZ_NO_FRAME
#define XYZ_HOLLOW_FRAME
- // Enable to save many cycles by drawing a hollow frame on Menu Screens
- #define MENU_HOLLOW_FRAME
-
// A bigger font is available for edit items. Costs 3120 bytes of PROGMEM.
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
//#define USE_BIG_EDIT_FONT
@@ -1406,9 +1673,6 @@
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
//#define USE_SMALL_INFOFONT
- // Swap the CW/CCW indicators in the graphics overlay
- //#define OVERLAY_GFX_REVERSE
-
/**
* ST7920-based LCDs can emulate a 16 x 4 character display using
* the ST7920 character-generator for very fast screen updates.
@@ -1421,7 +1685,7 @@
* Set STATUS_EXPIRE_SECONDS to zero to never clear the status.
* This will prevent position updates from being displayed.
*/
- #if ENABLED(U8GLIB_ST7920)
+ #if IS_U8GLIB_ST7920
// Enable this option and reduce the value to optimize screen updates.
// The normal delay is 10µs. Use the lowest value that still gives a reliable display.
//#define DOGM_SPI_DELAY_US 5
@@ -1439,17 +1703,18 @@
*/
//#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.
+ //#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of PROGMEM.
// Frivolous Game Options
//#define MARLIN_BRICKOUT
@@ -1459,6 +1724,17 @@
#endif // HAS_MARLINUI_U8GLIB
+#if HAS_MARLINUI_U8GLIB || IS_DWIN_MARLINUI
+ // Show SD percentage next to the progress bar
+ //#define SHOW_SD_PERCENT
+
+ // Enable to save many cycles by drawing a hollow frame on Menu Screens
+ #define MENU_HOLLOW_FRAME
+
+ // Swap the CW/CCW indicators in the graphics overlay
+ //#define OVERLAY_GFX_REVERSE
+#endif
+
//
// Additional options for DGUS / DWIN displays
//
@@ -1472,12 +1748,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
@@ -1496,6 +1772,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, IS_DWIN_MARLINUI)
+ //#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)
//
@@ -1505,8 +1819,10 @@
//#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272)
//#define LCD_HAOYU_FT800CB // Haoyu with 4.3" or 5" (480x272)
//#define LCD_HAOYU_FT810CB // Haoyu with 5" (800x480)
- //#define LCD_ALEPHOBJECTS_CLCD_UI // Aleph Objects Color LCD UI
+ //#define LCD_LULZBOT_CLCD_UI // LulzBot 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
@@ -1514,8 +1830,8 @@
//#define TOUCH_UI_800x480
// Mappings for boards with a standard RepRapDiscount Display connector
- //#define AO_EXP1_PINMAP // AlephObjects CLCD UI EXP1 mapping
- //#define AO_EXP2_PINMAP // AlephObjects CLCD UI EXP2 mapping
+ //#define AO_EXP1_PINMAP // LulzBot CLCD UI EXP1 mapping
+ //#define AO_EXP2_PINMAP // LulzBot CLCD UI EXP2 mapping
//#define CR10_TFT_PINMAP // Rudolph Riedel's CR10 pin mapping
//#define S6_TFT_PINMAP // FYSETC S6 pin mapping
//#define F6_TFT_PINMAP // FYSETC F6 pin mapping
@@ -1563,18 +1879,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
@@ -1682,7 +1994,8 @@
//#define EXTRA_LIN_ADVANCE_K // Enable for second linear advance constants
#define LIN_ADVANCE_K 0.51 // Unit: mm compression per 1mm/s extruder speed
//#define LA_DEBUG // If enabled, this will generate debug information output over USB.
- #define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration
+ //#define EXPERIMENTAL_SCURVE // Enable this option to permit S-Curve Acceleration
+ //#define ALLOW_LOW_EJERK // Allow a DEFAULT_EJERK value of <10. Recommended for direct drive hotends.
#endif
// @section leveling
@@ -1734,6 +2047,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.
@@ -1754,59 +2071,69 @@
/**
* Thermal Probe Compensation
- * Probe measurements are adjusted to compensate for temperature distortion.
- * Use G76 to calibrate this feature. Use M871 to set values manually.
- * For a more detailed explanation of the process see G76_M871.cpp.
+ *
+ * Adjust probe measurements to compensate for distortion associated with the temperature
+ * of the probe, bed, and/or hotend.
+ * Use G76 to automatically calibrate this feature for probe and bed temperatures.
+ * (Extruder temperature/offset values must be calibrated manually.)
+ * Use M871 to set temperature/offset values manually.
+ * For more details see https://marlinfw.org/docs/features/probe_temp_compensation.html
*/
-#if HAS_BED_PROBE && TEMP_SENSOR_PROBE && TEMP_SENSOR_BED
- // Enable thermal first layer compensation using bed and probe temperatures
- #define PROBE_TEMP_COMPENSATION
+//#define PTC_PROBE // Compensate based on probe temperature
+//#define PTC_BED // Compensate based on bed temperature
+//#define PTC_HOTEND // Compensate based on hotend temperature
- // Add additional compensation depending on hotend temperature
- // Note: this values cannot be calibrated and have to be set manually
- #if ENABLED(PROBE_TEMP_COMPENSATION)
- // Park position to wait for probe cooldown
- #define PTC_PARK_POS { 0, 0, 100 }
-
- // Probe position to probe and wait for probe to reach target temperature
- #define PTC_PROBE_POS { 90, 100 }
-
- // Enable additional compensation using hotend temperature
- // Note: this values cannot be calibrated automatically but have to be set manually
- //#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.
-
- //#define PTC_SAMPLE_START 30.0f
- //#define PTC_SAMPLE_RES 5.0f
- //#define PTC_SAMPLE_COUNT 10U
+#if ANY(PTC_PROBE, PTC_BED, PTC_HOTEND)
+ /**
+ * If the probe is outside the defined range, use linear extrapolation with the closest
+ * point and the point with index PTC_LINEAR_EXTRAPOLATION. e.g., If set to 4 it will use the
+ * linear extrapolation between data[0] and data[4] for values below PTC_PROBE_START.
+ */
+ //#define PTC_LINEAR_EXTRAPOLATION 4
+
+ #if ENABLED(PTC_PROBE)
+ // Probe temperature calibration generates a table of values starting at PTC_PROBE_START
+ // (e.g., 30), in steps of PTC_PROBE_RES (e.g., 5) with PTC_PROBE_COUNT (e.g., 10) samples.
+ #define PTC_PROBE_START 30 // (°C)
+ #define PTC_PROBE_RES 5 // (°C)
+ #define PTC_PROBE_COUNT 10
+ #define PTC_PROBE_ZOFFS { 0 } // (µm) Z adjustments per sample
+ #endif
+ #if ENABLED(PTC_BED)
// Bed temperature calibration builds a similar table.
+ #define PTC_BED_START 60 // (°C)
+ #define PTC_BED_RES 5 // (°C)
+ #define PTC_BED_COUNT 10
+ #define PTC_BED_ZOFFS { 0 } // (µm) Z adjustments per sample
+ #endif
- //#define BTC_SAMPLE_START 60.0f
- //#define BTC_SAMPLE_RES 5.0f
- //#define BTC_SAMPLE_COUNT 10U
+ #if ENABLED(PTC_HOTEND)
+ // Note: There is no automatic calibration for the hotend. Use M871.
+ #define PTC_HOTEND_START 180 // (°C)
+ #define PTC_HOTEND_RES 5 // (°C)
+ #define PTC_HOTEND_COUNT 20
+ #define PTC_HOTEND_ZOFFS { 0 } // (µm) Z adjustments per sample
+ #endif
- // The temperature the probe should be at while taking measurements during bed temperature
- // calibration.
- //#define BTC_PROBE_TEMP 30.0f
+ // G76 options
+ #if BOTH(PTC_PROBE, PTC_BED)
+ // Park position to wait for probe cooldown
+ #define PTC_PARK_POS { 0, 0, 100 }
- // 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
+ // Probe position to probe and wait for probe to reach target temperature
+ //#define PTC_PROBE_POS { 12.0f, 7.3f } // Example: MK52 magnetic heatbed
+ #define PTC_PROBE_POS { 90, 100 }
- // 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
+ // The temperature the probe should be at while taking measurements during
+ // bed temperature calibration.
+ #define PTC_PROBE_TEMP 30 // (°C)
- // 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]
- // and data[4] to perform linear extrapolation for values below PTC_SAMPLE_START.
- //#define PTC_LINEAR_EXTRAPOLATION 4
+ // 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 Z offset (e.g., as set with M851 Z).
+ #define PTC_PROBE_HEATING_OFFSET 0.5
#endif
-#endif
+#endif // PTC_PROBE || PTC_BED || PTC_HOTEND
// @section extras
@@ -1818,20 +2145,23 @@
//
// G2/G3 Arc Support
//
-//#define ARC_SUPPORT // Disable this feature to save ~3226 bytes
+#define ARC_SUPPORT // Requires ~3226 bytes
#if ENABLED(ARC_SUPPORT)
- #define MM_PER_ARC_SEGMENT 1 // (mm) Length (or minimum length) of each arc segment
- //#define ARC_SEGMENTS_PER_R 1 // Max segment length, MM_PER = Min
- #define MIN_ARC_SEGMENTS 24 // Minimum number of segments in a complete circle
- //#define ARC_SEGMENTS_PER_SEC 50 // Use feedrate to choose segment length (with MM_PER_ARC_SEGMENT as the minimum)
- #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections
- //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles
- //#define CNC_WORKSPACE_PLANES // Allow G2/G3 to operate in XY, ZX, or YZ planes
- //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure
+ #define MIN_ARC_SEGMENT_MM 0.1 // (mm) Minimum length of each arc segment
+ #define MAX_ARC_SEGMENT_MM 1.0 // (mm) Maximum length of each arc segment
+ #define MIN_CIRCLE_SEGMENTS 72 // Minimum number of segments in a complete circle
+ //#define ARC_SEGMENTS_PER_SEC 50 // Use the feedrate to choose the segment length
+ #define N_ARC_CORRECTION 25 // Number of interpolated segments between corrections
+ //#define ARC_P_CIRCLES // Enable the 'P' parameter to specify complete circles
+ //#define SF_ARC_FIX // Enable only if using SkeinForge with "Arc Point" fillet procedure
#endif
-// Support for G5 with XYZE destination and IJPQ offsets. Requires ~2666 bytes.
-//#define BEZIER_CURVE_SUPPORT
+// G5 Bézier Curve Support with XYZE destination and IJPQ offsets
+//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes
+
+#if EITHER(ARC_SUPPORT, BEZIER_CURVE_SUPPORT)
+ //#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes
+#endif
/**
* Direct Stepping
@@ -1914,7 +2244,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)
@@ -1950,9 +2280,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.
@@ -1963,6 +2290,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
*
@@ -1973,6 +2306,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'.
@@ -2016,21 +2369,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
@@ -2047,6 +2400,20 @@
//#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
+ //#define EVENT_GCODE_TOOLCHANGE_ALWAYS_RUN // Always execute above G-code sequences. Use with caution!
+
+ /**
+ * 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.
@@ -2062,7 +2429,7 @@
// Longer prime to clean out a SINGLENOZZLE
#define TOOLCHANGE_FS_EXTRA_PRIME 0 // (mm) Extra priming length
#define TOOLCHANGE_FS_PRIME_SPEED (4.6*60) // (mm/min) Extra priming feedrate
- #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm/min) Retract before cooling for less stringing, better wipe, etc.
+ #define TOOLCHANGE_FS_WIPE_RETRACT 0 // (mm) Retract before cooling for less stringing, better wipe, etc.
// Cool after prime to reduce stringing
#define TOOLCHANGE_FS_FAN -1 // Fan index or -1 to skip
@@ -2105,14 +2472,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.
+ *
+ * Requirements:
+ * - For Filament Change parking enable and configure NOZZLE_PARK_FEATURE.
+ * - For user interaction enable an LCD display, HOST_PROMPT_SUPPORT, or EMERGENCY_PARSER.
*
- * Requires an LCD display.
- * Requires NOZZLE_PARK_FEATURE.
- * This feature is required for the default FILAMENT_RUNOUT_SCRIPT.
+ * Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park.
*/
#define ADVANCED_PAUSE_FEATURE
#if ENABLED(ADVANCED_PAUSE_FEATURE)
@@ -2151,6 +2519,8 @@
#define PAUSE_PARK_NOZZLE_TIMEOUT 60 // (seconds) Time limit before the nozzle is turned off for safety.
#define FILAMENT_CHANGE_ALERT_BEEPS 3 // Number of alert beeps to play when a response is needed.
#define PAUSE_PARK_NO_STEPPER_TIMEOUT // Enable for XYZ steppers to stay powered on during filament change.
+ //#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again.
+ //#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing.
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
@@ -2178,7 +2548,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)
@@ -2190,7 +2560,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)
@@ -2202,19 +2572,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)
@@ -2226,43 +2614,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
@@ -2302,15 +2690,17 @@
#define X_RSENSE 0.11
#define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
//#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis
+ //#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis
#endif
#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
+ //#define X2_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Y)
@@ -2320,15 +2710,17 @@
#define Y_RSENSE 0.11
#define Y_CHAIN_POS -1
//#define Y_INTERPOLATE true
+ //#define Y_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define Y2_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(Z)
@@ -2338,33 +2730,67 @@
#define Z_RSENSE 0.11
#define Z_CHAIN_POS -1
//#define Z_INTERPOLATE true
+ //#define Z_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define Z2_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define Z3_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define Z4_HOLD_MULTIPLIER 0.5
+ #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
+ //#define I_HOLD_MULTIPLIER 0.5
+ #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
+ //#define J_HOLD_MULTIPLIER 0.5
+ #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
+ //#define K_HOLD_MULTIPLIER 0.5
#endif
#if AXIS_IS_TMC(E0)
@@ -2373,62 +2799,70 @@
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
//#define E0_INTERPOLATE true
+ //#define E0_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E1_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E2_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E3_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E4_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E5_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E6_HOLD_MULTIPLIER 0.5
#endif
#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
+ //#define E7_HOLD_MULTIPLIER 0.5
#endif
/**
@@ -2442,6 +2876,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
@@ -2473,22 +2911,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 2
- #define Z_SLAVE_ADDRESS 1
- #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 3
- #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
@@ -2505,6 +2946,9 @@
*/
#define STEALTHCHOP_XY
#define STEALTHCHOP_Z
+ #define STEALTHCHOP_I
+ #define STEALTHCHOP_J
+ #define STEALTHCHOP_K
#define STEALTHCHOP_E
/**
@@ -2522,23 +2966,26 @@
* 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)
+ //#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_I CHOPPER_TIMING
+ //#define CHOPPER_TIMING_J CHOPPER_TIMING
+ //#define CHOPPER_TIMING_K CHOPPER_TIMING
+ //#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
@@ -2576,6 +3023,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
@@ -2601,7 +3051,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.
*
@@ -2622,6 +3072,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
@@ -2646,7 +3099,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
@@ -2700,138 +3153,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
/**
@@ -2961,16 +3441,30 @@
//#define SPINDLE_FEATURE
//#define LASER_FEATURE
#if EITHER(SPINDLE_FEATURE, LASER_FEATURE)
- #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if the on/off function is active HIGH
- #define SPINDLE_LASER_PWM true // Set to "true" if your controller supports setting the speed/power
- #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
+ #define SPINDLE_LASER_ACTIVE_STATE LOW // Set to "HIGH" if SPINDLE_LASER_ENA_PIN is active HIGH
+
+ #define SPINDLE_LASER_USE_PWM // Enable if your controller supports setting the speed/power
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ #define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
+ #define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
+ #endif
+
+ //#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 SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR and LPC)
+ //#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
+ //#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
/**
@@ -3009,17 +3503,25 @@
* Speed/Power = (PWMDC / 255 * 100 - SPEED_POWER_INTERCEPT) / SPEED_POWER_SLOPE
* PWMDC = (spdpwr - SPEED_POWER_MIN) / (SPEED_POWER_MAX - SPEED_POWER_MIN) / SPEED_POWER_SLOPE
*/
- #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
- #define SPEED_POWER_MIN 5000 // (RPM)
- #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM
- #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
+ #define SPEED_POWER_MIN 5000 // (RPM)
+ #define SPEED_POWER_MAX 30000 // (RPM) SuperPID router controller 0 - 30,000 RPM
+ #define SPEED_POWER_STARTUP 25000 // (RPM) M3/M4 speed/power default (with no arguments)
+ #endif
#else
- #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
- #define SPEED_POWER_MIN 0 // (%) 0-100
- #define SPEED_POWER_MAX 100 // (%) 0-100
- #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
+ #if ENABLED(SPINDLE_LASER_USE_PWM)
+ #define SPEED_POWER_INTERCEPT 0 // (%) 0-100 i.e., Minimum power percentage
+ #define SPEED_POWER_MIN 0 // (%) 0-100
+ #define SPEED_POWER_MAX 100 // (%) 0-100
+ #define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
+ #endif
+
+ // 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.
@@ -3095,8 +3597,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
@@ -3157,13 +3681,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
*
@@ -3172,11 +3710,22 @@
*/
//#define CNC_COORDINATE_SYSTEMS
+/**
+ * Auto-report fan speed with M123 S
+ * Requires fans with tachometer pins
+ */
+//#define AUTO_REPORT_FANS
+
/**
* Auto-report temperatures with M155 S
*/
#define AUTO_REPORT_TEMPERATURES
+/**
+ * Auto-report position with M154 S
+ */
+//#define AUTO_REPORT_POSITION
+
/**
* Include capabilities in M115 output
*/
@@ -3246,7 +3795,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
@@ -3254,6 +3803,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
@@ -3293,29 +3846,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
/**
@@ -3334,8 +3957,10 @@
*/
//#define HOST_ACTION_COMMANDS
#if ENABLED(HOST_ACTION_COMMANDS)
+ //#define HOST_PAUSE_M76
//#define HOST_PROMPT_SUPPORT
- //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
+ //#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
+ //#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down
#endif
/**
@@ -3344,6 +3969,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.
@@ -3420,7 +4048,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
@@ -3465,6 +4093,16 @@
#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
*
@@ -3501,14 +4139,13 @@
/**
* 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
/**
@@ -3560,10 +4197,7 @@
//#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
@@ -3679,3 +4313,27 @@
// Enable Marlin dev mode which adds some special commands
//#define MARLIN_DEV_MODE
+
+#if ENABLED(MARLIN_DEV_MODE)
+ /**
+ * D576 - Buffer Monitoring
+ * To help diagnose print quality issues stemming from empty command buffers.
+ */
+ //#define BUFFER_MONITORING
+#endif
+
+/**
+ * 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
+
+// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR.
+//#define OPTIBOOT_RESET_REASON
diff --git a/Marlin/Makefile b/Marlin/Makefile
index 49cb960b92fe..eee1403b537c 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)
@@ -191,6 +191,134 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1034)
# RAMPS Derivatives - ATmega1280, ATmega2560
#
+# 3Drag Controller
+else ifeq ($(HARDWARE_MOTHERBOARD),1100)
+# Velleman K8200 Controller (derived from 3Drag Controller)
+else ifeq ($(HARDWARE_MOTHERBOARD),1101)
+# Velleman K8400 Controller (derived from 3Drag Controller)
+else ifeq ($(HARDWARE_MOTHERBOARD),1102)
+# Velleman K8600 Controller (Vertex Nano)
+else ifeq ($(HARDWARE_MOTHERBOARD),1103)
+# Velleman K8800 Controller (Vertex Delta)
+else ifeq ($(HARDWARE_MOTHERBOARD),1104)
+# 2PrintBeta BAM&DICE with STK drivers
+else ifeq ($(HARDWARE_MOTHERBOARD),1105)
+# 2PrintBeta BAM&DICE Due with STK drivers
+else ifeq ($(HARDWARE_MOTHERBOARD),1106)
+# MKS BASE v1.0
+else ifeq ($(HARDWARE_MOTHERBOARD),1107)
+# MKS BASE v1.4 with Allegro A4982 stepper drivers
+else ifeq ($(HARDWARE_MOTHERBOARD),1108)
+# MKS BASE v1.5 with Allegro A4982 stepper drivers
+else ifeq ($(HARDWARE_MOTHERBOARD),1109)
+# MKS BASE v1.6 with Allegro A4982 stepper drivers
+else ifeq ($(HARDWARE_MOTHERBOARD),1110)
+# MKS BASE 1.0 with Heroic HR4982 stepper drivers
+else ifeq ($(HARDWARE_MOTHERBOARD),1111)
+# MKS GEN v1.3 or 1.4
+else ifeq ($(HARDWARE_MOTHERBOARD),1112)
+# MKS GEN L
+else ifeq ($(HARDWARE_MOTHERBOARD),1113)
+# BigTreeTech or BIQU KFB2.0
+else ifeq ($(HARDWARE_MOTHERBOARD),1114)
+# zrib V2.0 (Chinese RAMPS replica)
+else ifeq ($(HARDWARE_MOTHERBOARD),1115)
+# zrib V5.2 (Chinese RAMPS replica)
+else ifeq ($(HARDWARE_MOTHERBOARD),1116)
+# Felix 2.0+ Electronics Board (RAMPS like)
+else ifeq ($(HARDWARE_MOTHERBOARD),1117)
+# Invent-A-Part RigidBoard
+else ifeq ($(HARDWARE_MOTHERBOARD),1118)
+# Invent-A-Part RigidBoard V2
+else ifeq ($(HARDWARE_MOTHERBOARD),1119)
+# Sainsmart 2-in-1 board
+else ifeq ($(HARDWARE_MOTHERBOARD),1120)
+# Ultimaker
+else ifeq ($(HARDWARE_MOTHERBOARD),1121)
+# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
+else ifeq ($(HARDWARE_MOTHERBOARD),1122)
+ MCU ?= atmega1280
+ PROG_MCU ?= m1280
+# Azteeg X3
+else ifeq ($(HARDWARE_MOTHERBOARD),1123)
+# Azteeg X3 Pro
+else ifeq ($(HARDWARE_MOTHERBOARD),1124)
+# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
+else ifeq ($(HARDWARE_MOTHERBOARD),1125)
+# Rumba
+else ifeq ($(HARDWARE_MOTHERBOARD),1126)
+# Raise3D N series Rumba derivative
+else ifeq ($(HARDWARE_MOTHERBOARD),1127)
+# Rapide Lite 200 (v1, low-cost RUMBA clone with drv)
+else ifeq ($(HARDWARE_MOTHERBOARD),1128)
+# Formbot T-Rex 2 Plus
+else ifeq ($(HARDWARE_MOTHERBOARD),1129)
+# Formbot T-Rex 3
+else ifeq ($(HARDWARE_MOTHERBOARD),1130)
+# Formbot Raptor
+else ifeq ($(HARDWARE_MOTHERBOARD),1131)
+# Formbot Raptor 2
+else ifeq ($(HARDWARE_MOTHERBOARD),1132)
+# bq ZUM Mega 3D
+else ifeq ($(HARDWARE_MOTHERBOARD),1133)
+# MakeBoard Mini v2.1.2 by MicroMake
+else ifeq ($(HARDWARE_MOTHERBOARD),1134)
+# TriGorilla Anycubic version 1.3-based on RAMPS EFB
+else ifeq ($(HARDWARE_MOTHERBOARD),1135)
+# ... Ver 1.4
+else ifeq ($(HARDWARE_MOTHERBOARD),1136)
+# ... Rev 1.1 (new servo pin order)
+else ifeq ($(HARDWARE_MOTHERBOARD),1137)
+# Creality: Ender-4, CR-8
+else ifeq ($(HARDWARE_MOTHERBOARD),1138)
+# Creality: CR10S, CR20, CR-X
+else ifeq ($(HARDWARE_MOTHERBOARD),1139)
+# Dagoma F5
+else ifeq ($(HARDWARE_MOTHERBOARD),1140)
+# FYSETC F6 1.3
+else ifeq ($(HARDWARE_MOTHERBOARD),1141)
+# FYSETC F6 1.4
+else ifeq ($(HARDWARE_MOTHERBOARD),1142)
+# Wanhao Duplicator i3 Plus
+else ifeq ($(HARDWARE_MOTHERBOARD),1143)
+# VORON Design
+else ifeq ($(HARDWARE_MOTHERBOARD),1144)
+# Tronxy TRONXY-V3-1.0
+else ifeq ($(HARDWARE_MOTHERBOARD),1145)
+# Z-Bolt X Series
+else ifeq ($(HARDWARE_MOTHERBOARD),1146)
+# TT OSCAR
+else ifeq ($(HARDWARE_MOTHERBOARD),1147)
+# Overlord/Overlord Pro
+else ifeq ($(HARDWARE_MOTHERBOARD),1148)
+# ADIMLab Gantry v1
+else ifeq ($(HARDWARE_MOTHERBOARD),1149)
+# ADIMLab Gantry v2
+else ifeq ($(HARDWARE_MOTHERBOARD),1150)
+# BIQU Tango V1
+else ifeq ($(HARDWARE_MOTHERBOARD),1151)
+# MKS GEN L V2
+else ifeq ($(HARDWARE_MOTHERBOARD),1152)
+# MKS GEN L V2.1
+else ifeq ($(HARDWARE_MOTHERBOARD),1153)
+# Copymaster 3D
+else ifeq ($(HARDWARE_MOTHERBOARD),1154)
+# Ortur 4
+else ifeq ($(HARDWARE_MOTHERBOARD),1155)
+# Tenlog D3 Hero IDEX printer
+else ifeq ($(HARDWARE_MOTHERBOARD),1156)
+# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
+else ifeq ($(HARDWARE_MOTHERBOARD),1157)
+# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
+else ifeq ($(HARDWARE_MOTHERBOARD),1158)
+# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
+else ifeq ($(HARDWARE_MOTHERBOARD),1159)
+# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
+else ifeq ($(HARDWARE_MOTHERBOARD),1160)
+# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
+else ifeq ($(HARDWARE_MOTHERBOARD),1161)
+
+
# 3Drag Controller
else ifeq ($(HARDWARE_MOTHERBOARD),1100)
# Velleman K8200 Controller (derived from 3Drag Controller)
@@ -219,7 +347,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 +451,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
@@ -356,20 +486,38 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1311)
else ifeq ($(HARDWARE_MOTHERBOARD),1312)
# Mega controller
else ifeq ($(HARDWARE_MOTHERBOARD),1313)
-# Geeetech GT2560 Rev B for Mecreator2
+# Geeetech GT2560 Rev A
else ifeq ($(HARDWARE_MOTHERBOARD),1314)
-# Geeetech GT2560 Rev. A
+# Geeetech GT2560 Rev A+ (with auto level probe)
else ifeq ($(HARDWARE_MOTHERBOARD),1315)
-# Geeetech GT2560 Rev. A+ (with auto level probe)
+# Geeetech GT2560 Rev B
else ifeq ($(HARDWARE_MOTHERBOARD),1316)
-# Geeetech GT2560 Rev B for A10(M/D)
+# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1317)
-# Geeetech GT2560 Rev B for A20(M/D)
+# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
-# Einstart retrofit
+# Geeetech GT2560 Rev B for Mecreator2
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
-# Wanhao 0ne+ i3 Mini
+# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
+# Einstart retrofit
+else ifeq ($(HARDWARE_MOTHERBOARD),1321)
+# Wanhao 0ne+ i3 Mini
+else ifeq ($(HARDWARE_MOTHERBOARD),1322)
+# Leapfrog Xeed 2015
+else ifeq ($(HARDWARE_MOTHERBOARD),1323)
+# PICA Shield (original version)
+else ifeq ($(HARDWARE_MOTHERBOARD),1324)
+# PICA Shield (rev C or later)
+else ifeq ($(HARDWARE_MOTHERBOARD),1325)
+# Intamsys 4.0 (Funmat HT)
+else ifeq ($(HARDWARE_MOTHERBOARD),1326)
+# Malyan M180 Mainboard Version 2 (no display function, direct gcode only)
+else ifeq ($(HARDWARE_MOTHERBOARD),1327)
+# Geeetech GT2560 Rev B for A20(M/T/D)
+else ifeq ($(HARDWARE_MOTHERBOARD),1328)
+# Mega controller & Protoneer CNC Shield V3.00
+else ifeq ($(HARDWARE_MOTHERBOARD),1329)
#
# ATmega1281, ATmega2561
@@ -443,6 +591,11 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1510)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
+# ZoneStar ZMIB V2
+else ifeq ($(HARDWARE_MOTHERBOARD),1511)
+ HARDWARE_VARIANT ?= Sanguino
+ MCU ?= atmega1284p
+ PROG_MCU ?= m1284p
#
# Other ATmega644P, ATmega644, ATmega1284P
@@ -991,5 +1144,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 fe0724fbfcb1..40136a36847d 100644
--- a/Marlin/Version.h
+++ b/Marlin/Version.h
@@ -28,7 +28,7 @@
/**
* Marlin release version identifier
*/
-//#define SHORT_BUILD_VERSION "bugfix-2.0.x"
+//#define SHORT_BUILD_VERSION "2.0.9.3"
/**
* 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 "2019-07-10"
+//#define STRING_DISTRIBUTION_DATE "2021-12-25"
/**
* 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..d7bf2a6f6fbb 100644
--- a/Marlin/src/HAL/AVR/HAL.cpp
+++ b/Marlin/src/HAL/AVR/HAL.cpp
@@ -24,16 +24,42 @@
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
+#ifdef USBCON
+ DefaultSerial1 MSerial0(false, Serial);
+ #ifdef BLUETOOTH
+ BTSerial btSerial(false, bluetoothSerial);
+ #endif
+#endif
+
// ------------------------
// Public Variables
// ------------------------
-//uint8_t MCUSR;
+// Don't initialize/override variable (which would happen in .init4)
+uint8_t reset_reason __attribute__((section(".noinit")));
// ------------------------
// Public functions
// ------------------------
+__attribute__((naked)) // Don't output function pro- and epilogue
+__attribute__((used)) // Output the function, even if "not used"
+__attribute__((section(".init3"))) // Put in an early user definable section
+void HAL_save_reset_reason() {
+ #if ENABLED(OPTIBOOT_RESET_REASON)
+ __asm__ __volatile__(
+ A("STS %0, r2")
+ : "=m"(reset_reason)
+ );
+ #else
+ reset_reason = MCUSR;
+ #endif
+
+ // Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop
+ MCUSR = 0;
+ wdt_disable();
+}
+
void HAL_init() {
// Init Servo Pins
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
@@ -51,6 +77,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 aa6a32132032..2217f239d64e 100644
--- a/Marlin/src/HAL/AVR/HAL.h
+++ b/Marlin/src/HAL/AVR/HAL.h
@@ -39,6 +39,19 @@
#include
#include
+//
+// Default graphical display delays
+//
+#if F_CPU >= 20000000
+ #define CPU_ST7920_DELAY_1 150
+ #define CPU_ST7920_DELAY_2 0
+ #define CPU_ST7920_DELAY_3 150
+#elif F_CPU == 16000000
+ #define CPU_ST7920_DELAY_1 125
+ #define CPU_ST7920_DELAY_2 0
+ #define CPU_ST7920_DELAY_3 188
+#endif
+
#ifndef pgm_read_ptr
// Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for
// Windows Subsystem for Linux on Windows 10 as of 10/18/2019
@@ -78,28 +91,50 @@ typedef int8_t pin_t;
// Public Variables
// ------------------------
-//extern uint8_t MCUSR;
+extern uint8_t reset_reason;
// Serial ports
#ifdef USBCON
- #define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
+ #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 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 MYSERIAL1 customizedSerial2
+ #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
@@ -117,21 +152,19 @@ void HAL_init();
//void _delay_ms(const int delay);
-inline void HAL_clear_reset_source() { MCUSR = 0; }
-inline uint8_t HAL_get_reset_source() { return MCUSR; }
+inline void HAL_clear_reset_source() { }
+inline uint8_t HAL_get_reset_source() { return reset_reason; }
-inline void HAL_reboot() {} // reboot the board or restart the bootloader
+void HAL_reboot();
+#pragma GCC diagnostic push
#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
+#pragma GCC diagnostic pop
// ADC
#ifdef DIDR2
@@ -164,7 +197,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)
@@ -188,7 +221,7 @@ void set_pwm_frequency(const pin_t pin, int f_desired);
/**
* set_pwm_duty
- * Sets the PWM duty cycle of the provided pin to the provided value
+ * 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]
*/
diff --git a/Marlin/src/HAL/AVR/HAL_SPI.cpp b/Marlin/src/HAL/AVR/HAL_SPI.cpp
index 31e589746cf2..8784bb07b30e 100644
--- a/Marlin/src/HAL/AVR/HAL_SPI.cpp
+++ b/Marlin/src/HAL/AVR/HAL_SPI.cpp
@@ -34,17 +34,19 @@
#include "../../inc/MarlinConfig.h"
void spiBegin() {
- OUT_WRITE(SS_PIN, HIGH);
- SET_OUTPUT(SCK_PIN);
- SET_INPUT(MISO_PIN);
- SET_OUTPUT(MOSI_PIN);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ #endif
+ 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);
@@ -74,7 +76,8 @@ void spiBegin() {
#elif defined(PRR0)
PRR0
#endif
- , PRSPI);
+ , PRSPI
+ );
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
@@ -88,7 +91,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 +110,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 +198,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 +218,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 +228,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 +239,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/MarlinSPI.h b/Marlin/src/HAL/AVR/MarlinSPI.h
new file mode 100644
index 000000000000..0c447ba4cb3d
--- /dev/null
+++ b/Marlin/src/HAL/AVR/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * 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
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.cpp b/Marlin/src/HAL/AVR/MarlinSerial.cpp
index 63599efd4132..cd8bf5e6903b 100644
--- a/Marlin/src/HAL/AVR/MarlinSerial.cpp
+++ b/Marlin/src/HAL/AVR/MarlinSerial.cpp
@@ -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 // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
- HardwareSerial bluetoothSerial;
+ MSerialBT bluetoothSerial(false);
#endif
#endif // __AVR__
diff --git a/Marlin/src/HAL/AVR/MarlinSerial.h b/Marlin/src/HAL/AVR/MarlinSerial.h
index 8a0423d143d8..84c5ddd2978e 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 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 defined(USBCON) && ENABLED(BLUETOOTH)
- extern HardwareSerial bluetoothSerial;
+ typedef Serial1Class MSerialBT;
+ extern MSerialBT bluetoothSerial;
#endif
diff --git a/Marlin/src/HAL/AVR/eeprom.cpp b/Marlin/src/HAL/AVR/eeprom.cpp
index ee2a73e410ad..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;
diff --git a/Marlin/src/HAL/AVR/endstop_interrupts.h b/Marlin/src/HAL/AVR/endstop_interrupts.h
index 9fd9c38b86ad..50f29c3356ce 100644
--- a/Marlin/src/HAL/AVR/endstop_interrupts.h
+++ b/Marlin/src/HAL/AVR/endstop_interrupts.h
@@ -168,6 +168,51 @@ void setup_endstop_interrupts() {
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);
@@ -256,6 +301,5 @@ void setup_endstop_interrupts() {
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/fast_pwm.cpp b/Marlin/src/HAL/AVR/fast_pwm.cpp
index 238c1124adeb..804e5fad3070 100644
--- a/Marlin/src/HAL/AVR/fast_pwm.cpp
+++ b/Marlin/src/HAL/AVR/fast_pwm.cpp
@@ -22,11 +22,10 @@
#ifdef __AVR__
#include "../../inc/MarlinConfigPre.h"
+#include "HAL.h"
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
-#include "HAL.h"
-
struct Timer {
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
volatile uint16_t* OCRnQ[3]; // max 3 OCR registers per timer
@@ -55,8 +54,8 @@ Timer get_pwm_timer(const pin_t pin) {
case TIMER1A: case TIMER1B:
#endif
break;
- #if defined(TCCR2) || defined(TCCR2A)
- #ifdef TCCR2
+ #if HAS_TCCR2 || defined(TCCR2A)
+ #if HAS_TCCR2
case TIMER2: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2, nullptr, nullptr },
@@ -153,7 +152,7 @@ Timer get_pwm_timer(const pin_t pin) {
void set_pwm_frequency(const pin_t pin, int f_desired) {
Timer timer = get_pwm_timer(pin);
- if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
+ if (timer.n == 0) return; // Don't proceed if protected timer or not recognized
uint16_t size;
if (timer.n == 2) size = 255; else size = 65535;
@@ -201,16 +200,10 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
res = res_temp_fast;
j = i;
// Set the Wave Generation Mode to FAST PWM
- if (timer.n == 2) {
- wgm = (
- #if ENABLED(USE_OCR2A_AS_TOP)
- WGM2_FAST_PWM_OCR2A
- #else
- WGM2_FAST_PWM
- #endif
- );
- }
- else wgm = WGM_FAST_PWM_ICRn;
+ if (timer.n == 2)
+ wgm = TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM);
+ else
+ wgm = WGM_FAST_PWM_ICRn;
}
// If PHASE CORRECT values are closes to desired f
else if (f_phase_diff < f_diff) {
@@ -218,16 +211,10 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
res = res_temp_phase_correct;
j = i;
// Set the Wave Generation Mode to PWM PHASE CORRECT
- if (timer.n == 2) {
- wgm = (
- #if ENABLED(USE_OCR2A_AS_TOP)
- WGM2_PWM_PC_OCR2A
- #else
- WGM2_PWM_PC
- #endif
- );
- }
- else wgm = WGM_PWM_PC_ICRn;
+ if (timer.n == 2)
+ wgm = TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM);
+ else
+ wgm = WGM_PWM_PC_ICRn;
}
}
}
@@ -235,48 +222,39 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
_SET_CSn(timer.TCCRnQ, j);
if (timer.n == 2) {
- #if ENABLED(USE_OCR2A_AS_TOP)
- _SET_OCRnQ(timer.OCRnQ, 0, res); // Set OCR2A value (TOP) = res
- #endif
+ TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer.OCRnQ, 0, res)); // Set OCR2A value (TOP) = res
}
else
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
}
+#endif // NEEDS_HARDWARE_PWM
+
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
- // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
- // Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
- if (v == 0)
- digitalWrite(pin, invert);
- else if (v == v_size)
- digitalWrite(pin, !invert);
- else {
- Timer timer = get_pwm_timer(pin);
- if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
- // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
- _SET_COMnQ(timer.TCCRnQ, (timer.q
- #ifdef TCCR2
- + (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
- #endif
- ), COM_CLEAR_SET + invert
- );
+ #if NEEDS_HARDWARE_PWM
- uint16_t top;
- if (timer.n == 2) { // if TIMER2
- top = (
- #if ENABLED(USE_OCR2A_AS_TOP)
- *timer.OCRnQ[0] // top = OCR2A
- #else
- 255 // top = 0xFF (max)
- #endif
- );
+ // If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
+ // Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
+ if (v == 0)
+ digitalWrite(pin, invert);
+ else if (v == v_size)
+ digitalWrite(pin, !invert);
+ else {
+ Timer timer = get_pwm_timer(pin);
+ if (timer.n == 0) return; // Don't proceed if protected timer or not recognized
+ // Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
+ _SET_COMnQ(timer.TCCRnQ, timer.q TERN_(HAS_TCCR2, + (timer.q == 2)), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2
+ const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
+ _SET_OCRnQ(timer.OCRnQ, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value
}
- else
- top = *timer.ICRn; // top = ICRn
- _SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top) / float(v_size)); // Scale 8/16-bit v to top value
- }
+ #else
+
+ analogWrite(pin, v);
+ UNUSED(v_size);
+ UNUSED(invert);
+
+ #endif
}
-#endif // NEEDS_HARDWARE_PWM
#endif // __AVR__
diff --git a/Marlin/src/HAL/AVR/fastio.cpp b/Marlin/src/HAL/AVR/fastio.cpp
index b51d7f97686a..8af3ef805efa 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.
@@ -267,11 +267,11 @@ uint16_t set_pwm_frequency_hz(const float &hz, const float dca, const float dcb,
SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP
//SERIAL_ECHOLNPGM("Timer 5 Settings:");
- //SERIAL_ECHOLNPAIR(" Prescaler=", prescaler);
- //SERIAL_ECHOLNPAIR(" TOP=", ICR5);
- //SERIAL_ECHOLNPAIR(" OCR5A=", OCR5A);
- //SERIAL_ECHOLNPAIR(" OCR5B=", OCR5B);
- //SERIAL_ECHOLNPAIR(" OCR5C=", OCR5C);
+ //SERIAL_ECHOLNPGM(" Prescaler=", prescaler);
+ //SERIAL_ECHOLNPGM(" TOP=", ICR5);
+ //SERIAL_ECHOLNPGM(" OCR5A=", OCR5A);
+ //SERIAL_ECHOLNPGM(" OCR5B=", OCR5B);
+ //SERIAL_ECHOLNPGM(" OCR5C=", OCR5C);
}
else {
// Restore the default for Timer 5
diff --git a/Marlin/src/HAL/AVR/fastio.h b/Marlin/src/HAL/AVR/fastio.h
index dd0163466110..db6e598b8670 100644
--- a/Marlin/src/HAL/AVR/fastio.h
+++ b/Marlin/src/HAL/AVR/fastio.h
@@ -211,32 +211,32 @@ enum ClockSource2 : char {
// Set Clock Select bits
// Ex: SET_CS3(PRESCALER_64);
+#ifdef TCCR2
+ #define HAS_TCCR2 1
+#endif
#define _SET_CS(T,V) (TCCR##T##B = (TCCR##T##B & ~(0x7 << CS##T##0)) | ((int(V) & 0x7) << CS##T##0))
#define _SET_CS0(V) _SET_CS(0,V)
#define _SET_CS1(V) _SET_CS(1,V)
-#ifdef TCCR2
- #define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
-#else
- #define _SET_CS2(V) _SET_CS(2,V)
-#endif
#define _SET_CS3(V) _SET_CS(3,V)
#define _SET_CS4(V) _SET_CS(4,V)
#define _SET_CS5(V) _SET_CS(5,V)
#define SET_CS0(V) _SET_CS0(CS_##V)
#define SET_CS1(V) _SET_CS1(CS_##V)
-#ifdef TCCR2
+
+#if HAS_TCCR2
+ #define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
#define SET_CS2(V) _SET_CS2(CS2_##V)
#else
+ #define _SET_CS2(V) _SET_CS(2,V)
#define SET_CS2(V) _SET_CS2(CS_##V)
#endif
+
#define SET_CS3(V) _SET_CS3(CS_##V)
#define SET_CS4(V) _SET_CS4(CS_##V)
#define SET_CS5(V) _SET_CS5(CS_##V)
#define SET_CS(T,V) SET_CS##T(V)
// Runtime (see set_pwm_frequency)
-#define _SET_CSn(TCCRnQ, V) do{ \
- (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)); \
- }while(0)
+#define _SET_CSn(TCCRnQ, V) (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
// Set Compare Mode bits
// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET);
@@ -247,21 +247,15 @@ enum ClockSource2 : char {
#define SET_COMC(T,V) SET_COM(T,C,V)
#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
// Runtime (see set_pwm_duty)
-#define _SET_COMnQ(TCCRnQ, Q, V) do{ \
- (*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))); \
- }while(0)
+#define _SET_COMnQ(TCCRnQ, Q, V) (*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q))))
// Set OCRnQ register
// Runtime (see set_pwm_duty):
-#define _SET_OCRnQ(OCRnQ, Q, V) do{ \
- (*(OCRnQ)[(Q)] = (0x0000) | (int(V) & 0xFFFF)); \
- }while(0)
+#define _SET_OCRnQ(OCRnQ, Q, V) (*(OCRnQ)[Q] = int(V) & 0xFFFF)
// Set ICRn register (one per timer)
// Runtime (see set_pwm_frequency)
-#define _SET_ICRn(ICRn, V) do{ \
- (*(ICRn) = (0x0000) | (int(V) & 0xFFFF)); \
- }while(0)
+#define _SET_ICRn(ICRn, V) (*(ICRn) = int(V) & 0xFFFF)
// Set Noise Canceler bit
// Ex: SET_ICNC(2,1)
@@ -284,8 +278,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..2f80d1fee165 100644
--- a/Marlin/src/HAL/AVR/inc/SanityCheck.h
+++ b/Marlin/src/HAL/AVR/inc/SanityCheck.h
@@ -28,14 +28,14 @@
/**
* Checks for FAST PWM
*/
-#if ENABLED(FAST_PWM_FAN) && (ENABLED(USE_OCR2A_AS_TOP) && defined(TCCR2))
+#if ALL(FAST_PWM_FAN, USE_OCR2A_AS_TOP, HAS_TCCR2)
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
#endif
/**
* Sanity checks for Spindle / Laser PWM
*/
-#if ENABLED(SPINDLE_LASER_PWM)
+#if ENABLED(SPINDLE_LASER_USE_PWM)
#include "../ServoTimers.h" // Needed to check timer availability (_useTimer3)
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
@@ -43,7 +43,7 @@
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
#elif defined(SPINDLE_LASER_FREQUENCY)
- #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_PWM."
+ #error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM."
#endif
/**
@@ -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..0f564df987f3 100644
--- a/Marlin/src/HAL/AVR/pinsDebug.h
+++ b/Marlin/src/HAL/AVR/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -38,7 +41,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
@@ -99,7 +102,7 @@ void PRINT_ARRAY_NAME(uint8_t x) {
return true; \
} else return false
-
+#define ABTEST(N) defined(TCCR##N##A) && defined(COM##N##A1)
/**
* Print a pin's PWM status.
@@ -110,7 +113,7 @@ static bool pwm_status(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
- #if defined(TCCR0A) && defined(COM0A1)
+ #if ABTEST(0)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
PWM_CASE(0, A);
@@ -119,20 +122,20 @@ static bool pwm_status(uint8_t pin) {
PWM_CASE(0, B);
#endif
- #if defined(TCCR1A) && defined(COM1A1)
+ #if ABTEST(1)
PWM_CASE(1, A);
PWM_CASE(1, B);
- #if defined(COM1C1) && defined(TIMER1C)
- PWM_CASE(1, C);
- #endif
+ #if defined(COM1C1) && defined(TIMER1C)
+ PWM_CASE(1, C);
+ #endif
#endif
- #if defined(TCCR2A) && defined(COM2A1)
+ #if ABTEST(2)
PWM_CASE(2, A);
PWM_CASE(2, B);
#endif
- #if defined(TCCR3A) && defined(COM3A1)
+ #if ABTEST(3)
PWM_CASE(3, A);
PWM_CASE(3, B);
#ifdef COM3C1
@@ -146,7 +149,7 @@ static bool pwm_status(uint8_t pin) {
PWM_CASE(4, C);
#endif
- #if defined(TCCR5A) && defined(COM5A1)
+ #if ABTEST(5)
PWM_CASE(5, A);
PWM_CASE(5, B);
PWM_CASE(5, C);
@@ -163,16 +166,16 @@ static bool pwm_status(uint8_t pin) {
const volatile uint8_t* const PWM_other[][3] PROGMEM = {
{ &TCCR0A, &TCCR0B, &TIMSK0 },
{ &TCCR1A, &TCCR1B, &TIMSK1 },
- #if defined(TCCR2A) && defined(COM2A1)
+ #if ABTEST(2)
{ &TCCR2A, &TCCR2B, &TIMSK2 },
#endif
- #if defined(TCCR3A) && defined(COM3A1)
+ #if ABTEST(3)
{ &TCCR3A, &TCCR3B, &TIMSK3 },
#endif
#ifdef TCCR4A
{ &TCCR4A, &TCCR4B, &TIMSK4 },
#endif
- #if defined(TCCR5A) && defined(COM5A1)
+ #if ABTEST(5)
{ &TCCR5A, &TCCR5B, &TIMSK5 },
#endif
};
@@ -192,11 +195,11 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
{ (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, 0 },
#endif
- #if defined(TCCR2A) && defined(COM2A1)
+ #if ABTEST(2)
{ &OCR2A, &OCR2B, 0 },
#endif
- #if defined(TCCR3A) && defined(COM3A1)
+ #if ABTEST(3)
#ifdef COM3C1
{ (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, (const uint8_t*)&OCR3C },
#else
@@ -208,7 +211,7 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
{ (const uint8_t*)&OCR4A, (const uint8_t*)&OCR4B, (const uint8_t*)&OCR4C },
#endif
- #if defined(TCCR5A) && defined(COM5A1)
+ #if ABTEST(5)
{ (const uint8_t*)&OCR5A, (const uint8_t*)&OCR5B, (const uint8_t*)&OCR5C },
#endif
};
@@ -235,9 +238,9 @@ 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(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
+ SERIAL_ECHOPGM(" COM", AS_DIGIT(N));
+ SERIAL_CHAR(Z);
+ SERIAL_ECHOPGM(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
}
void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout
@@ -247,8 +250,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_ECHOPGM(" TIMER", AS_DIGIT(T));
+ SERIAL_CHAR(L);
SERIAL_ECHO_SP(3);
if (N == 3) {
@@ -259,22 +262,14 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A');
PWM_PRINT(*OCRVAL16);
}
- SERIAL_ECHOPAIR(" WGM: ", WGM);
+ SERIAL_ECHOPGM(" 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_ECHOPGM(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
+ SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "A: ", *TCCRA);
+ SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "B: ", *TCCRB);
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
- SERIAL_ECHOPGM(" TIMSK");
- SERIAL_CHAR(T + '0');
- SERIAL_ECHOPAIR(": ", *TMSK);
+ SERIAL_ECHOPGM(" TIMSK", AS_DIGIT(T), ": ", *TMSK);
const uint8_t OCIE = L - 'A' + 1;
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
@@ -286,7 +281,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
static void pwm_details(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
- #if defined(TCCR0A) && defined(COM0A1)
+ #if ABTEST(0)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
case TIMER0A: timer_prefix(0, 'A', 3); break;
@@ -295,7 +290,7 @@ static void pwm_details(uint8_t pin) {
case TIMER0B: timer_prefix(0, 'B', 3); break;
#endif
- #if defined(TCCR1A) && defined(COM1A1)
+ #if ABTEST(1)
case TIMER1A: timer_prefix(1, 'A', 4); break;
case TIMER1B: timer_prefix(1, 'B', 4); break;
#if defined(COM1C1) && defined(TIMER1C)
@@ -303,12 +298,12 @@ static void pwm_details(uint8_t pin) {
#endif
#endif
- #if defined(TCCR2A) && defined(COM2A1)
+ #if ABTEST(2)
case TIMER2A: timer_prefix(2, 'A', 3); break;
case TIMER2B: timer_prefix(2, 'B', 3); break;
#endif
- #if defined(TCCR3A) && defined(COM3A1)
+ #if ABTEST(3)
case TIMER3A: timer_prefix(3, 'A', 4); break;
case TIMER3B: timer_prefix(3, 'B', 4); break;
#ifdef COM3C1
@@ -322,7 +317,7 @@ static void pwm_details(uint8_t pin) {
case TIMER4C: timer_prefix(4, 'C', 4); break;
#endif
- #if defined(TCCR5A) && defined(COM5A1)
+ #if ABTEST(5)
case TIMER5A: timer_prefix(5, 'A', 4); break;
case TIMER5B: timer_prefix(5, 'B', 4); break;
case TIMER5C: timer_prefix(5, 'C', 4); break;
@@ -356,7 +351,6 @@ static void pwm_details(uint8_t pin) {
#endif
} // pwm_details
-
#ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs
int digitalRead_mod(const int8_t pin) { // same as digitalRead except the PWM stop section has been removed
const uint8_t port = digitalPinToPort_DEBUG(pin);
@@ -401,3 +395,6 @@ static void pwm_details(uint8_t pin) {
#endif
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
+
+#undef ABTEST
diff --git a/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h
index 051972a861ad..582ae79ba787 100644
--- a/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h
+++ b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h
@@ -2,6 +2,9 @@
* 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
diff --git a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
index db3fdf1f767b..d9aa44c3cb15 100644
--- a/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
+++ b/Marlin/src/HAL/AVR/pinsDebug_plus_70.h
@@ -2,6 +2,9 @@
* 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
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/timers.h b/Marlin/src/HAL/AVR/timers.h
index 82eb8b14b161..36b04eae0d1f 100644
--- a/Marlin/src/HAL/AVR/timers.h
+++ b/Marlin/src/HAL/AVR/timers.h
@@ -34,14 +34,14 @@ typedef uint16_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 1
+#ifndef MF_TIMER_STEP
+ #define MF_TIMER_STEP 1
#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 0
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP 0
#endif
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
@@ -64,7 +64,7 @@ typedef uint16_t hal_timer_t;
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
switch (timer_num) {
- case STEP_TIMER_NUM:
+ case MF_TIMER_STEP:
// waveform generation = 0100 = CTC
SET_WGM(1, CTC_OCRnA);
@@ -84,7 +84,7 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
TCNT1 = 0;
break;
- case TEMP_TIMER_NUM:
+ case MF_TIMER_TEMP:
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
@@ -109,8 +109,8 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
* (otherwise, characters will be lost due to UART overflow).
* Then: Stepper, Endstops, Temperature, and -finally- all others.
*/
-#define HAL_timer_isr_prologue(TIMER_NUM)
-#define HAL_timer_isr_epilogue(TIMER_NUM)
+#define HAL_timer_isr_prologue(T)
+#define HAL_timer_isr_epilogue(T)
/* 18 cycles maximum latency */
#ifndef HAL_STEP_TIMER_ISR
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..45b54379dba7 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,10 +62,10 @@
#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;
+static uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
+static volatile uint8_t *u8g_outData, *u8g_outClock;
static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) {
u8g_outData = portOutputRegister(digitalPinToPort(dataPin));
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 395ca4ccc971..96ab5d9808ac 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
@@ -129,6 +144,11 @@ inline void HAL_adc_init() {}//todo
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
+//
+// PWM
+//
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
//
// Pin Map
//
@@ -153,16 +173,14 @@ void HAL_init();
//
void _delay_ms(const int delay);
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
#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..c5e8f2433d7d 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,38 +575,34 @@
// 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);
SPI_Enable(SPI0);
- SET_OUTPUT(DAC0_SYNC);
+ SET_OUTPUT(DAC0_SYNC_PIN);
#if HAS_MULTI_EXTRUDER
- SET_OUTPUT(DAC1_SYNC);
- WRITE(DAC1_SYNC, HIGH);
+ OUT_WRITE(DAC1_SYNC_PIN, HIGH);
#endif
- SET_OUTPUT(SPI_EEPROM1_CS);
- SET_OUTPUT(SPI_EEPROM2_CS);
- SET_OUTPUT(SPI_FLASH_CS);
- WRITE(DAC0_SYNC, HIGH);
- WRITE(SPI_EEPROM1_CS, HIGH);
- WRITE(SPI_EEPROM2_CS, HIGH);
- WRITE(SPI_FLASH_CS, HIGH);
- WRITE(SS_PIN, HIGH);
+ WRITE(DAC0_SYNC_PIN, HIGH);
+ OUT_WRITE(SPI_EEPROM1_CS_PIN, HIGH);
+ OUT_WRITE(SPI_EEPROM2_CS_PIN, HIGH);
+ OUT_WRITE(SPI_FLASH_CS_PIN, HIGH);
+ WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, LOW);
@@ -645,7 +641,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 +664,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 +685,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 +698,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 +797,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/MarlinSPI.h b/Marlin/src/HAL/DUE/MarlinSPI.h
new file mode 100644
index 000000000000..0c447ba4cb3d
--- /dev/null
+++ b/Marlin/src/HAL/DUE/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * 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
+
+using MarlinSPI = SPIClass;
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..5a61bffee0da 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,44 +115,15 @@ 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; }
+ static 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 = 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..8de2dc7924a0 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();
@@ -45,15 +41,11 @@ extern "C" {
int udi_cdc_getc();
bool udi_cdc_is_tx_ready();
int udi_cdc_putc(int value);
-};
+}
// 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/Tone.cpp b/Marlin/src/HAL/DUE/Tone.cpp
index 9beb6022237f..1ac81faaf0e1 100644
--- a/Marlin/src/HAL/DUE/Tone.cpp
+++ b/Marlin/src/HAL/DUE/Tone.cpp
@@ -38,17 +38,17 @@ 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);
+ HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
}
void noTone(const pin_t _pin) {
- HAL_timer_disable_interrupt(TONE_TIMER_NUM);
+ HAL_timer_disable_interrupt(MF_TIMER_TONE);
extDigitalWrite(_pin, LOW);
}
HAL_TONE_TIMER_ISR() {
static uint8_t pin_state = 0;
- HAL_timer_isr_prologue(TONE_TIMER_NUM);
+ HAL_timer_isr_prologue(MF_TIMER_TONE);
if (toggles) {
toggles--;
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..68f6a5c1a7cb 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
@@ -20,7 +20,6 @@
*
*/
-
/**
* Based on u8g_com_msp430_hw_spi.c
*
@@ -60,16 +59,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 +98,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 7df180cbaa82..8268cf307e08 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
@@ -57,11 +57,12 @@
#include "../../../inc/MarlinConfigPre.h"
-#if ENABLED(U8GLIB_ST7920)
+#if IS_U8GLIB_ST7920
+#include "../../../inc/MarlinConfig.h"
#include "../../shared/Delay.h"
-#include
+#include
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
@@ -181,5 +182,5 @@ uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
}
#endif // LIGHTWEIGHT_UI
-#endif // U8GLIB_ST7920
+#endif // IS_U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM
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..68e3e74a45a0 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
@@ -57,17 +57,14 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
-
-#undef SPI_SPEED
-#define SPI_SPEED 2 // About 2 MHz
+#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#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
@@ -144,5 +141,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
-#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM
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 209a5161ae02..7ce4a84df531 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));
@@ -200,9 +200,9 @@ static bool ee_PageWrite(uint16_t page, const void* data) {
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM PageWrite ", page);
- DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
- DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
+ DEBUG_ECHOLNPGM("EEPROM PageWrite ", page);
+ DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
+ DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
// Get the page relative to the start of the EFC controller, and the EFC controller to use
@@ -246,7 +246,7 @@ static bool ee_PageWrite(uint16_t page, const void* data) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
+ DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ", page);
return false;
}
@@ -271,7 +271,7 @@ static bool ee_PageWrite(uint16_t page, const void* data) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Write failure for page ", page);
+ DEBUG_ECHOLNPGM("EEPROM Write failure for page ", page);
return false;
}
@@ -287,14 +287,14 @@ static bool ee_PageWrite(uint16_t page, const void* data) {
#ifdef EE_EMU_DEBUG
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
+ DEBUG_ECHOLNPGM("EEPROM Verify Write failure for page ", page);
ee_Dump( page, (uint32_t *)addrflash);
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]) {
@@ -306,7 +306,7 @@ static bool ee_PageWrite(uint16_t page, const void* data) {
}
}
}
- DEBUG_ECHOLNPAIR("--> Differing bits: ", count);
+ DEBUG_ECHOLNPGM("--> Differing bits: ", count);
#endif
return false;
@@ -326,9 +326,9 @@ static bool ee_PageErase(uint16_t page) {
uint32_t addrflash = uint32_t(getFlashStorage(page));
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM PageErase ", page);
- DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
- DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
+ DEBUG_ECHOLNPGM("EEPROM PageErase ", page);
+ DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
+ DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
// Get the page relative to the start of the EFC controller, and the EFC controller to use
@@ -371,7 +371,7 @@ static bool ee_PageErase(uint16_t page) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
+ DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ",page);
return false;
}
@@ -395,7 +395,7 @@ static bool ee_PageErase(uint16_t page) {
__enable_irq();
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Erase failure for page ",page);
+ DEBUG_ECHOLNPGM("EEPROM Erase failure for page ",page);
return false;
}
@@ -411,7 +411,7 @@ static bool ee_PageErase(uint16_t page) {
for (i = 0; i < PageSize >> 2; i++) {
if (*aligned_src++ != 0xFFFFFFFF) {
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
+ DEBUG_ECHOLNPGM("EEPROM Verify Erase failure for page ",page);
ee_Dump(page, (uint32_t *)addrflash);
return false;
}
@@ -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;
@@ -922,7 +922,7 @@ static void ee_Init() {
if (curGroup >= GroupCount) curGroup = 0;
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
+ DEBUG_ECHOLNPGM("EEPROM Current Group: ",curGroup);
DEBUG_FLUSH();
// Now, validate that all the other group pages are empty
@@ -932,7 +932,7 @@ static void ee_Init() {
for (int page = 0; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
+ DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on group ", grp);
DEBUG_FLUSH();
ee_PageErase(grp * PagesPerGroup + page);
}
@@ -949,14 +949,14 @@ static void ee_Init() {
}
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Active page: ", curPage);
+ DEBUG_ECHOLNPGM("EEPROM Active page: ", curPage);
DEBUG_FLUSH();
// Make sure the pages following the first clean one are also clean
for (int page = curPage + 1; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
DEBUG_ECHO_START();
- DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
+ DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on active group ", curGroup);
DEBUG_FLUSH();
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
ee_PageErase(curGroup * PagesPerGroup + page);
@@ -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;
diff --git a/Marlin/src/HAL/DUE/eeprom_wired.cpp b/Marlin/src/HAL/DUE/eeprom_wired.cpp
index b488c36f1666..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;
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 5fb8b4d01533..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
/**
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/pinsDebug.h b/Marlin/src/HAL/DUE/pinsDebug.h
index a99ca8ecce90..f01c53c8ce06 100644
--- a/Marlin/src/HAL/DUE/pinsDebug.h
+++ b/Marlin/src/HAL/DUE/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -64,6 +67,7 @@
#define PRINT_PORT(p)
#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("%02d"), p); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0)
@@ -86,7 +90,7 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
uint32_t chan = g_APinDescription[pin].ulPWMChannel;
- SERIAL_ECHOPAIR("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
+ SERIAL_ECHOPGM("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
}
}
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..a7bf7fbd6d85 100644
--- a/Marlin/src/HAL/DUE/timers.cpp
+++ b/Marlin/src/HAL/DUE/timers.cpp
@@ -42,7 +42,7 @@
// Private Variables
// ------------------------
-const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
+const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
{ TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5]
{ TC0, 1, TC1_IRQn, 0}, // 1
{ TC0, 2, TC2_IRQn, 2}, // 2 - stepper
@@ -66,9 +66,9 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
*/
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
- Tc *tc = TimerConfig[timer_num].pTimerRegs;
- IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
- uint32_t channel = TimerConfig[timer_num].channel;
+ Tc *tc = timer_config[timer_num].pTimerRegs;
+ IRQn_Type irq = timer_config[timer_num].IRQ_Id;
+ uint32_t channel = timer_config[timer_num].channel;
// Disable interrupt, just in case it was already enabled
NVIC_DisableIRQ(irq);
@@ -86,7 +86,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
- NVIC_SetPriority(irq, TimerConfig [timer_num].priority);
+ NVIC_SetPriority(irq, timer_config[timer_num].priority);
// wave mode, reset counter on match with RC,
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
@@ -105,12 +105,12 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
- IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ IRQn_Type irq = timer_config[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
- IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ IRQn_Type irq = timer_config[timer_num].IRQ_Id;
NVIC_DisableIRQ(irq);
// We NEED memory barriers to ensure Interrupts are actually disabled!
@@ -121,11 +121,11 @@ 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) {
- IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ IRQn_Type irq = timer_config[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}
diff --git a/Marlin/src/HAL/DUE/timers.h b/Marlin/src/HAL/DUE/timers.h
index 0e1ea07cc2e4..e2932ff36f91 100644
--- a/Marlin/src/HAL/DUE/timers.h
+++ b/Marlin/src/HAL/DUE/timers.h
@@ -37,35 +37,35 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 2 // Timer Index for Stepper
+#ifndef MF_TIMER_STEP
+ #define MF_TIMER_STEP 2 // Timer Index for Stepper
#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 4 // Timer Index for Temperature
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP 4 // Timer Index for Temperature
#endif
-#ifndef TONE_TIMER_NUM
- #define TONE_TIMER_NUM 6 // index of timer to use for beeper tones
+#ifndef MF_TIMER_TONE
+ #define MF_TIMER_TONE 6 // index of timer to use for beeper tones
#endif
#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 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 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_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
@@ -92,7 +92,7 @@ typedef struct {
// Public Variables
// ------------------------
-extern const tTimerConfig TimerConfig[];
+extern const tTimerConfig timer_config[];
// ------------------------
// Public functions
@@ -101,17 +101,17 @@ extern const tTimerConfig TimerConfig[];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
- const tTimerConfig * const pConfig = &TimerConfig[timer_num];
+ const tTimerConfig * const pConfig = &timer_config[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
- const tTimerConfig * const pConfig = &TimerConfig[timer_num];
+ const tTimerConfig * const pConfig = &timer_config[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
- const tTimerConfig * const pConfig = &TimerConfig[timer_num];
+ const tTimerConfig * const pConfig = &timer_config[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV;
}
@@ -120,9 +120,9 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
- const tTimerConfig * const pConfig = &TimerConfig[timer_num];
+ const tTimerConfig * const pConfig = &timer_config[timer_num];
// Reading the status register clears the interrupt flag
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
}
-#define HAL_timer_isr_epilogue(TIMER_NUM)
+#define HAL_timer_isr_epilogue(T)
diff --git a/Marlin/src/HAL/DUE/upload_extra_script.py b/Marlin/src/HAL/DUE/upload_extra_script.py
index d52a0a3642b4..4f7a494512b2 100644
--- a/Marlin/src/HAL/DUE/upload_extra_script.py
+++ b/Marlin/src/HAL/DUE/upload_extra_script.py
@@ -4,15 +4,16 @@
# Windows: bossac.exe
# Other: leave unchanged
#
+import pioutil
+if pioutil.is_pio_build():
+ import platform
+ current_OS = platform.system()
-import platform
-current_OS = platform.system()
+ if current_OS == 'Windows':
-if current_OS == 'Windows':
+ Import("env")
- Import("env")
-
- # Use bossac.exe on Windows
- env.Replace(
- UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
- )
+ # Use bossac.exe on Windows
+ env.Replace(
+ UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
+ )
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 db5e82ec5502..34cc256b30ff 100644
--- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
+++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp
@@ -10,7 +10,7 @@
#include "../../../sd/cardreader.h"
extern "C" {
-#include "sd_mmc_spi_mem.h"
+ #include "sd_mmc_spi_mem.h"
}
#define SD_MMC_BLOCK_SIZE 512
@@ -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, nullptr)) {
- card.getSd2Card().readStop();
+ card.diskIODriver()->readStop();
return CTRL_FAIL;
}
}
// Stop reading
- card.getSd2Card().readStop();
+ card.diskIODriver()->readStop();
// Done
return CTRL_GOOD;
@@ -108,12 +108,12 @@ 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
@@ -121,16 +121,16 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
// USB -> RAM
if (!udi_msc_trans_block(false, sector_buf, SD_MMC_BLOCK_SIZE, nullptr)) {
- card.getSd2Card().writeStop();
+ 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/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 ead448d78d7a..810e386894ec 100644
--- a/Marlin/src/HAL/ESP32/HAL.cpp
+++ b/Marlin/src/HAL/ESP32/HAL.cpp
@@ -28,6 +28,10 @@
#include
#include
+#if ENABLED(USE_ESP32_TASK_WDT)
+ #include
+#endif
+
#if ENABLED(WIFISUPPORT)
#include
#include "wifi.h"
@@ -40,6 +44,10 @@
#endif
#endif
+#if ENABLED(ESP3D_WIFISUPPORT)
+ DefaultSerial1 MSerial0(false, Serial2Socket);
+#endif
+
// ------------------------
// Externs
// ------------------------
@@ -86,10 +94,24 @@ volatile int numPWMUsed = 0,
#endif
-void HAL_init() { TERN_(I2S_STEPPER_STREAM, i2s_init()); }
+#if ENABLED(USE_ESP32_EXIO)
+ HardwareSerial YSerial2(2);
-void HAL_init_board() {
+ void Write_EXIO(uint8_t IO, uint8_t v) {
+ if (ISRS_ENABLED()) {
+ DISABLE_ISRS();
+ YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
+ ENABLE_ISRS();
+ }
+ else
+ YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
+ }
+#endif
+void HAL_init_board() {
+ #if ENABLED(USE_ESP32_TASK_WDT)
+ esp_task_wdt_init(10, true);
+ #endif
#if ENABLED(ESP3D_WIFISUPPORT)
esp3dlib.init();
#elif ENABLED(WIFISUPPORT)
@@ -122,6 +144,14 @@ 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.
+ #if ENABLED(USE_ESP32_EXIO)
+ YSerial2.begin(460800 * 3, SERIAL_8N1, 16, 17);
+ #elif ENABLED(I2S_STEPPER_STREAM)
+ i2s_init();
+ #endif
}
void HAL_idletask() {
@@ -135,6 +165,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 +211,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.
@@ -243,7 +276,7 @@ void analogWrite(pin_t pin, int value) {
idx = numPWMUsed;
pwmPins[idx] = pin;
// Start timer on first use
- if (idx == 0) HAL_timer_start(PWM_TIMER_NUM, PWM_TIMER_FREQUENCY);
+ if (idx == 0) HAL_timer_start(MF_TIMER_PWM, PWM_TIMER_FREQUENCY);
++numPWMUsed;
}
@@ -254,7 +287,7 @@ void analogWrite(pin_t pin, int value) {
// Handle PWM timer interrupt
HAL_PWM_TIMER_ISR() {
- HAL_timer_isr_prologue(PWM_TIMER_NUM);
+ HAL_timer_isr_prologue(MF_TIMER_PWM);
static uint8_t count = 0;
@@ -268,7 +301,7 @@ HAL_PWM_TIMER_ISR() {
// 128 for 7 Bit resolution
count = (count + 1) & 0x7F;
- HAL_timer_isr_epilogue(PWM_TIMER_NUM);
+ HAL_timer_isr_epilogue(MF_TIMER_PWM);
}
#endif // ARDUINO_ARCH_ESP32
diff --git a/Marlin/src/HAL/ESP32/HAL.h b/Marlin/src/HAL/ESP32/HAL.h
index 5ef13e0c21d4..8473e3c4e469 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,26 +88,31 @@ 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
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
void analogWrite(pin_t pin, int value);
@@ -126,6 +129,10 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
+// PWM
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
+// Pin Map
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
@@ -134,9 +141,13 @@ 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();
+#if ENABLED(USE_ESP32_EXIO)
+ void Write_EXIO(uint8_t IO, uint8_t v);
+#endif
+
//
// Delay in cycles (used by DELAY_NS / DELAY_US)
//
diff --git a/Marlin/src/HAL/ESP32/HAL_SPI.cpp b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
index 8e5875fc388d..868ab1b6712d 100644
--- a/Marlin/src/HAL/ESP32/HAL_SPI.cpp
+++ b/Marlin/src/HAL/ESP32/HAL_SPI.cpp
@@ -53,11 +53,9 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
- #if !PIN_EXISTS(SS)
- #error "SS_PIN not defined!"
+ #if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
#endif
-
- OUT_WRITE(SS_PIN, HIGH);
}
void spiInit(uint8_t spiRate) {
@@ -85,7 +83,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 +95,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/MarlinSPI.h b/Marlin/src/HAL/ESP32/MarlinSPI.h
new file mode 100644
index 000000000000..0c447ba4cb3d
--- /dev/null
+++ b/Marlin/src/HAL/ESP32/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * 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
+
+using MarlinSPI = SPIClass;
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..9c16cdde800a
--- /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(MF_TIMER_TONE, 2 * frequency);
+}
+
+void noTone(const pin_t _pin) {
+ HAL_timer_disable_interrupt(MF_TIMER_TONE);
+ WRITE(_pin, LOW);
+}
+
+HAL_TONE_TIMER_ISR() {
+ HAL_timer_isr_prologue(MF_TIMER_TONE);
+
+ 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/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/esp32.csv b/Marlin/src/HAL/ESP32/esp32.csv
new file mode 100644
index 000000000000..8f6e101f02ea
--- /dev/null
+++ b/Marlin/src/HAL/ESP32/esp32.csv
@@ -0,0 +1,6 @@
+# Name, Type, SubType, Offset, Size, Flags
+nvs, data, nvs, 0x9000, 0x5000,
+otadata, data, ota, 0xe000, 0x2000,
+app0, app, ota_0, 0x10000, 0x180000,
+app1, app, ota_1, 0x190000, 0x180000,
+spiffs, data, spiffs, 0x310000, 0xF0000,
diff --git a/Marlin/src/HAL/ESP32/fastio.h b/Marlin/src/HAL/ESP32/fastio.h
index 8db89dca12a1..c8e3f7e343e9 100644
--- a/Marlin/src/HAL/ESP32/fastio.h
+++ b/Marlin/src/HAL/ESP32/fastio.h
@@ -40,13 +40,19 @@
// Set pin as input with pullup mode
#define _PULLUP(IO, v) pinMode(IO, v ? INPUT_PULLUP : INPUT)
-// Read a pin wrapper
-#define READ(IO) (IS_I2S_EXPANDER_PIN(IO) ? i2s_state(I2S_EXPANDER_PIN_INDEX(IO)) : digitalRead(IO))
-
-// Write to a pin wrapper
-#define WRITE(IO, v) (IS_I2S_EXPANDER_PIN(IO) ? i2s_write(I2S_EXPANDER_PIN_INDEX(IO), v) : digitalWrite(IO, v))
-
-// Set pin as input wrapper
+#if ENABLED(USE_ESP32_EXIO)
+ // Read a pin wrapper
+ #define READ(IO) digitalRead(IO)
+ // Write to a pin wrapper
+ #define WRITE(IO, v) (IO >= 100 ? Write_EXIO(IO, v) : digitalWrite(IO, v))
+#else
+ // Read a pin wrapper
+ #define READ(IO) (IS_I2S_EXPANDER_PIN(IO) ? i2s_state(I2S_EXPANDER_PIN_INDEX(IO)) : digitalRead(IO))
+ // Write to a pin wrapper
+ #define WRITE(IO, v) (IS_I2S_EXPANDER_PIN(IO) ? i2s_write(I2S_EXPANDER_PIN_INDEX(IO), v) : digitalWrite(IO, v))
+#endif
+
+// Set pin as input wrapper (0x80 | (v << 5) | (IO - 100))
#define SET_INPUT(IO) _SET_INPUT(IO)
// Set pin as input with pullup wrapper
diff --git a/Marlin/src/HAL/ESP32/i2s.cpp b/Marlin/src/HAL/ESP32/i2s.cpp
index e8f380654314..3e77b658360b 100644
--- a/Marlin/src/HAL/ESP32/i2s.cpp
+++ b/Marlin/src/HAL/ESP32/i2s.cpp
@@ -23,6 +23,8 @@
#include "../../inc/MarlinConfigPre.h"
+#if DISABLED(USE_ESP32_EXIO)
+
#include "i2s.h"
#include "../shared/Marduino.h"
@@ -62,12 +64,9 @@ uint32_t i2s_port_data = 0;
#define I2S_EXIT_CRITICAL() portEXIT_CRITICAL(&i2s_spinlock[i2s_num])
static inline void gpio_matrix_out_check(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv) {
- //if pin = -1, do not need to configure
- if (gpio != -1) {
- PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
- gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
- gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv);
- }
+ PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio], PIN_FUNC_GPIO);
+ gpio_set_direction((gpio_num_t)gpio, (gpio_mode_t)GPIO_MODE_DEF_OUTPUT);
+ gpio_matrix_out(gpio, signal_idx, out_inv, oen_inv);
}
static esp_err_t i2s_reset_fifo(i2s_port_t i2s_num) {
@@ -139,7 +138,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) {
@@ -254,13 +253,7 @@ int i2s_init() {
I2S0.fifo_conf.dscr_en = 0;
- I2S0.conf_chan.tx_chan_mod = (
- #if ENABLED(I2S_STEPPER_SPLIT_STREAM)
- 4
- #else
- 0
- #endif
- );
+ I2S0.conf_chan.tx_chan_mod = TERN(I2S_STEPPER_SPLIT_STREAM, 4, 0);
I2S0.fifo_conf.tx_fifo_mod = 0;
I2S0.conf.tx_mono = 0;
@@ -311,9 +304,16 @@ int i2s_init() {
xTaskCreatePinnedToCore(stepperTask, "StepperTask", 10000, nullptr, 1, nullptr, CONFIG_ARDUINO_RUNNING_CORE); // run I2S stepper task on same core as rest of Marlin
// Route the i2s pins to the appropriate GPIO
- gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0);
- gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0);
- gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0);
+ // If a pin is not defined, no need to configure
+ #if defined(I2S_DATA) && I2S_DATA >= 0
+ gpio_matrix_out_check(I2S_DATA, I2S0O_DATA_OUT23_IDX, 0, 0);
+ #endif
+ #if defined(I2S_BCK) && I2S_BCK >= 0
+ gpio_matrix_out_check(I2S_BCK, I2S0O_BCK_OUT_IDX, 0, 0);
+ #endif
+ #if defined(I2S_WS) && I2S_WS >= 0
+ gpio_matrix_out_check(I2S_WS, I2S0O_WS_OUT_IDX, 0, 0);
+ #endif
// Start the I2S peripheral
return i2s_start(I2S_NUM_0);
@@ -340,4 +340,5 @@ void i2s_push_sample() {
dma.current[dma.rw_pos++] = i2s_port_data;
}
+#endif // !USE_ESP32_EXIO
#endif // ARDUINO_ARCH_ESP32
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..58881f0ea7ec 100644
--- a/Marlin/src/HAL/ESP32/spi_pins.h
+++ b/Marlin/src/HAL/ESP32/spi_pins.h
@@ -2,6 +2,9 @@
* 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
@@ -18,7 +21,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..df0065f45396 100644
--- a/Marlin/src/HAL/ESP32/timers.cpp
+++ b/Marlin/src/HAL/ESP32/timers.cpp
@@ -41,11 +41,11 @@
static timg_dev_t *TG[2] = {&TIMERG0, &TIMERG1};
-const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
+const tTimerConfig timer_config[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
};
// ------------------------
@@ -53,7 +53,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
// ------------------------
void IRAM_ATTR timer_isr(void *para) {
- const tTimerConfig& timer = TimerConfig[(int)para];
+ const tTimerConfig& timer = timer_config[(int)para];
// Retrieve the interrupt status and the counter value
// from the timer that reported the interrupt
@@ -82,7 +82,7 @@ void IRAM_ATTR timer_isr(void *para) {
* @param frequency frequency of the timer
*/
void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
- const tTimerConfig timer = TimerConfig[timer_num];
+ const tTimerConfig timer = timer_config[timer_num];
timer_config_t config;
config.divider = timer.divider;
@@ -115,7 +115,7 @@ void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
* @param count threshold at which the interrupt is triggered
*/
void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) {
- const tTimerConfig timer = TimerConfig[timer_num];
+ const tTimerConfig timer = timer_config[timer_num];
timer_set_alarm_value(timer.group, timer.idx, count);
}
@@ -125,7 +125,7 @@ void HAL_timer_set_compare(const uint8_t timer_num, hal_timer_t count) {
* @return the timer current threshold for the alarm to be triggered
*/
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
- const tTimerConfig timer = TimerConfig[timer_num];
+ const tTimerConfig timer = timer_config[timer_num];
uint64_t alarm_value;
timer_get_alarm_value(timer.group, timer.idx, &alarm_value);
@@ -139,7 +139,7 @@ hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
* @return the current counter of the alarm
*/
hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
- const tTimerConfig timer = TimerConfig[timer_num];
+ const tTimerConfig timer = timer_config[timer_num];
uint64_t counter_value;
timer_get_counter_value(timer.group, timer.idx, &counter_value);
return counter_value;
@@ -150,7 +150,7 @@ hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
* @param timer_num timer number to enable interrupts on
*/
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
- //const tTimerConfig timer = TimerConfig[timer_num];
+ //const tTimerConfig timer = timer_config[timer_num];
//timer_enable_intr(timer.group, timer.idx);
}
@@ -159,12 +159,12 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num) {
* @param timer_num timer number to disable interrupts on
*/
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
- //const tTimerConfig timer = TimerConfig[timer_num];
+ //const tTimerConfig timer = timer_config[timer_num];
//timer_disable_intr(timer.group, timer.idx);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
- const tTimerConfig timer = TimerConfig[timer_num];
+ const tTimerConfig timer = timer_config[timer_num];
return TG[timer.group]->int_ena.val | BIT(timer_num);
}
diff --git a/Marlin/src/HAL/ESP32/timers.h b/Marlin/src/HAL/ESP32/timers.h
index 98386e3980b9..266169848daf 100644
--- a/Marlin/src/HAL/ESP32/timers.h
+++ b/Marlin/src/HAL/ESP32/timers.h
@@ -32,17 +32,20 @@
typedef uint64_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFFFFFFFFFFULL
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 0 // Timer Index for Stepper
+#ifndef MF_TIMER_STEP
+ #define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
-#ifndef PWM_TIMER_NUM
- #define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs
+#ifndef MF_TIMER_PWM
+ #define MF_TIMER_PWM 2 // index of timer to use for PWM outputs
+#endif
+#ifndef MF_TIMER_TONE
+ #define MF_TIMER_TONE 3 // index of timer for beeper tones
#endif
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
@@ -59,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
@@ -74,12 +79,12 @@ typedef uint64_t hal_timer_t;
#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_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_TEMP_TIMER_ISR
#define HAL_TEMP_TIMER_ISR() extern "C" void tempTC_Handler()
@@ -90,11 +95,15 @@ 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();
void stepTC_Handler();
void pwmTC_Handler();
+ void toneTC_Handler();
}
// ------------------------
@@ -112,7 +121,7 @@ typedef struct {
// Public Variables
// ------------------------
-extern const tTimerConfig TimerConfig[];
+extern const tTimerConfig timer_config[];
// ------------------------
// Public functions
@@ -127,5 +136,5 @@ 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)
+#define HAL_timer_isr_prologue(T)
+#define HAL_timer_isr_epilogue(T)
diff --git a/Marlin/src/HAL/ESP32/watchdog.h b/Marlin/src/HAL/ESP32/watchdog.h
index b6c169e34742..43db8130763f 100644
--- a/Marlin/src/HAL/ESP32/watchdog.h
+++ b/Marlin/src/HAL/ESP32/watchdog.h
@@ -25,7 +25,7 @@
extern "C" {
#endif
- esp_err_t esp_task_wdt_reset();
+ esp_err_t esp_task_wdt_reset();
#ifdef __cplusplus
}
diff --git a/Marlin/src/HAL/ESP32/wifi.cpp b/Marlin/src/HAL/ESP32/wifi.cpp
index f4cf5a606a03..060f3bdb4874 100644
--- a/Marlin/src/HAL/ESP32/wifi.cpp
+++ b/Marlin/src/HAL/ESP32/wifi.cpp
@@ -59,7 +59,7 @@ void wifi_init() {
MDNS.addService("http", "tcp", 80);
- SERIAL_ECHOLNPAIR("Successfully connected to WiFi with SSID '" WIFI_SSID "', hostname: '" WIFI_HOSTNAME "', IP address: ", WiFi.localIP().toString().c_str());
+ SERIAL_ECHOLNPGM("Successfully connected to WiFi with SSID '" WIFI_SSID "', hostname: '" WIFI_HOSTNAME "', IP address: ", WiFi.localIP().toString().c_str());
}
#endif // WIFISUPPORT
diff --git a/Marlin/src/HAL/HAL.h b/Marlin/src/HAL/HAL.h
index 9eefda8fb1e2..0cd836af2b68 100644
--- a/Marlin/src/HAL/HAL.h
+++ b/Marlin/src/HAL/HAL.h
@@ -29,12 +29,6 @@
#include HAL_PATH(.,HAL.h)
-#ifdef SERIAL_PORT_2
- #define NUM_SERIAL 2
-#else
- #define NUM_SERIAL 1
-#endif
-
#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 ee9e31e140e8..0b679170ef17 100644
--- a/Marlin/src/HAL/LINUX/HAL.cpp
+++ b/Marlin/src/HAL/LINUX/HAL.cpp
@@ -24,7 +24,7 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
-HalSerial usb_serial;
+MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true));
// U8glib required functions
extern "C" {
@@ -73,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 729f6c856e19..d7d3a92b73b9 100644
--- a/Marlin/src/HAL/LINUX/HAL.h
+++ b/Marlin/src/HAL/LINUX/HAL.h
@@ -60,12 +60,12 @@ 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)
-#define ST7920_DELAY_3 DELAY_NS(750)
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
//
// Interrupts
@@ -79,16 +79,14 @@ extern HalSerial usb_serial;
inline void HAL_init() {}
// Utility functions
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
// ADC
#define HAL_ADC_VREF 5.0
@@ -103,18 +101,16 @@ void HAL_adc_enable_channel(const uint8_t ch);
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
+// PWM
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
// Reset source
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/MarlinSPI.h b/Marlin/src/HAL/LINUX/MarlinSPI.h
new file mode 100644
index 000000000000..0c447ba4cb3d
--- /dev/null
+++ b/Marlin/src/HAL/LINUX/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * 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
+
+using MarlinSPI = SPIClass;
diff --git a/Marlin/src/HAL/LINUX/hardware/Gpio.h b/Marlin/src/HAL/LINUX/hardware/Gpio.h
index 2d9b1f29ebad..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;
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..36d3190a3e08 100644
--- a/Marlin/src/HAL/LINUX/inc/SanityCheck.h
+++ b/Marlin/src/HAL/LINUX/inc/SanityCheck.h
@@ -26,7 +26,7 @@
*/
// Emulating RAMPS
-#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
#error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
#endif
@@ -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 6aeb0db58335..d4086e259a2f 100644
--- a/Marlin/src/HAL/LINUX/include/Arduino.h
+++ b/Marlin/src/HAL/LINUX/include/Arduino.h
@@ -73,27 +73,6 @@ 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 _delay_ms(const int delay);
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 eadc409324c9..f2af2ff33f52 100644
--- a/Marlin/src/HAL/LINUX/main.cpp
+++ b/Marlin/src/HAL/LINUX/main.cpp
@@ -1,8 +1,10 @@
/**
* 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
@@ -17,6 +19,7 @@
* along with this program. If not, see .
*
*/
+
#ifdef __PLAT_LINUX__
//#define GPIO_LOGGING // Full GPIO and Positional Logging
@@ -106,8 +109,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 8f8543ef5984..7bfd97d024f7 100644
--- a/Marlin/src/HAL/LINUX/pinsDebug.h
+++ b/Marlin/src/HAL/LINUX/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -34,6 +37,7 @@
#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 PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); 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
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/timers.h b/Marlin/src/HAL/LINUX/timers.h
index 1beaea95abc6..a98ceb6f391d 100644
--- a/Marlin/src/HAL/LINUX/timers.h
+++ b/Marlin/src/HAL/LINUX/timers.h
@@ -37,14 +37,14 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 0 // Timer Index for Stepper
+#ifndef MF_TIMER_STEP
+ #define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
#define TEMP_TIMER_RATE 1000000
@@ -58,12 +58,12 @@ typedef uint32_t hal_timer_t;
#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_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() extern "C" void TIMER0_IRQHandler()
@@ -77,7 +77,6 @@ typedef uint32_t hal_timer_t;
#define HAL_PWM_TIMER_ISR() extern "C" void TIMER3_IRQHandler()
#define HAL_PWM_TIMER_IRQn
-
void HAL_timer_init();
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
@@ -93,5 +92,5 @@ 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)
+#define HAL_timer_isr_prologue(T)
+#define HAL_timer_isr_epilogue(T)
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 3614e953851c..cee9cfc5f744 100644
--- a/Marlin/src/HAL/LPC1768/HAL.cpp
+++ b/Marlin/src/HAL/LPC1768/HAL.cpp
@@ -29,6 +29,8 @@
#include "watchdog.h"
#endif
+DefaultSerial1 USBSerial(false, UsbSerial);
+
uint32_t HAL_adc_reading = 0;
// U8glib required functions
@@ -61,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());
@@ -74,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 9a1852d94d38..348ea6b21a04 100644
--- a/Marlin/src/HAL/LPC1768/HAL.h
+++ b/Marlin/src/HAL/LPC1768/HAL.h
@@ -47,51 +47,67 @@ 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
//
-#ifndef ST7920_DELAY_1
- #define ST7920_DELAY_1 DELAY_NS(600)
-#endif
-#ifndef ST7920_DELAY_2
- #define ST7920_DELAY_2 DELAY_NS(750)
-#endif
-#ifndef ST7920_DELAY_3
- #define ST7920_DELAY_3 DELAY_NS(750)
-#endif
+#define CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 750
+
+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 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 "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 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() LCD_SERIAL.available()
#endif
#endif
@@ -107,16 +123,14 @@ extern "C" volatile uint32_t _millis;
//
// Utility functions
//
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
//
// ADC API
@@ -140,17 +154,17 @@ int freeMemory();
using FilteredADC = LPC176x::ADC;
extern uint32_t HAL_adc_reading;
-[[gnu::always_inline]] inline void HAL_start_adc(const pin_t pin) {
+[[gnu::always_inline]] inline void HAL_adc_start_conversion(const pin_t pin) {
HAL_adc_reading = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
}
-[[gnu::always_inline]] inline uint16_t HAL_read_adc() {
+[[gnu::always_inline]] inline uint16_t HAL_adc_get_result() {
return HAL_adc_reading;
}
#define HAL_adc_init()
#define HAL_ANALOG_SELECT(pin) FilteredADC::enable_channel(pin)
-#define HAL_START_ADC(pin) HAL_start_adc(pin)
-#define HAL_READ_ADC() HAL_read_adc()
+#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
+#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() (true)
// Test whether the pin is valid
@@ -176,7 +190,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();
@@ -206,17 +220,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
-
-#ifndef strcat_P
- #define strcat_P(a, b) strcat((a), (b))
-#endif
-
-#ifndef strcpy_P
- #define strcpy_P(a, b) strcpy((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 16ac789fc0f3..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,13 +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, 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); }
@@ -144,16 +150,15 @@
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
@@ -392,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/MarlinSerial.cpp b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
index baad3f8f26b7..f2aecf54a050 100644
--- a/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
+++ b/Marlin/src/HAL/LPC1768/MarlinSerial.cpp
@@ -21,24 +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(); }
+#include "../../inc/MarlinConfig.h"
+
+#if USING_HW_SERIAL0
+ MarlinSerial _MSerial0(LPC_UART0);
+ MSerialT MSerial0(true, _MSerial0);
+ extern "C" void UART0_IRQHandler() { _MSerial0.IRQHandler(); }
+#endif
+#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_SERIAL_1
- MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1);
- extern "C" void UART1_IRQHandler() { MSerial1.IRQHandler(); }
+#if USING_HW_SERIAL2
+ MarlinSerial _MSerial2(LPC_UART2);
+ MSerialT MSerial2(true, _MSerial2);
+ extern "C" void UART2_IRQHandler() { _MSerial2.IRQHandler(); }
#endif
-#if USING_SERIAL_2
- MarlinSerial MSerial2(LPC_UART2);
- extern "C" void UART2_IRQHandler() { MSerial2.IRQHandler(); }
+#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..3e6848a1e3d0 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,28 @@
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
- }
+ uint8_t availableForWrite(void) { /* flushTX(); */ return TX_BUFFER_SIZE; }
- EmergencyParser::State emergency_state;
- static inline bool emergency_parser_enabled() { return true; }
+ #if ENABLED(EMERGENCY_PARSER)
+ 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 3c0c3c8ec30e..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.
diff --git a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
index 54a64ccd72f1..1991d7971959 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_sdcard.cpp
@@ -1,10 +1,9 @@
/**
* Marlin 3D Printer Firmware
- *
* Copyright (c) 2020 MarlinFirmware [/~https://github.com/MarlinFirmware/Marlin]
- * Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
- * Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
- * Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
+ *
+ * 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
@@ -20,12 +19,19 @@
* along with this program. If not, see .
*
*/
+
+/**
+ * Implementation of EEPROM settings in SD Card
+ */
+
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDCARD_EEPROM_EMULATION)
+//#define DEBUG_SD_EEPROM_EMULATION
+
#include "../shared/eeprom_api.h"
#include
@@ -38,9 +44,11 @@ FATFS fat_fs;
FIL eeprom_file;
bool eeprom_file_open = false;
+#define EEPROM_FILENAME "eeprom.dat"
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE size_t(0x1000) // 4KiB of Emulated EEPROM
#endif
+
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
bool PersistentStore::access_start() {
@@ -50,7 +58,7 @@ bool PersistentStore::access_start() {
MSC_Release_Lock();
return false;
}
- FRESULT res = f_open(&eeprom_file, "eeprom.dat", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
+ FRESULT res = f_open(&eeprom_file, EEPROM_FILENAME, FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
if (res) MSC_Release_Lock();
if (res == FR_OK) {
@@ -81,19 +89,20 @@ bool PersistentStore::access_finish() {
// This extra chit-chat goes away soon, but is helpful for now
// to see errors that are happening in read_data / write_data
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), ", ...)");
- 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);
- }
- else
- SERIAL_ECHOLNPAIR(" f_lseek()=", int(s));
+ #if ENABLED(DEBUG_SD_EEPROM_EMULATION)
+ FSTR_P const rw_str = write ? F("write") : F("read");
+ SERIAL_CHAR(' ');
+ SERIAL_ECHOF(rw_str);
+ SERIAL_ECHOLNPGM("_data(", pos, ",", *value, ",", size, ", ...)");
+ if (total) {
+ SERIAL_ECHOPGM(" f_");
+ SERIAL_ECHOF(rw_str);
+ SERIAL_ECHOPGM("()=", s, "\n size=", size, "\n bytes_");
+ SERIAL_ECHOLNF(write ? F("written=") : F("read="), total);
+ }
+ else
+ SERIAL_ECHOLNPGM(" f_lseek()=", s);
+ #endif
}
// File function return codes for type FRESULT. This goes away soon, but
diff --git a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
index d94aba6119f1..f9286a74ac88 100644
--- a/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
+++ b/Marlin/src/HAL/LPC1768/eeprom_wired.cpp
@@ -42,25 +42,22 @@ 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;
}
@@ -68,7 +65,6 @@ bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t
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 126d6e7d5bb2..23bd0cc982b2 100644
--- a/Marlin/src/HAL/LPC1768/endstop_interrupts.h
+++ b/Marlin/src/HAL/LPC1768/endstop_interrupts.h
@@ -122,4 +122,37 @@ void setup_endstop_interrupts() {
#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/fast_pwm.cpp b/Marlin/src/HAL/LPC1768/fast_pwm.cpp
index dd440b5e7730..eae0e36b0b0e 100644
--- a/Marlin/src/HAL/LPC1768/fast_pwm.cpp
+++ b/Marlin/src/HAL/LPC1768/fast_pwm.cpp
@@ -22,18 +22,20 @@
#ifdef TARGET_LPC1768
#include "../../inc/MarlinConfigPre.h"
-
-#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
-
#include
-void set_pwm_frequency(const pin_t pin, int f_desired) {
- LPC176x::pwm_set_frequency(pin, f_desired);
-}
-
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
- LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
+ if (!LPC176x::pin_is_valid(pin)) return;
+ if (LPC176x::pwm_attach_pin(pin))
+ LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range
}
-#endif // NEEDS_HARDWARE_PWM
+#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
+
+ void set_pwm_frequency(const pin_t pin, int f_desired) {
+ LPC176x::pwm_set_frequency(pin, f_desired);
+ }
+
+#endif
+
#endif // TARGET_LPC1768
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 21d149fcafe6..3ea054589ec3 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)
@@ -67,7 +67,7 @@ static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are in
* Test LPC176x-specific configuration values for errors at compile-time.
*/
-//#if ENABLED(SPINDLE_LASER_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
//#endif
@@ -92,7 +92,7 @@ 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)
@@ -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 ecd91f6a3b73..24f4759315bd 100644
--- a/Marlin/src/HAL/LPC1768/include/SPI.h
+++ b/Marlin/src/HAL/LPC1768/include/SPI.h
@@ -77,7 +77,7 @@ class SPISettings {
//uint32_t spiRate() const { return spi_speed; }
- static inline uint32_t spiRate2Clock(uint32_t spiRate) {
+ static uint32_t spiRate2Clock(uint32_t spiRate) {
uint32_t Marlin_speed[7]; // CPSR is always 2
Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
diff --git a/Marlin/src/HAL/LPC1768/main.cpp b/Marlin/src/HAL/LPC1768/main.cpp
index 96faf54d7fd2..ef0dc42c78ca 100644
--- a/Marlin/src/HAL/LPC1768/main.cpp
+++ b/Marlin/src/HAL/LPC1768/main.cpp
@@ -46,6 +46,8 @@ extern "C" {
void SysTick_Callback() { disk_timerproc(); }
+TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
+
void HAL_init() {
// Init LEDs
@@ -90,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
@@ -115,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 HAS_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)) {
@@ -137,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/pinsDebug.h b/Marlin/src/HAL/LPC1768/pinsDebug.h
index f80551604fa1..a2f5c123a260 100644
--- a/Marlin/src/HAL/LPC1768/pinsDebug.h
+++ b/Marlin/src/HAL/LPC1768/pinsDebug.h
@@ -2,6 +2,9 @@
* 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
@@ -33,8 +36,9 @@
#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("%d.%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(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("P%d_%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
+#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0)
+#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
#ifndef M43_NEVER_TOUCH
@@ -48,6 +52,4 @@ bool GET_PINMODE(const pin_t pin) {
return LPC176x::gpio_direction(pin);
}
-bool GET_ARRAY_IS_DIGITAL(const pin_t pin) {
- return (!LPC176x::pin_has_adc(pin) || !LPC176x::pin_adc_enabled(pin));
-}
+#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
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 a2cb66ab5bfd..a9847b2d2fa0 100644
--- a/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/tft_spi.cpp
@@ -26,39 +26,22 @@
#include "tft_spi.h"
-//TFT_SPI tft;
-
SPIClass TFT_SPI::SPIx(1);
-#define TFT_CS_H WRITE(TFT_CS_PIN, HIGH)
-#define TFT_CS_L WRITE(TFT_CS_PIN, LOW)
-
-#define TFT_DC_H WRITE(TFT_DC_PIN, HIGH)
-#define TFT_DC_L WRITE(TFT_DC_PIN, LOW)
-
-#define TFT_RST_H WRITE(TFT_RESET_PIN, HIGH)
-#define TFT_RST_L WRITE(TFT_RESET_PIN, LOW)
-
-#define TFT_BLK_H WRITE(TFT_BACKLIGHT_PIN, HIGH)
-#define TFT_BLK_L WRITE(TFT_BACKLIGHT_PIN, LOW)
-
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
- SET_OUTPUT(TFT_RESET_PIN);
- TFT_RST_H;
+ OUT_WRITE(TFT_RESET_PIN, HIGH);
delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
- SET_OUTPUT(TFT_BACKLIGHT_PIN);
- TFT_BLK_H;
+ OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
SET_OUTPUT(TFT_DC_PIN);
SET_OUTPUT(TFT_CS_PIN);
-
- TFT_DC_H;
- TFT_CS_H;
+ WRITE(TFT_DC_PIN, HIGH);
+ WRITE(TFT_CS_PIN, HIGH);
/**
* STM32F1 APB2 = 72MHz, APB1 = 36MHz, max SPI speed of this MCU if 18Mhz
@@ -97,7 +80,7 @@ void TFT_SPI::Init() {
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
SPIx.setDataSize(DataSize);
SPIx.begin();
- TFT_CS_L;
+ WRITE(TFT_CS_PIN, LOW);
}
uint32_t TFT_SPI::GetID() {
@@ -116,7 +99,7 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
SPIx.setDataSize(DATASIZE_8BIT);
SPIx.setClock(SPI_CLOCK_DIV64);
SPIx.begin();
- TFT_CS_L;
+ WRITE(TFT_CS_PIN, LOW);
WriteReg(Reg);
LOOP_L_N(i, 4) {
@@ -131,21 +114,15 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
return data >> 7;
}
-bool TFT_SPI::isBusy() {
- return false;
-}
+bool TFT_SPI::isBusy() { return false; }
-void TFT_SPI::Abort() {
- DataTransferEnd();
-}
+void TFT_SPI::Abort() { DataTransferEnd(); }
-void TFT_SPI::Transmit(uint16_t Data) {
- SPIx.transfer(Data);
-}
+void TFT_SPI::Transmit(uint16_t Data) { SPIx.transfer(Data); }
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
- DataTransferBegin(DATASIZE_16BIT); //16
- TFT_DC_H;
+ DataTransferBegin(DATASIZE_16BIT);
+ WRITE(TFT_DC_PIN, HIGH);
SPIx.dmaSend(Data, Count, MemoryIncrease);
DataTransferEnd();
}
diff --git a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
index cf14405484ff..9c1e158981da 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.cpp
@@ -22,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
-#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS
+#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 29db0b3fc454..7c456cf00e1b 100644
--- a/Marlin/src/HAL/LPC1768/tft/xpt2046.h
+++ b/Marlin/src/HAL/LPC1768/tft/xpt2046.h
@@ -28,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
@@ -54,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
@@ -65,8 +65,8 @@ class XPT2046 {
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
- static inline void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
- static inline void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
+ static void DataTransferBegin() { WRITE(TOUCH_CS_PIN, LOW); };
+ static void DataTransferEnd() { WRITE(TOUCH_CS_PIN, HIGH); };
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
static uint16_t HardwareIO(uint16_t data);
#endif
diff --git a/Marlin/src/HAL/LPC1768/timers.cpp b/Marlin/src/HAL/LPC1768/timers.cpp
index a7a40584dabc..bbb13f81da05 100644
--- a/Marlin/src/HAL/LPC1768/timers.cpp
+++ b/Marlin/src/HAL/LPC1768/timers.cpp
@@ -40,7 +40,7 @@ void HAL_timer_init() {
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
switch (timer_num) {
- case 0:
+ case MF_TIMER_STEP:
LPC_TIM0->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
LPC_TIM0->MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency
LPC_TIM0->TCR = _BV(SBIT_CNTEN); // Counter Enable
@@ -49,7 +49,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
NVIC_EnableIRQ(TIMER0_IRQn);
break;
- case 1:
+ case MF_TIMER_TEMP:
LPC_TIM1->MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
LPC_TIM1->MR0 = uint32_t(TEMP_TIMER_RATE) / frequency;
LPC_TIM1->TCR = _BV(SBIT_CNTEN); // Counter Enable
diff --git a/Marlin/src/HAL/LPC1768/timers.h b/Marlin/src/HAL/LPC1768/timers.h
index e6744fb005bf..78e856db2857 100644
--- a/Marlin/src/HAL/LPC1768/timers.h
+++ b/Marlin/src/HAL/LPC1768/timers.h
@@ -60,17 +60,17 @@ typedef uint32_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 0 // Timer Index for Stepper
+#ifndef MF_TIMER_STEP
+ #define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM 1 // Timer Index for Temperature
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP 1 // Timer Index for Temperature
#endif
-#ifndef PWM_TIMER_NUM
- #define PWM_TIMER_NUM 3 // Timer Index for PWM
+#ifndef MF_TIMER_PWM
+ #define MF_TIMER_PWM 3 // Timer Index for PWM
#endif
#define TEMP_TIMER_RATE 1000000
@@ -84,23 +84,23 @@ typedef uint32_t hal_timer_t;
#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_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(STEP_TIMER_NUM)
+ #define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_STEP)
#endif
#ifndef HAL_TEMP_TIMER_ISR
- #define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(TEMP_TIMER_NUM)
+ #define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_TEMP)
#endif
// Timer references by index
-#define STEP_TIMER_PTR _HAL_TIMER(STEP_TIMER_NUM)
-#define TEMP_TIMER_PTR _HAL_TIMER(TEMP_TIMER_NUM)
+#define STEP_TIMER_PTR _HAL_TIMER(MF_TIMER_STEP)
+#define TEMP_TIMER_PTR _HAL_TIMER(MF_TIMER_TEMP)
// ------------------------
// Public functions
@@ -110,38 +110,38 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
switch (timer_num) {
- case 0: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0
- case 1: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0
+ case MF_TIMER_STEP: STEP_TIMER_PTR->MR0 = compare; break; // Stepper Timer Match Register 0
+ case MF_TIMER_TEMP: TEMP_TIMER_PTR->MR0 = compare; break; // Temp Timer Match Register 0
}
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
switch (timer_num) {
- case 0: return STEP_TIMER_PTR->MR0; // Stepper Timer Match Register 0
- case 1: return TEMP_TIMER_PTR->MR0; // Temp Timer Match Register 0
+ case MF_TIMER_STEP: return STEP_TIMER_PTR->MR0; // Stepper Timer Match Register 0
+ case MF_TIMER_TEMP: return TEMP_TIMER_PTR->MR0; // Temp Timer Match Register 0
}
return 0;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
switch (timer_num) {
- case 0: return STEP_TIMER_PTR->TC; // Stepper Timer Count
- case 1: return TEMP_TIMER_PTR->TC; // Temp Timer Count
+ case MF_TIMER_STEP: return STEP_TIMER_PTR->TC; // Stepper Timer Count
+ case MF_TIMER_TEMP: return TEMP_TIMER_PTR->TC; // Temp Timer Count
}
return 0;
}
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
- case 0: NVIC_EnableIRQ(TIMER0_IRQn); break; // Enable interrupt handler
- case 1: NVIC_EnableIRQ(TIMER1_IRQn); break; // Enable interrupt handler
+ case MF_TIMER_STEP: NVIC_EnableIRQ(TIMER0_IRQn); break; // Enable interrupt handler
+ case MF_TIMER_TEMP: NVIC_EnableIRQ(TIMER1_IRQn); break; // Enable interrupt handler
}
}
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
switch (timer_num) {
- case 0: NVIC_DisableIRQ(TIMER0_IRQn); break; // Disable interrupt handler
- case 1: NVIC_DisableIRQ(TIMER1_IRQn); break; // Disable interrupt handler
+ case MF_TIMER_STEP: NVIC_DisableIRQ(TIMER0_IRQn); break; // Disable interrupt handler
+ case MF_TIMER_TEMP: NVIC_DisableIRQ(TIMER1_IRQn); break; // Disable interrupt handler
}
// We NEED memory barriers to ensure Interrupts are actually disabled!
@@ -152,22 +152,22 @@ 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) {
switch (timer_num) {
- case 0: return NVIC_GetEnableIRQ(TIMER0_IRQn); // Check if interrupt is enabled or not
- case 1: return NVIC_GetEnableIRQ(TIMER1_IRQn); // Check if interrupt is enabled or not
+ case MF_TIMER_STEP: return NVIC_GetEnableIRQ(TIMER0_IRQn); // Check if interrupt is enabled or not
+ case MF_TIMER_TEMP: return NVIC_GetEnableIRQ(TIMER1_IRQn); // Check if interrupt is enabled or not
}
return false;
}
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
switch (timer_num) {
- case 0: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break;
- case 1: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break;
+ case MF_TIMER_STEP: SBI(STEP_TIMER_PTR->IR, SBIT_CNTEN); break;
+ case MF_TIMER_TEMP: SBI(TEMP_TIMER_PTR->IR, SBIT_CNTEN); break;
}
}
-#define HAL_timer_isr_epilogue(TIMER_NUM)
+#define HAL_timer_isr_epilogue(T)
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..e159ebaa0ca8 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
@@ -57,14 +57,16 @@
#include "../../../inc/MarlinConfigPre.h"
-#if ENABLED(U8GLIB_ST7920)
+#if IS_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);
@@ -141,5 +143,5 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
return 1;
}
-#endif // U8GLIB_ST7920
+#endif // IS_U8GLIB_ST7920
#endif // TARGET_LPC1768
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..f116a9b80aa6 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
@@ -57,19 +57,21 @@
#include "../../../inc/MarlinConfigPre.h"
-#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
+#if HAS_MARLINUI_U8GLIB && !IS_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;
@@ -203,5 +205,5 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
return 1;
}
-#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
+#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // TARGET_LPC1768
diff --git a/Marlin/src/HAL/LPC1768/upload_extra_script.py b/Marlin/src/HAL/LPC1768/upload_extra_script.py
index 1daaa883ed6b..7975f151f712 100755
--- a/Marlin/src/HAL/LPC1768/upload_extra_script.py
+++ b/Marlin/src/HAL/LPC1768/upload_extra_script.py
@@ -1,123 +1,127 @@
#
-# sets output_port
+# upload_extra_script.py
+# set the output_port
# if target_filename is found then that drive is used
# else if target_drive is found then that drive is used
#
from __future__ import print_function
-target_filename = "FIRMWARE.CUR"
-target_drive = "REARM"
+import pioutil
+if pioutil.is_pio_build():
-import os
-import getpass
-import platform
+ target_filename = "FIRMWARE.CUR"
+ target_drive = "REARM"
-current_OS = platform.system()
-Import("env")
+ import os,getpass,platform
-def print_error(e):
- print('\nUnable to find destination disk (%s)\n' \
- 'Please select it in platformio.ini using the upload_port keyword ' \
- '(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
- 'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
- %(e, env.get('PIOENV')))
+ current_OS = platform.system()
+ Import("env")
-try:
- #
- # Find a disk for upload
- #
- upload_disk = 'Disk not found'
- target_file_found = False
- target_drive_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
- from ctypes import windll
- import string
+ def print_error(e):
+ print('\nUnable to find destination disk (%s)\n' \
+ 'Please select it in platformio.ini using the upload_port keyword ' \
+ '(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
+ 'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
+ %(e, env.get('PIOENV')))
- # 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
+ def before_upload(source, target, env):
+ try:
+ #
+ # Find a disk for upload
+ #
+ upload_disk = 'Disk not found'
+ target_file_found = False
+ target_drive_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
- 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
- if target_filename in volume_info:
- if not target_file_found:
- upload_disk = final_drive_name
- target_file_found = True
+ # 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
+ if target_filename in volume_info:
+ if not target_file_found:
+ upload_disk = final_drive_name
+ target_file_found = True
- 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
+ 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:
- 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
- #
+ 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 or target_drive_found:
+ env.Replace(
+ UPLOAD_FLAGS="-P$UPLOAD_PORT"
+ )
- if target_file_found or target_drive_found:
- env.Replace(
- UPLOAD_FLAGS="-P$UPLOAD_PORT"
- )
+ 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:
+ filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
+ except:
+ continue
+ else:
+ if target_filename in filenames:
+ if not target_file_found:
+ upload_disk = '/Volumes/' + drive + '/'
+ target_file_found = True
- 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:
- filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
- except:
- continue
+ #
+ # Set upload_port to drive if found
+ #
+ if target_file_found or target_drive_found:
+ env.Replace(UPLOAD_PORT=upload_disk)
+ print('\nUpload disk: ', upload_disk, '\n')
else:
- if target_filename in filenames:
- if not target_file_found:
- upload_disk = '/Volumes/' + drive + '/'
- target_file_found = True
+ print_error('Autodetect Error')
- #
- # Set upload_port to drive if found
- #
- if target_file_found or target_drive_found:
- 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/NATIVE_SIM/HAL.h b/Marlin/src/HAL/NATIVE_SIM/HAL.h
new file mode 100644
index 000000000000..436b4b4daa26
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/HAL.h
@@ -0,0 +1,222 @@
+/**
+ * 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 CPU_ST7920_DELAY_1 600
+#define CPU_ST7920_DELAY_2 750
+#define CPU_ST7920_DELAY_3 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();
+
+// PWM
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
+// Reset source
+inline void HAL_clear_reset_source(void) {}
+inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
+
+void HAL_reboot();
+
+/* ---------------- 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/NATIVE_SIM/inc/Conditionals_LCD.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
new file mode 100644
index 000000000000..1ac02f118285
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_LCD.h
@@ -0,0 +1,22 @@
+/**
+ * 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
diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
new file mode 100644
index 000000000000..69b6b4848f6e
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_adv.h
@@ -0,0 +1,31 @@
+/**
+ * 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
+
+// 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/NATIVE_SIM/inc/Conditionals_post.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
new file mode 100644
index 000000000000..1ac02f118285
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h
@@ -0,0 +1,22 @@
+/**
+ * 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
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..2d7bef23a36d
--- /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_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
+ #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
+#endif
+
+#if 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..aa90eb39a330
--- /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 PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); 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..b131853643a8
--- /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 void DataTransferBegin();
+ static 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..cedfdb62d631
--- /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 MF_TIMER_STEP
+ #define MF_TIMER_STEP 0 // Timer Index for Stepper
+#endif
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
+#endif
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP 1 // Timer Index for Temperature
+#endif
+#ifndef MF_TIMER_SYSTICK
+ #define MF_TIMER_SYSTICK 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(MF_TIMER_STEP)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
+
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
+
+#ifndef HAL_STEP_TIMER_ISR
+ #define HAL_STEP_TIMER_ISR() 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(T)
+#define HAL_timer_isr_epilogue(T)
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..c384cdd75185
--- /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 IS_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 // IS_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..7be84580b133
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/u8g/u8g_com_sw_spi.cpp
@@ -0,0 +1,218 @@
+/**
+ * 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 && !IS_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 NONE(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 && !IS_U8GLIB_ST7920
+
+#endif // __PLAT_NATIVE_SIM__
diff --git a/Marlin/src/HAL/NATIVE_SIM/watchdog.h b/Marlin/src/HAL/NATIVE_SIM/watchdog.h
new file mode 100644
index 000000000000..4e404c3887da
--- /dev/null
+++ b/Marlin/src/HAL/NATIVE_SIM/watchdog.h
@@ -0,0 +1,27 @@
+/**
+ * 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
+
+#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 d985ef37871f..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
@@ -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 ff9310114641..c262752a8d66 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
@@ -109,6 +127,11 @@ void HAL_adc_init();
void HAL_adc_start_conversion(const uint8_t adc_pin);
+//
+// PWM
+//
+inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
+
//
// Pin Map
//
@@ -135,16 +158,14 @@ void HAL_idletask();
//
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
+#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
#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/MarlinSPI.h b/Marlin/src/HAL/SAMD51/MarlinSPI.h
new file mode 100644
index 000000000000..0c447ba4cb3d
--- /dev/null
+++ b/Marlin/src/HAL/SAMD51/MarlinSPI.h
@@ -0,0 +1,26 @@
+/**
+ * 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
+
+using MarlinSPI = SPIClass;
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.h b/Marlin/src/HAL/SAMD51/QSPIFlash.h
index db4abec91caf..58822fe05f3e 100644
--- a/Marlin/src/HAL/SAMD51/QSPIFlash.h
+++ b/Marlin/src/HAL/SAMD51/QSPIFlash.h
@@ -25,7 +25,6 @@
*
* Derived from Adafruit_SPIFlash class with no SdFat references
*/
-
#pragma once
#include
diff --git a/Marlin/src/HAL/SAMD51/Servo.cpp b/Marlin/src/HAL/SAMD51/Servo.cpp
index 9bab8e89be23..23ab21c615c4 100644
--- a/Marlin/src/HAL/SAMD51/Servo.cpp
+++ b/Marlin/src/HAL/SAMD51/Servo.cpp
@@ -53,7 +53,7 @@
static volatile int8_t currentServoIndex[_Nbr_16timers]; // index for the servo being pulsed for each timer (or -1 if refresh interval)
FORCE_INLINE static uint16_t getTimerCount() {
- Tc * const tc = TimerConfig[SERVO_TC].pTc;
+ Tc * const tc = timer_config[SERVO_TC].pTc;
tc->COUNT16.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
SYNC(tc->COUNT16.SYNCBUSY.bit.CTRLB || tc->COUNT16.SYNCBUSY.bit.COUNT);
@@ -65,7 +65,7 @@ FORCE_INLINE static uint16_t getTimerCount() {
// Interrupt handler for the TC
// ----------------------------
HAL_SERVO_TIMER_ISR() {
- Tc * const tc = TimerConfig[SERVO_TC].pTc;
+ Tc * const tc = timer_config[SERVO_TC].pTc;
const timer16_Sequence_t timer =
#ifndef _useTimer1
_timer2
@@ -125,7 +125,7 @@ HAL_SERVO_TIMER_ISR() {
}
void initISR(timer16_Sequence_t timer) {
- Tc * const tc = TimerConfig[SERVO_TC].pTc;
+ Tc * const tc = timer_config[SERVO_TC].pTc;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
static bool initialized = false; // Servo TC has been initialized
@@ -202,7 +202,7 @@ void initISR(timer16_Sequence_t timer) {
}
void finISR(timer16_Sequence_t timer) {
- Tc * const tc = TimerConfig[SERVO_TC].pTc;
+ Tc * const tc = timer_config[SERVO_TC].pTc;
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
// Disable the match channel interrupt request
diff --git a/Marlin/src/HAL/SAMD51/eeprom_wired.cpp b/Marlin/src/HAL/SAMD51/eeprom_wired.cpp
index d9a0225a7ae4..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;
diff --git a/Marlin/src/HAL/SAMD51/endstop_interrupts.h b/Marlin/src/HAL/SAMD51/endstop_interrupts.h
index daac7733875b..61a06c0d4b42 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(); }
@@ -205,4 +163,40 @@ void setup_endstop_interrupts() {
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
+ #if 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);
+ #endif
+ #if 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);
+ #endif
+ #if 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);
+ #endif
+ #if 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..1b876c947dc7 100644
--- a/Marlin/src/HAL/SAMD51/inc/SanityCheck.h
+++ b/Marlin/src/HAL/SAMD51/inc/SanityCheck.h
@@ -31,11 +31,12 @@
#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
-#if SERVO_TC == RTC_TIMER_NUM
+#if SERVO_TC == MF_TIMER_RTC
#error "Servos can't use RTC timer"
#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/pinsDebug.h b/Marlin/src/HAL/SAMD51/pinsDebug.h
index 81376db79add..f0a46fd7c567 100644
--- a/Marlin/src/HAL/SAMD51/pinsDebug.h
+++ b/Marlin/src/HAL/SAMD51/pinsDebug.h
@@ -26,6 +26,7 @@
#define PRINT_PORT(p) do{ SERIAL_ECHOPGM(" Port: "); sprintf_P(buffer, PSTR("%c%02ld"), 'A' + g_APinDescription[p].ulPort, g_APinDescription[p].ulPin); SERIAL_ECHO(buffer); }while (0)
#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 PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL)
@@ -47,7 +48,7 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
//uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative;
- //SERIAL_ECHOPAIR("PWM = ", duty);
+ //SERIAL_ECHOPGM("PWM = ", duty);
}
}
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..ce13dd231ecd 100644
--- a/Marlin/src/HAL/SAMD51/timers.cpp
+++ b/Marlin/src/HAL/SAMD51/timers.cpp
@@ -31,13 +31,13 @@
// Local defines
// --------------------------------------------------------------------------
-#define NUM_HARDWARE_TIMERS 8
+#define NUM_HARDWARE_TIMERS 9
// --------------------------------------------------------------------------
// Private Variables
// --------------------------------------------------------------------------
-const tTimerConfig TimerConfig[NUM_HARDWARE_TIMERS+1] = {
+const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
{ {.pTc=TC0}, TC0_IRQn, TC_PRIORITY(0) }, // 0 - stepper (assigned priority 2)
{ {.pTc=TC1}, TC1_IRQn, TC_PRIORITY(1) }, // 1 - stepper (needed by 32 bit timers)
{ {.pTc=TC2}, TC2_IRQn, 5 }, // 2 - tone (reserved by framework and fixed assigned priority 5)
@@ -67,13 +67,13 @@ FORCE_INLINE void Disable_Irq(IRQn_Type irq) {
// --------------------------------------------------------------------------
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
- IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ IRQn_Type irq = timer_config[timer_num].IRQ_Id;
// Disable interrupt, just in case it was already enabled
Disable_Irq(irq);
- if (timer_num == RTC_TIMER_NUM) {
- Rtc * const rtc = TimerConfig[timer_num].pRtc;
+ if (timer_num == MF_TIMER_RTC) {
+ Rtc * const rtc = timer_config[timer_num].pRtc;
// Disable timer interrupt
rtc->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
@@ -101,13 +101,13 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
SYNC(rtc->MODE0.SYNCBUSY.bit.ENABLE);
}
else {
- Tc * const tc = TimerConfig[timer_num].pTc;
+ Tc * const tc = timer_config[timer_num].pTc;
// Disable timer interrupt
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
@@ -141,27 +141,27 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
// Finally, enable IRQ
- NVIC_SetPriority(irq, TimerConfig[timer_num].priority);
+ NVIC_SetPriority(irq, timer_config[timer_num].priority);
NVIC_EnableIRQ(irq);
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
- const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ const IRQn_Type irq = timer_config[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
- const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ const IRQn_Type irq = timer_config[timer_num].IRQ_Id;
Disable_Irq(irq);
}
// 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) {
- const IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
+ const IRQn_Type irq = timer_config[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}
diff --git a/Marlin/src/HAL/SAMD51/timers.h b/Marlin/src/HAL/SAMD51/timers.h
index dc6e38b7307c..86e980c56690 100644
--- a/Marlin/src/HAL/SAMD51/timers.h
+++ b/Marlin/src/HAL/SAMD51/timers.h
@@ -25,21 +25,22 @@
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
-#define RTC_TIMER_NUM 8 // This is not a TC but a RTC
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE F_CPU // frequency of timers peripherals
-#ifndef STEP_TIMER_NUM
- #define STEP_TIMER_NUM 0 // Timer Index for Stepper
+#define MF_TIMER_RTC 8 // This is not a TC but a RTC
+
+#ifndef MF_TIMER_STEP
+ #define MF_TIMER_STEP 0 // Timer Index for Stepper
#endif
-#ifndef PULSE_TIMER_NUM
- #define PULSE_TIMER_NUM STEP_TIMER_NUM
+#ifndef MF_TIMER_PULSE
+ #define MF_TIMER_PULSE MF_TIMER_STEP
#endif
-#ifndef TEMP_TIMER_NUM
- #define TEMP_TIMER_NUM RTC_TIMER_NUM // Timer Index for Temperature
+#ifndef MF_TIMER_TEMP
+ #define MF_TIMER_TEMP MF_TIMER_RTC // Timer Index for Temperature
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
@@ -52,30 +53,29 @@ typedef uint32_t hal_timer_t;
#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_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
+#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
+#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
-#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
-#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
+#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
+#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
-#define TC_PRIORITY(t) t == SERVO_TC ? 1 \
- : (t == STEP_TIMER_NUM || t == PULSE_TIMER_NUM) ? 2 \
- : (t == TEMP_TIMER_NUM) ? 6 \
- : 7
+#define TC_PRIORITY(t) ( t == SERVO_TC ? 1 \
+ : (t == MF_TIMER_STEP || t == MF_TIMER_PULSE) ? 2 \
+ : (t == MF_TIMER_TEMP) ? 6 : 7 )
#define _TC_HANDLER(t) void TC##t##_Handler()
#define TC_HANDLER(t) _TC_HANDLER(t)
#ifndef HAL_STEP_TIMER_ISR
- #define HAL_STEP_TIMER_ISR() TC_HANDLER(STEP_TIMER_NUM)
+ #define HAL_STEP_TIMER_ISR() TC_HANDLER(MF_TIMER_STEP)
#endif
-#if STEP_TIMER_NUM != PULSE_TIMER_NUM
- #define HAL_PULSE_TIMER_ISR() TC_HANDLER(PULSE_TIMER_NUM)
+#if MF_TIMER_STEP != MF_TIMER_PULSE
+ #define HAL_PULSE_TIMER_ISR() TC_HANDLER(MF_TIMER_PULSE)
#endif
-#if TEMP_TIMER_NUM == RTC_TIMER_NUM
+#if MF_TIMER_TEMP == MF_TIMER_RTC
#define HAL_TEMP_TIMER_ISR() void RTC_Handler()
#else
- #define HAL_TEMP_TIMER_ISR() TC_HANDLER(TEMP_TIMER_NUM)
+ #define HAL_TEMP_TIMER_ISR() TC_HANDLER(MF_TIMER_TEMP)
#endif
// --------------------------------------------------------------------------
@@ -95,7 +95,7 @@ typedef struct {
// Public Variables
// --------------------------------------------------------------------------
-extern const tTimerConfig TimerConfig[];
+extern const tTimerConfig timer_config[];
// --------------------------------------------------------------------------
// Public functions
@@ -104,20 +104,20 @@ extern const tTimerConfig TimerConfig[];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
- // Should never be called with timer RTC_TIMER_NUM
- Tc * const tc = TimerConfig[timer_num].pTc;
+ // Should never be called with timer MF_TIMER_RTC
+ Tc * const tc = timer_config[timer_num].pTc;
tc->COUNT32.CC[0].reg = compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
- // Should never be called with timer RTC_TIMER_NUM
- Tc * const tc = TimerConfig[timer_num].pTc;
+ // Should never be called with timer MF_TIMER_RTC
+ Tc * const tc = timer_config[timer_num].pTc;
return (hal_timer_t)tc->COUNT32.CC[0].reg;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
- // Should never be called with timer RTC_TIMER_NUM
- Tc * const tc = TimerConfig[timer_num].pTc;
+ // Should never be called with timer MF_TIMER_RTC
+ Tc * const tc = timer_config[timer_num].pTc;
tc->COUNT32.CTRLBSET.reg = TC_CTRLBCLR_CMD_READSYNC;
SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB || tc->COUNT32.SYNCBUSY.bit.COUNT);
return tc->COUNT32.COUNT.reg;
@@ -128,13 +128,13 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
- if (timer_num == RTC_TIMER_NUM) {
- Rtc * const rtc = TimerConfig[timer_num].pRtc;
+ if (timer_num == MF_TIMER_RTC) {
+ Rtc * const rtc = timer_config[timer_num].pRtc;
// Clear interrupt flag
rtc->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_CMP0;
}
else {
- Tc * const tc = TimerConfig[timer_num].pTc;
+ Tc * const tc = timer_config[timer_num].pTc;
// Clear interrupt flag
tc->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;
}
diff --git a/Marlin/src/HAL/STM32/HAL.cpp b/Marlin/src/HAL/STM32/HAL.cpp
index c886f9c0b988..0920a72ec1bc 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
@@ -84,6 +90,25 @@ void HAL_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(); }
@@ -112,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" {
@@ -126,8 +153,8 @@ 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
+WEAK void flashFirmware(const int16_t) { HAL_reboot(); }
// Maple Compatibility
volatile uint32_t systick_uptime_millis = 0;
@@ -138,4 +165,4 @@ void HAL_SYSTICK_Callback() {
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 9842cdaae4b0..adaf14223f32 100644
--- a/Marlin/src/HAL/STM32/HAL.h
+++ b/Marlin/src/HAL/STM32/HAL.h
@@ -37,41 +37,71 @@
#include
+//
+// Default graphical display delays
+//
+#define CPU_ST7920_DELAY_1 300
+#define CPU_ST7920_DELAY_2 40
+#define CPU_ST7920_DELAY_3 340
+
+//
+// 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 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 "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration."
+ #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()
@@ -96,19 +126,15 @@
// 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
// ------------------------
-typedef int16_t pin_t;
+#ifdef STM32G0B1xx
+ typedef int32_t pin_t;
+#else
+ typedef int16_t pin_t;
+#endif
#define HAL_SERVO_LIB libServo
#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
@@ -130,6 +156,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();
@@ -137,25 +165,21 @@ 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);
extern "C" char* _sbrk(int incr);
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wunused-function"
-#endif
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-function"
static inline int freeMemory() {
volatile char top;
return &top - reinterpret_cast(_sbrk(0));
}
-#if GCC_VERSION <= 50000
- #pragma GCC diagnostic pop
-#endif
+#pragma GCC diagnostic pop
//
// ADC
@@ -163,14 +187,19 @@ static inline int freeMemory() {
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
-inline void HAL_adc_init() {}
+#ifdef ADC_RESOLUTION
+ #define HAL_ADC_RESOLUTION ADC_RESOLUTION
+#else
+ #define HAL_ADC_RESOLUTION 12
+#endif
#define HAL_ADC_VREF 3.3
-#define HAL_ADC_RESOLUTION 10
#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();
@@ -182,6 +211,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
@@ -191,6 +221,7 @@ 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
diff --git a/Marlin/src/HAL/STM32/HAL_MinSerial.cpp b/Marlin/src/HAL/STM32/HAL_MinSerial.cpp
new file mode 100644
index 000000000000..b6e86b72daa9
--- /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 NONE(DYNAMIC_VECTORTABLE, STM32F0xx, STM32G0xx) // 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..8ee476164785 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,36 @@ 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);
+ #if PIN_EXISTS(SD_SS)
+ OUT_WRITE(SD_SS_PIN, HIGH);
+ #endif
+ 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 +86,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 +146,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 +167,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 +195,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 +220,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 +228,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
index 399430f5eb94..f7c603d77e5c 100644
--- a/Marlin/src/HAL/STM32/MarlinSPI.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSPI.cpp
@@ -19,7 +19,10 @@
* along with this program. If not, see .
*
*/
-#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "../platforms.h"
+
+#if defined(HAL_STM32) && !defined(STM32H7xx)
#include "MarlinSPI.h"
@@ -60,7 +63,6 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
}
#ifdef STM32F4xx
- _dmaHandle.Init.Channel = DMA_CHANNEL_3;
_dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
#endif
@@ -73,7 +75,8 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
#elif defined(STM32F4xx)
__HAL_RCC_DMA2_CLK_ENABLE();
- _dmaHandle.Instance = DMA2_Stream3;
+ _dmaHandle.Init.Channel = DMA_CHANNEL_3;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0;
#endif
}
#endif
@@ -83,7 +86,9 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
#elif defined(STM32F4xx)
- //TODO: f4 dma config
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3;
#endif
}
#endif
@@ -93,7 +98,9 @@ void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaH
__HAL_RCC_DMA2_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
#elif defined(STM32F4xx)
- //TODO: f4 dma config
+ __HAL_RCC_DMA1_CLK_ENABLE();
+ _dmaHandle.Init.Channel = DMA_CHANNEL_0;
+ _dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2;
#endif
}
#endif
@@ -107,16 +114,19 @@ byte MarlinSPI::transfer(uint8_t _data) {
return rxData;
}
+__STATIC_INLINE void LL_SPI_EnableDMAReq_RX(SPI_TypeDef *SPIx) { SET_BIT(SPIx->CR2, SPI_CR2_RXDMAEN); }
+__STATIC_INLINE void LL_SPI_EnableDMAReq_TX(SPI_TypeDef *SPIx) { SET_BIT(SPIx->CR2, SPI_CR2_TXDMAEN); }
+
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
+ //if (!LL_SPI_IsEnabled(_spi.handle)) // 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 */
+ LL_SPI_EnableDMAReq_RX(_spi.handle.Instance); // Enable Rx DMA Request
}
// check for 2 lines transfer
@@ -129,7 +139,7 @@ uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16
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 */
+ LL_SPI_EnableDMAReq_TX(_spi.handle.Instance); // Enable Tx DMA Request
}
if (transmitBuf) {
@@ -153,7 +163,7 @@ 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 */
+ LL_SPI_EnableDMAReq_TX(_spi.handle.Instance); // Enable Tx DMA Request
HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Abort(&_dmaTx);
// DeInit objects
@@ -161,4 +171,4 @@ uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc)
return 1;
}
-#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+#endif // HAL_STM32 && !STM32H7xx
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.cpp b/Marlin/src/HAL/STM32/MarlinSerial.cpp
index 50765ee9958e..37a8f40fd0b1 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.cpp
+++ b/Marlin/src/HAL/STM32/MarlinSerial.cpp
@@ -2,6 +2,9 @@
* 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
@@ -16,7 +19,10 @@
* along with this program. If not, see .
*
*/
-#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
+
+#include "../platforms.h"
+
+#ifdef HAL_STM32
#include "../../inc/MarlinConfig.h"
#include "MarlinSerial.h"
@@ -28,28 +34,47 @@
#ifndef USART4
#define USART4 UART4
#endif
-
#ifndef USART5
#define USART5 UART5
#endif
#define DECLARE_SERIAL_PORT(ser_num) \
void _rx_complete_irq_ ## ser_num (serial_t * obj); \
- MarlinSerial MSerial ## ser_num (USART ## ser_num, &_rx_complete_irq_ ## ser_num); \
+ MSerialT MSerial ## ser_num (true, USART ## ser_num, &_rx_complete_irq_ ## ser_num); \
void _rx_complete_irq_ ## ser_num (serial_t * obj) { MSerial ## ser_num ._rx_complete_irq(obj); }
-#define DECLARE_SERIAL_PORT_EXP(ser_num) DECLARE_SERIAL_PORT(ser_num)
-
-#if defined(SERIAL_PORT) && SERIAL_PORT >= 0
- DECLARE_SERIAL_PORT_EXP(SERIAL_PORT)
+#if USING_HW_SERIAL1
+ DECLARE_SERIAL_PORT(1)
#endif
-
-#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
- DECLARE_SERIAL_PORT_EXP(SERIAL_PORT_2)
+#if USING_HW_SERIAL2
+ DECLARE_SERIAL_PORT(2)
#endif
-
-#if defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT >= 0
- DECLARE_SERIAL_PORT_EXP(LCD_SERIAL_PORT)
+#if USING_HW_SERIAL3
+ DECLARE_SERIAL_PORT(3)
+#endif
+#if USING_HW_SERIAL4
+ DECLARE_SERIAL_PORT(4)
+#endif
+#if USING_HW_SERIAL5
+ DECLARE_SERIAL_PORT(5)
+#endif
+#if USING_HW_SERIAL6
+ DECLARE_SERIAL_PORT(6)
+#endif
+#if USING_HW_SERIAL7
+ DECLARE_SERIAL_PORT(7)
+#endif
+#if USING_HW_SERIAL8
+ DECLARE_SERIAL_PORT(8)
+#endif
+#if USING_HW_SERIAL9
+ DECLARE_SERIAL_PORT(9)
+#endif
+#if USING_HW_SERIAL10
+ DECLARE_SERIAL_PORT(10)
+#endif
+#if USING_HW_SERIALLP1
+ DECLARE_SERIAL_PORT(LP1)
#endif
void MarlinSerial::begin(unsigned long baud, uint8_t config) {
@@ -77,9 +102,9 @@ void MarlinSerial::_rx_complete_irq(serial_t *obj) {
}
#if ENABLED(EMERGENCY_PARSER)
- emergency_parser.update(emergency_state, c);
+ emergency_parser.update(static_cast(this)->emergency_state, c);
#endif
}
}
-#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+#endif // HAL_STM32
diff --git a/Marlin/src/HAL/STM32/MarlinSerial.h b/Marlin/src/HAL/STM32/MarlinSerial.h
index 3611cc78d7ce..bf861fb8a79a 100644
--- a/Marlin/src/HAL/STM32/MarlinSerial.h
+++ b/Marlin/src/HAL/STM32/MarlinSerial.h
@@ -2,6 +2,9 @@
* 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
@@ -24,41 +27,33 @@
#include "../../feature/e_parser.h"
#endif
+#include "../../core/serial_hook.h"
+
typedef void (*usart_rx_callback_t)(serial_t * obj);
-class MarlinSerial : public HardwareSerial {
-public:
- MarlinSerial(void* peripheral, usart_rx_callback_t rx_callback) :
+struct MarlinSerial : public HardwareSerial {
+ MarlinSerial(void *peripheral, usart_rx_callback_t rx_callback) :
HardwareSerial(peripheral), _rx_callback(rx_callback)
- #if ENABLED(EMERGENCY_PARSER)
- , emergency_state(EmergencyParser::State::EP_RESET)
- #endif
{ }
- #if ENABLED(EMERGENCY_PARSER)
- static inline bool emergency_parser_enabled() { return true; }
- #endif
-
void begin(unsigned long baud, uint8_t config);
inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
- void _rx_complete_irq(serial_t* obj);
+ void _rx_complete_irq(serial_t *obj);
protected:
usart_rx_callback_t _rx_callback;
- #if ENABLED(EMERGENCY_PARSER)
- EmergencyParser::State emergency_state;
- #endif
};
-extern MarlinSerial MSerial1;
-extern MarlinSerial MSerial2;
-extern MarlinSerial MSerial3;
-extern MarlinSerial MSerial4;
-extern MarlinSerial MSerial5;
-extern MarlinSerial MSerial6;
-extern MarlinSerial MSerial7;
-extern MarlinSerial MSerial8;
-extern MarlinSerial MSerial9;
-extern MarlinSerial MSerial10;
-extern MarlinSerial MSerialLP1;
+typedef Serial1Class MSerialT;
+extern MSerialT MSerial1;
+extern MSerialT MSerial2;
+extern MSerialT MSerial3;
+extern MSerialT MSerial4;
+extern MSerialT MSerial5;
+extern MSerialT MSerial6;
+extern MSerialT MSerial7;
+extern MSerialT MSerial8;
+extern MSerialT MSerial9;
+extern MSerialT MSerial10;
+extern MSerialT MSerialLP1;
diff --git a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp b/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
deleted file mode 100644
index a7b1e8006f2d..000000000000
--- a/Marlin/src/HAL/STM32/Sd2Card_sdio_stm32duino.cpp
+++ /dev/null
@@ -1,323 +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 .
- *
- */
-#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
-
-#include "../../inc/MarlinConfig.h"
-
-#if ENABLED(SDIO_SUPPORT)
-
-#include
-#include
-
-#if NONE(STM32F103xE, STM32F103xG, STM32F4xx, STM32F7xx)
- #error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported"
-#endif
-
-#if HAS_SD_HOST_DRIVE
-
- // use USB drivers
-
- extern "C" { int8_t SD_MSC_Read(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
- int8_t SD_MSC_Write(uint8_t lun, uint8_t *buf, uint32_t blk_addr, uint16_t blk_len);
- extern SD_HandleTypeDef hsd;
- }
-
- bool SDIO_Init() {
- return hsd.State == HAL_SD_STATE_READY; // return pass/fail status
- }
-
- bool SDIO_ReadBlock(uint32_t block, uint8_t *src) {
- int8_t status = SD_MSC_Read(0, (uint8_t*)src, block, 1); // read one 512 byte block
- return (bool) status;
- }
-
- bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
- int8_t status = SD_MSC_Write(0, (uint8_t*)src, block, 1); // write one 512 byte block
- return (bool) status;
- }
-
-#else // !USBD_USE_CDC_COMPOSITE
-
- // use local drivers
- #if defined(STM32F103xE) || defined(STM32F103xG)
- #include
- #include
- #elif defined(STM32F4xx)
- #include
- #include