Compare commits
438 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b412a1a03e | ||
|
8fd6f9a2b0 | ||
|
5c225ba887 | ||
|
2685119332 | ||
|
fc350701b2 | ||
|
0ad695d45a | ||
|
f1802bc7fe | ||
|
d6c673b9de | ||
|
6a2a592c26 | ||
|
c4ac695c15 | ||
|
8465818754 | ||
|
3c482a9ba1 | ||
|
ecfe7b6400 | ||
|
85599abba7 | ||
|
494a2fc80c | ||
|
f7bea2846f | ||
|
d56731cd07 | ||
|
0041de1a8a | ||
|
d58497bc8e | ||
|
fd13a928c1 | ||
|
369542db3b | ||
|
40d96c3460 | ||
|
d7a71beaf4 | ||
|
f3b593ae73 | ||
|
1d8d8dccf4 | ||
|
1e127a93c4 | ||
|
fcef8d946c | ||
|
0253500ccd | ||
|
0d783a7690 | ||
|
e784e04132 | ||
|
11d68e3127 | ||
|
8b8b2a7ed3 | ||
|
fc1a620b87 | ||
|
9799907dc9 | ||
|
6fc4dbbbc4 | ||
|
74596ad4d7 | ||
|
28f8646aa6 | ||
|
9a74bcd4cf | ||
|
07cd248b91 | ||
|
209c792ef7 | ||
|
dbd00d9927 | ||
|
4ae54a6229 | ||
|
ce0af56d0a | ||
|
6c557a2480 | ||
|
a6ce9bf559 | ||
|
21c838cb1b | ||
|
3443a9e18b | ||
|
b2b5b85045 | ||
|
2086cc9f4e | ||
|
8eccfd4a6f | ||
|
9ab654adcb | ||
|
0ae982188c | ||
|
bed0788f72 | ||
|
deb1ba73bb | ||
|
57f0ac88af | ||
|
915bce495c | ||
|
800a936caa | ||
|
ccf39b1c42 | ||
|
d19179ce28 | ||
|
4a6ae1b64d | ||
|
0daaef589c | ||
|
4831cbebd8 | ||
|
e0deb75764 | ||
|
a0fe4f4895 | ||
|
4d65d7f142 | ||
|
1b879f0ee4 | ||
|
b6abc760ce | ||
|
0ae061713c | ||
|
1d12e72bf6 | ||
|
c97cf10956 | ||
|
b72f9277e9 | ||
|
06c4a9acdb | ||
|
8a301196e1 | ||
|
1e7219f4a6 | ||
|
02c267f542 | ||
|
fe77fc66c0 | ||
|
268a16b1ef | ||
|
8351b1431f | ||
|
718806761f | ||
|
78c7fedcea | ||
|
c4b8339b84 | ||
|
94ed67e36e | ||
|
03b819bdb2 | ||
|
2204f05dca | ||
|
a13cceaad1 | ||
|
5c25ed60c8 | ||
|
1c516bdd5e | ||
|
425684e2ff | ||
|
63aecad7ee | ||
|
dcd769b4a1 | ||
|
f9b7f00d1e | ||
|
a6ff63d506 | ||
|
7d37ae2b2b | ||
|
a7d40ec654 | ||
|
7ed339cfa0 | ||
|
cb4ad020af | ||
|
0805f9bf3f | ||
|
d235bc9e1c | ||
|
d5f472a6cf | ||
|
d67fa98cf6 | ||
|
d3fe0caa7f | ||
|
bd09f8acff | ||
|
a9aca5f5e8 | ||
|
13d1eb7241 | ||
|
238ab1dd06 | ||
|
a7e4061d12 | ||
|
31c87adba8 | ||
|
727e7e7fd7 | ||
|
975b90c0b7 | ||
|
8f0180802a | ||
|
aa4c991755 | ||
|
9ab1a57d72 | ||
|
044bf8ab7e | ||
|
4bdec5e993 | ||
|
7444933d5d | ||
|
f35404f853 | ||
|
7fa2dcedda | ||
|
4c84769a81 | ||
|
8fb3074901 | ||
|
230db90b70 | ||
|
28d2bc353e | ||
|
7b5e2cd786 | ||
|
4b456078dd | ||
|
8d3c84a6d9 | ||
|
cbc6f23a8a | ||
|
bed8abe5b6 | ||
|
74565890f3 | ||
|
4ec9af42b8 | ||
|
b0d621d8b9 | ||
|
995221e68e | ||
|
54e543872b | ||
|
7b39604d6f | ||
|
01c9c26661 | ||
|
27b1484428 | ||
|
7f1c5ad7aa | ||
|
4fd7d1b056 | ||
|
7ffe4de021 | ||
|
eada17ed69 | ||
|
cd5c5ea60e | ||
|
e9ea82e78d | ||
|
18b17fc97d | ||
|
89d5ed0c9e | ||
|
a56bf9045d | ||
|
c23d035149 | ||
|
7ff4b70694 | ||
|
421c38ff2e | ||
|
ec447dba04 | ||
|
be6535e5f7 | ||
|
99252cf0cd | ||
|
f6f31434b8 | ||
|
2f3960904e | ||
|
2dc4c642e7 | ||
|
70ea0e7c34 | ||
|
a81fd009f0 | ||
|
e667d4e6e4 | ||
|
2d0af75d37 | ||
|
5e68a86968 | ||
|
8bd1547c3b | ||
|
a5e083603f | ||
|
c5f7547e8c | ||
|
5c5b380fda | ||
|
bb0e0cf7f3 | ||
|
5ee99dfc49 | ||
|
a083b1280e | ||
|
b7b5cee88b | ||
|
7456fd68a4 | ||
|
20154718b5 | ||
|
a6794c1862 | ||
|
bd5c6bf23c | ||
|
68ee64283a | ||
|
dd29394bbe | ||
|
ceb99e89a0 | ||
|
6112277f9b | ||
|
81f403025c | ||
|
eeda8b451a | ||
|
c7e8ba7857 | ||
|
071e5c336a | ||
|
be08d4c4f0 | ||
|
e99104a004 | ||
|
edc4089121 | ||
|
3bce266ef7 | ||
|
c89d0114ac | ||
|
0e693854d0 | ||
|
9324132a40 | ||
|
5632ad65f5 | ||
|
eccbfbcede | ||
|
5ef4fb378e | ||
|
21f0945d2c | ||
|
b2a318af9a | ||
|
1c89c0470f | ||
|
2ee4a667e1 | ||
|
f8e177a43e | ||
|
9ac1c73041 | ||
|
4a8b99d505 | ||
|
b094a3fc0d | ||
|
2d99a608fd | ||
|
fba8805c0c | ||
|
039a22649f | ||
|
ced0ad8e09 | ||
|
10a0c9a9b3 | ||
|
abfb041180 | ||
|
72f207f489 | ||
|
7186037f20 | ||
|
b0a400da72 | ||
|
cc4c2c2f98 | ||
|
5dae8a6734 | ||
|
05dea4e30a | ||
|
7e88ee8c5c | ||
|
cc8e485e1c | ||
|
c7a2ecc31a | ||
|
260b40d145 | ||
|
c87eded8f6 | ||
|
2f2a999368 | ||
|
2558b323e8 | ||
|
1db6855939 | ||
|
62f298aca3 | ||
|
8d20c5aadf | ||
|
61b470249c | ||
|
4ffa88f814 | ||
|
8257040faf | ||
|
5d9ab7e71e | ||
|
1a76d4d467 | ||
|
4028c1cfc7 | ||
|
c49f26a7ae | ||
|
f82b133595 | ||
|
2c3f2a1471 | ||
|
4817efcf81 | ||
|
16271377e2 | ||
|
61fb382868 | ||
|
7dae720de5 | ||
|
c6f4b38877 | ||
|
eabeac29fd | ||
|
b045c91f26 | ||
|
56955c179d | ||
|
4eb1326355 | ||
|
b669aa49cc | ||
|
152ec49b8b | ||
|
e4ca822dcf | ||
|
0fafcd20cd | ||
|
bd72df3bb6 | ||
|
fd582dc863 | ||
|
2986bc3b76 | ||
|
e082a141f6 | ||
|
575c3150f9 | ||
|
43d4e30668 | ||
|
9b17699b9b | ||
|
0337602bbe | ||
|
fbfe0642b6 | ||
|
41a51e9527 | ||
|
2d648e4dd9 | ||
|
35d11070b4 | ||
|
feafb7d49a | ||
|
39001bd8d2 | ||
|
3db2fecaa4 | ||
|
c0288590b3 | ||
|
d2cd3f2e68 | ||
|
893c662438 | ||
|
b0fdbede9c | ||
|
8e11a2bb83 | ||
|
9588f21d2e | ||
|
80e569015b | ||
|
be70352203 | ||
|
980c009fc7 | ||
|
8a02646f52 | ||
|
7ec2167a73 | ||
|
56cec9690a | ||
|
428b67db31 | ||
|
1b2715ccf2 | ||
|
ac76ed7ece | ||
|
4ba4ab1c75 | ||
|
c0f6d2f78c | ||
|
0b4f5298f5 | ||
|
195383bc33 | ||
|
4199191e99 | ||
|
7da28768f7 | ||
|
172cd2eefb | ||
|
341113bcfb | ||
|
5f0e1a15df | ||
|
3abf4de4ae | ||
|
cc1a48ad2d | ||
|
2a584cea96 | ||
|
9f57f6f36f | ||
|
59548410b8 | ||
|
65c4f14a9e | ||
|
3e18cf2b6a | ||
|
11071c7472 | ||
|
38484c6eb6 | ||
|
b964d2fff0 | ||
|
973366e6aa | ||
|
e255e4a69f | ||
|
942f088522 | ||
|
c4341a4e35 | ||
|
6e23ffd12c | ||
|
58239c65cb | ||
|
82ae3646cb | ||
|
8799837d75 | ||
|
cdcf31453b | ||
|
a23ecf0d2f | ||
|
f5046a41cd | ||
|
0d07c49c1d | ||
|
f193729f54 | ||
|
22db62d95a | ||
|
50ffacfb90 | ||
|
21935b41f0 | ||
|
15eabba11d | ||
|
b2d0f2fd8c | ||
|
a07d7e4b8a | ||
|
d4801461f5 | ||
|
f42c1b4cae | ||
|
f8571fc18f | ||
|
fbbf556e08 | ||
|
1cdaddaaf2 | ||
|
4d8976bf6b | ||
|
c02bc3887a | ||
|
68dfc50564 | ||
|
c7b0626b02 | ||
|
30d1f0ba81 | ||
|
758dc7af9d | ||
|
361dab93b3 | ||
|
f0f1d33980 | ||
|
38e0e92e9d | ||
|
2dcc3ddeed | ||
|
33c89547f0 | ||
|
a4ea8bc1e1 | ||
|
9f06079549 | ||
|
2f48c30445 | ||
|
5090687682 | ||
|
2d032b734c | ||
|
2142456a25 | ||
|
99f3b8b4a8 | ||
|
de0bc19230 | ||
|
17099e7973 | ||
|
63f3e347d9 | ||
|
32ff8c1489 | ||
|
369ba99fdb | ||
|
f33ec4aacf | ||
|
1d0ca179b5 | ||
|
8ea172cafe | ||
|
7b4f5108ac | ||
|
6f82d1befb | ||
|
5d5be55ef9 | ||
|
e704de9bb0 | ||
|
8695f462b7 | ||
|
d8c5e49281 | ||
|
4e72df9a28 | ||
|
ac6c1a9e12 | ||
|
3f4112aee4 | ||
|
31ec8f2449 | ||
|
d18558bbd3 | ||
|
70f03ad852 | ||
|
ab40c99893 | ||
|
420f074915 | ||
|
4f2ed67324 | ||
|
a80cafbcfc | ||
|
01cb7c19f9 | ||
|
44249b1380 | ||
|
d7287e7db8 | ||
|
cf654bbba2 | ||
|
5617edbb96 | ||
|
39e4310c7b | ||
|
0204547c09 | ||
|
7b79d53de0 | ||
|
c478ed08c8 | ||
|
67e5298a34 | ||
|
2ca1d844d7 | ||
|
b435487da7 | ||
|
d7b7b570c7 | ||
|
2690bb1bc2 | ||
|
b6c37960e8 | ||
|
c1d3e4634c | ||
|
9df0dbc981 | ||
|
d418f3bfba | ||
|
2893060302 | ||
|
ad945017d6 | ||
|
52a92ca24e | ||
|
ba2f6c66d3 | ||
|
19e193410e | ||
|
b9cef2e2e3 | ||
|
186d2ba6b4 | ||
|
4dfd398d7d | ||
|
bfdb7c7135 | ||
|
bf067738f2 | ||
|
e028a3c441 | ||
|
9847470b38 | ||
|
51209667a5 | ||
|
db4172b5fa | ||
|
242192d03d | ||
|
7135c3b185 | ||
|
c91d033b5d | ||
|
0470fbe0a1 | ||
|
eb8d819325 | ||
|
41f80a4498 | ||
|
e0f75d4f06 | ||
|
42449b8683 | ||
|
e23c696566 | ||
|
035f9b8e13 | ||
|
49f8171f7a | ||
|
75d0e94d5b | ||
|
915f610782 | ||
|
2231e00b2c | ||
|
63f2b15396 | ||
|
f503722c45 | ||
|
4fd1de7fb7 | ||
|
93126c0d02 | ||
|
80f77ea807 | ||
|
9ff8220b8a | ||
|
7754860289 | ||
|
4efe4788af | ||
|
2faf4e2a99 | ||
|
9956e62674 | ||
|
a732427329 | ||
|
974883d2f6 | ||
|
1170ed995e | ||
|
24f9c3a777 | ||
|
5ec384f40c | ||
|
6d7ffa6add | ||
|
dadd7516b5 | ||
|
f99732ba75 | ||
|
5a9635aa58 | ||
|
1552c6d2a5 | ||
|
06c2ed3c99 | ||
|
430c5da54c | ||
|
5b9f3bd4b1 | ||
|
ccc66a8528 | ||
|
8abe314b18 | ||
|
dc470eb10f | ||
|
4c5e57ae89 | ||
|
5d7328df46 | ||
|
99c237e05e | ||
|
56adbc3ebf | ||
|
4cfe812c18 | ||
|
27d2471ea3 | ||
|
61b9248c35 | ||
|
c9561a8826 | ||
|
58c84f17ba | ||
|
73b8320e9c | ||
|
1c3f2498b1 | ||
|
4202baa409 |
169
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
169
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,169 +0,0 @@
|
||||
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
|
20
.github/ISSUE_TEMPLATE/config.yml
vendored
20
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,20 +0,0 @@
|
||||
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!
|
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,44 +0,0 @@
|
||||
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.
|
10
.github/contributing.md
vendored
10
.github/contributing.md
vendored
@@ -50,13 +50,13 @@ If chat is more your speed, you can join the MarlinFirmware Discord server:
|
||||
|
||||
This section guides you through submitting a Bug Report for Marlin. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
|
||||
|
||||
Before creating a Bug Report, please test the "nightly" development branch, as you might find out that you don't need to create one. When you are creating a Bug Report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](issue_template.md), the information it asks for helps us resolve issues faster.
|
||||
Before creating a Bug Report, please test the "nightly" development branch, as you might find out that you don't need to create one. When you are creating a Bug Report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](ISSUE_TEMPLATE/bug_report.yml), the information it asks for helps us resolve issues faster.
|
||||
|
||||
> **Note:** Regressions can happen. If you find a **Closed** issue that seems like your issue, go ahead and open a new issue and include a link to the original issue in the body of your new one. All you need to create a link is the issue number, preceded by #. For example, #8888.
|
||||
|
||||
#### How Do I Submit A (Good) Bug Report?
|
||||
|
||||
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Use the New Issue button to create an issue and provide the following information by filling in [the template](issue_template.md).
|
||||
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Use the New Issue button to create an issue and provide the following information by filling in [the template](ISSUE_TEMPLATE/bug_report.yml).
|
||||
|
||||
Explain the problem and include additional details to help maintainers reproduce the problem:
|
||||
|
||||
@@ -88,12 +88,12 @@ Include details about your configuration and environment:
|
||||
|
||||
This section guides you through submitting a suggestion for Marlin, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions.
|
||||
|
||||
Before creating a suggestion, please check [this list](#before-submitting-a-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). Fill in [the template](issue_template.md), including the steps that you imagine you would take if the feature you're requesting existed.
|
||||
Before creating a suggestion, please check [this list](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aopen+is%3Aissue+label%3A%22T%3A+Feature+Request%22) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-feature-request). Fill in [the template](ISSUE_TEMPLATE/feature_request.yml), including the steps that you imagine you would take if the feature you're requesting existed.
|
||||
|
||||
#### Before Submitting a Feature Request
|
||||
|
||||
* **Check the [Marlin website](https://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](https://marlinfw.org/docs/configuration/configuration.html).
|
||||
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
||||
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aopen+is%3Aissue+label%3A%22T%3A+Feature+Request%22)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
||||
|
||||
#### How Do I Submit A (Good) Feature Request?
|
||||
|
||||
@@ -116,7 +116,7 @@ Unsure where to begin contributing to Marlin? You can start by looking through t
|
||||
|
||||
### Pull Requests
|
||||
|
||||
Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
|
||||
Pull Requests should always be targeted to working branches (e.g., `bugfix-2.0.x` and/or `bugfix-1.1.x`) and never to release branches (e.g., `2.0.x` and/or `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
|
||||
|
||||
* Fill in [the required template](pull_request_template.md).
|
||||
* Don't include issue numbers in the PR title.
|
||||
|
35
.github/issue_template.md
vendored
35
.github/issue_template.md
vendored
@@ -1,35 +0,0 @@
|
||||
<!--
|
||||
|
||||
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/.github/code_of_conduct.md
|
||||
|
||||
Do you want to ask a question? Are you looking for support? Please don't post here. Instead use one of the following options:
|
||||
|
||||
- The Marlin Firmware forum at https://reprap.org/forum/list.php?415
|
||||
- The MarlinFirmware Facebook Group at https://www.facebook.com/groups/1049718498464482/
|
||||
- The MarlinFirmware Discord Server at https://discord.gg/n5NJ59y.
|
||||
|
||||
Before filing an issue be sure to test the latest "bugfix" branch to see whether the issue is already addressed.
|
||||
|
||||
-->
|
||||
|
||||
### Description
|
||||
|
||||
<!-- Description of the bug or requested feature -->
|
||||
|
||||
### Steps to Reproduce
|
||||
|
||||
<!-- If this is a Bug Report, please describe the steps needed to reproduce the issue -->
|
||||
|
||||
1. [First Step]
|
||||
2. [Second Step]
|
||||
3. [and so on...]
|
||||
|
||||
**Expected behavior:** [What you expect to happen]
|
||||
|
||||
**Actual behavior:** [What actually happens]
|
||||
|
||||
#### Additional Information
|
||||
|
||||
* Include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files.
|
||||
* Provide pictures or links to videos that clearly demonstrate the issue.
|
||||
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.
|
40
.github/lock.yml
vendored
40
.github/lock.yml
vendored
@@ -1,40 +0,0 @@
|
||||
#
|
||||
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
|
||||
#
|
||||
|
||||
# Number of days of inactivity before a closed issue or pull request is locked
|
||||
daysUntilLock: 60
|
||||
|
||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
||||
skipCreatedBefore: false
|
||||
|
||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
||||
exemptLabels: [ 'no-locking' ]
|
||||
|
||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
||||
lockLabel: false
|
||||
|
||||
# Comment to post before locking. Set to `false` to disable
|
||||
lockComment: >
|
||||
This thread has been automatically locked since there has not been
|
||||
any recent activity after it was closed. Please open a new issue for
|
||||
related bugs.
|
||||
|
||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
||||
setLockReason: true
|
||||
|
||||
# Limit to only `issues` or `pulls`
|
||||
# only: issues
|
||||
|
||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
||||
# issues:
|
||||
# exemptLabels:
|
||||
# - help-wanted
|
||||
# lockLabel: outdated
|
||||
|
||||
# pulls:
|
||||
# daysUntilLock: 30
|
||||
|
||||
# Repository to extend settings from
|
||||
# _extends: repo
|
36
.github/workflows/bump-date.yml
vendored
36
.github/workflows/bump-date.yml
vendored
@@ -1,36 +0,0 @@
|
||||
#
|
||||
# bump-date.yml
|
||||
# Bump the distribution date once per day
|
||||
#
|
||||
|
||||
name: Bump Distribution Date
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '0 0 * * *'
|
||||
|
||||
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
|
||||
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
|
33
.github/workflows/check-pr.yml
vendored
33
.github/workflows/check-pr.yml
vendored
@@ -1,33 +0,0 @@
|
||||
#
|
||||
# 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.
|
39
.github/workflows/clean-closed.yml
vendored
39
.github/workflows/clean-closed.yml
vendored
@@ -1,39 +0,0 @@
|
||||
#
|
||||
# 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 }}
|
28
.github/workflows/close-stale.yml
vendored
28
.github/workflows/close-stale.yml
vendored
@@ -1,28 +0,0 @@
|
||||
#
|
||||
# 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'
|
32
.github/workflows/lock-closed.yml
vendored
32
.github/workflows/lock-closed.yml
vendored
@@ -1,32 +0,0 @@
|
||||
#
|
||||
# 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: ''
|
145
.github/workflows/test-builds.yml
vendored
145
.github/workflows/test-builds.yml
vendored
@@ -1,145 +0,0 @@
|
||||
#
|
||||
# test-builds.yml
|
||||
# Do test builds to catch compile errors
|
||||
#
|
||||
|
||||
name: CI
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches:
|
||||
- bugfix-2.0.x
|
||||
paths-ignore:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- '**/*.md'
|
||||
push:
|
||||
branches:
|
||||
- bugfix-2.0.x
|
||||
paths-ignore:
|
||||
- config/**
|
||||
- data/**
|
||||
- docs/**
|
||||
- '**/*.md'
|
||||
|
||||
jobs:
|
||||
test_builds:
|
||||
name: Run All Tests
|
||||
if: github.repository == 'MarlinFirmware/Marlin'
|
||||
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
test-platform:
|
||||
# Base Environments
|
||||
|
||||
- DUE
|
||||
- DUE_archim
|
||||
- esp32
|
||||
- linux_native
|
||||
- mega2560
|
||||
- at90usb1286_dfu
|
||||
- teensy31
|
||||
- teensy35
|
||||
- teensy41
|
||||
- SAMD51_grandcentral_m4
|
||||
|
||||
# Extended AVR Environments
|
||||
|
||||
- FYSETC_F6
|
||||
- mega1280
|
||||
- rambo
|
||||
- sanguino1284p
|
||||
- sanguino644p
|
||||
|
||||
# STM32F1 (Maple) Environments
|
||||
|
||||
#- STM32F103RC_btt_maple
|
||||
- STM32F103RC_btt_USB_maple
|
||||
- STM32F103RC_fysetc_maple
|
||||
- STM32F103RC_meeb
|
||||
- jgaurora_a5s_a1_maple
|
||||
- STM32F103VE_longer_maple
|
||||
#- mks_robin_maple
|
||||
- mks_robin_lite_maple
|
||||
- mks_robin_pro_maple
|
||||
#- mks_robin_nano35_maple
|
||||
#- STM32F103RET6_creality_maple
|
||||
- STM32F103VE_ZM3E4V2_USB_maple
|
||||
|
||||
# STM32 (ST) Environments
|
||||
|
||||
- STM32F103RC_btt
|
||||
#- STM32F103RC_btt_USB
|
||||
- STM32F103RE_btt
|
||||
- STM32F103RE_btt_USB
|
||||
- STM32F103RET6_creality
|
||||
- STM32F103VE_longer
|
||||
- STM32F407VE_black
|
||||
- STM32F401VE_STEVAL
|
||||
- BIGTREE_BTT002
|
||||
- BIGTREE_SKR_PRO
|
||||
- BIGTREE_GTR_V1_0
|
||||
- mks_robin
|
||||
- ARMED
|
||||
- FYSETC_S6
|
||||
- STM32F070CB_malyan
|
||||
- STM32F070RB_malyan
|
||||
- malyan_M300
|
||||
- FLYF407ZG
|
||||
- rumba32
|
||||
- LERDGEX
|
||||
- LERDGEK
|
||||
- mks_robin_nano35
|
||||
- NUCLEO_F767ZI
|
||||
- REMRAM_V1
|
||||
- BTT_SKR_SE_BX
|
||||
- chitu_f103
|
||||
- Index_Mobo_Rev03
|
||||
|
||||
# Put lengthy tests last
|
||||
|
||||
- LPC1768
|
||||
- LPC1769
|
||||
|
||||
# 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@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
|
||||
|
||||
- name: Install PlatformIO
|
||||
run: |
|
||||
pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
|
||||
platformio update
|
||||
|
||||
- name: Run ${{ matrix.test-platform }} Tests
|
||||
run: |
|
||||
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
|
22
.github/workflows/unlock-reopened.yml
vendored
22
.github/workflows/unlock-reopened.yml
vendored
@@ -1,22 +0,0 @@
|
||||
#
|
||||
# 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 }}"
|
8
.gitignore
vendored
8
.gitignore
vendored
@@ -41,7 +41,6 @@ applet/
|
||||
*.rej
|
||||
*.bak
|
||||
*.idea
|
||||
*.s
|
||||
*.i
|
||||
*.ii
|
||||
*.swp
|
||||
@@ -141,11 +140,8 @@ __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
|
||||
|
11
.vscode/extensions.json
vendored
Normal file
11
.vscode/extensions.json
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"marlinfirmware.auto-build",
|
||||
"platformio.platformio-ide"
|
||||
],
|
||||
"unwantedRecommendations": [
|
||||
"ms-vscode.cpptools-extension-pack"
|
||||
]
|
||||
}
|
@@ -35,7 +35,7 @@
|
||||
*
|
||||
* Advanced settings can be found in Configuration_adv.h
|
||||
*/
|
||||
#define CONFIGURATION_H_VERSION 02000903
|
||||
#define CONFIGURATION_H_VERSION 02010000
|
||||
|
||||
//===========================================================================
|
||||
//============================= Getting Started =============================
|
||||
@@ -150,42 +150,84 @@
|
||||
//#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:
|
||||
* Stepper Drivers
|
||||
*
|
||||
* 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
|
||||
* These settings allow Marlin to tune stepper driver timing and enable advanced options for
|
||||
* stepper drivers that support them. You may also override timing options in Configuration_adv.h.
|
||||
*
|
||||
* :[3, 4, 5, 6]
|
||||
* Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
|
||||
*
|
||||
* Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01,
|
||||
* TB6560, TB6600, TMC2100,
|
||||
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
|
||||
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
|
||||
* TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE,
|
||||
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE
|
||||
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'L6470', 'L6474', 'POWERSTEP01', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC26X', 'TMC26X_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
|
||||
*/
|
||||
//#define LINEAR_AXES 3
|
||||
#define X_DRIVER_TYPE A4988
|
||||
#define Y_DRIVER_TYPE A4988
|
||||
#define Z_DRIVER_TYPE A4988
|
||||
//#define X2_DRIVER_TYPE A4988
|
||||
//#define Y2_DRIVER_TYPE A4988
|
||||
//#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 U_DRIVER_TYPE A4988
|
||||
//#define V_DRIVER_TYPE A4988
|
||||
//#define W_DRIVER_TYPE A4988
|
||||
#define E0_DRIVER_TYPE A4988
|
||||
//#define E1_DRIVER_TYPE A4988
|
||||
//#define E2_DRIVER_TYPE A4988
|
||||
//#define E3_DRIVER_TYPE A4988
|
||||
//#define E4_DRIVER_TYPE A4988
|
||||
//#define E5_DRIVER_TYPE A4988
|
||||
//#define E6_DRIVER_TYPE A4988
|
||||
//#define E7_DRIVER_TYPE A4988
|
||||
|
||||
/**
|
||||
* 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).
|
||||
* Additional Axis Settings
|
||||
*
|
||||
* Define AXISn_ROTATES for all axes that rotate or pivot.
|
||||
* Rotational axis coordinates are expressed in degrees.
|
||||
*
|
||||
* AXISn_NAME defines the letter used to refer to the axis in (most) G-code commands.
|
||||
* By convention the names and roles are typically:
|
||||
* 'A' : Rotational axis parallel to X
|
||||
* 'B' : Rotational axis parallel to Y
|
||||
* 'C' : Rotational axis parallel to Z
|
||||
* 'U' : Secondary linear axis parallel to X
|
||||
* 'V' : Secondary linear axis parallel to Y
|
||||
* 'W' : Secondary linear axis parallel to Z
|
||||
*
|
||||
* Regardless of these settings the axes are internally named I, J, K, U, V, W.
|
||||
*/
|
||||
#if LINEAR_AXES >= 4
|
||||
#ifdef I_DRIVER_TYPE
|
||||
#define AXIS4_NAME 'A' // :['A', 'B', 'C', 'U', 'V', 'W']
|
||||
#define AXIS4_ROTATES
|
||||
#endif
|
||||
#if LINEAR_AXES >= 5
|
||||
#define AXIS5_NAME 'B' // :['A', 'B', 'C', 'U', 'V', 'W']
|
||||
#ifdef J_DRIVER_TYPE
|
||||
#define AXIS5_NAME 'B' // :['B', 'C', 'U', 'V', 'W']
|
||||
#define AXIS5_ROTATES
|
||||
#endif
|
||||
#if LINEAR_AXES >= 6
|
||||
#define AXIS6_NAME 'C' // :['A', 'B', 'C', 'U', 'V', 'W']
|
||||
#ifdef K_DRIVER_TYPE
|
||||
#define AXIS6_NAME 'C' // :['C', 'U', 'V', 'W']
|
||||
#define AXIS6_ROTATES
|
||||
#endif
|
||||
#ifdef U_DRIVER_TYPE
|
||||
#define AXIS7_NAME 'U' // :['U', 'V', 'W']
|
||||
//#define AXIS7_ROTATES
|
||||
#endif
|
||||
#ifdef V_DRIVER_TYPE
|
||||
#define AXIS8_NAME 'V' // :['V', 'W']
|
||||
//#define AXIS8_ROTATES
|
||||
#endif
|
||||
#ifdef W_DRIVER_TYPE
|
||||
#define AXIS9_NAME 'W' // :['W']
|
||||
//#define AXIS9_ROTATES
|
||||
#endif
|
||||
|
||||
// @section extruder
|
||||
@@ -371,8 +413,12 @@
|
||||
//#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
|
||||
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
|
||||
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
|
||||
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
|
||||
//#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay
|
||||
|
||||
//#define POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
|
||||
//#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown
|
||||
|
||||
//#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
|
||||
//#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off)
|
||||
@@ -384,12 +430,14 @@
|
||||
#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
|
||||
#if EITHER(AUTO_POWER_CONTROL, POWER_OFF_WAIT_FOR_COOLDOWN)
|
||||
//#define AUTO_POWER_E_TEMP 50 // (°C) PSU on if any extruder is over this temperature
|
||||
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) PSU on if the chamber is over this temperature
|
||||
//#define AUTO_POWER_COOLER_TEMP 26 // (°C) PSU on if the cooler is over this temperature
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
@@ -431,6 +479,9 @@
|
||||
* 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
|
||||
* 503 : 100kΩ Zonestar (Z8XM2) Heated Bed thermistor
|
||||
* 504 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-B3950) Hotend Thermistor
|
||||
* 505 : 100kΩ Zonestar P802QR2 (Part# QWG-104F-3950) Bed Thermistor
|
||||
* 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
|
||||
@@ -450,6 +501,7 @@
|
||||
* 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
|
||||
* 66 : 4.7MΩ Dyze Design High Temperature Thermistor
|
||||
* 67 : 500kΩ SliceEngineering 450°C Thermistor
|
||||
* 68 : PT100 amplifier board from Dyze Design
|
||||
* 70 : 100kΩ bq Hephestos 2
|
||||
* 75 : 100kΩ Generic Silicon Heat Pad with NTC100K MGB18-104F39050L32
|
||||
* 2000 : 100kΩ Ultimachine Rambo TDK NTCG104LH104KT1 NTC100K motherboard Thermistor
|
||||
@@ -579,19 +631,19 @@
|
||||
//===========================================================================
|
||||
//============================= PID Settings ================================
|
||||
//===========================================================================
|
||||
// PID Tuning Guide here: https://reprap.org/wiki/PID_Tuning
|
||||
|
||||
// Comment the following line to disable PID and enable bang-bang.
|
||||
#define PIDTEMP
|
||||
// Enable PIDTEMP for PID control or MPCTEMP for Predictive Model.
|
||||
// temperature control. Disable both for bang-bang heating.
|
||||
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
|
||||
//#define MPCTEMP // ** EXPERIMENTAL **
|
||||
|
||||
#define BANG_MAX 255 // Limits current to nozzle while in bang-bang mode; 255=full current
|
||||
#define PID_MAX BANG_MAX // Limits current to nozzle while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
|
||||
#define PID_K1 0.95 // Smoothing factor within any PID loop
|
||||
|
||||
#if ENABLED(PIDTEMP)
|
||||
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
|
||||
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
|
||||
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
|
||||
// Set/get with gcode: M301 E[extruder number, 0-2]
|
||||
// Set/get with G-code: M301 E[extruder number, 0-2]
|
||||
|
||||
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
||||
// Specify up to one value per hotend here, according to your setup.
|
||||
@@ -604,7 +656,49 @@
|
||||
#define DEFAULT_Ki 1.08
|
||||
#define DEFAULT_Kd 114.00
|
||||
#endif
|
||||
#endif // PIDTEMP
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Model Predictive Control for hotend
|
||||
*
|
||||
* Use a physical model of the hotend to control temperature. When configured correctly
|
||||
* this gives better responsiveness and stability than PID and it also removes the need
|
||||
* for PID_EXTRUSION_SCALING and PID_FAN_SCALING. Use M306 to autotune the model.
|
||||
*/
|
||||
#if ENABLED(MPCTEMP)
|
||||
//#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash)
|
||||
//#define MPC_AUTOTUNE_MENU // Add MPC auto-tuning to the "Advanced Settings" menu. (~350 bytes of flash)
|
||||
|
||||
#define MPC_MAX BANG_MAX // (0..255) Current to nozzle while MPC is active.
|
||||
#define MPC_HEATER_POWER { 40.0f } // (W) Heat cartridge powers.
|
||||
|
||||
#define MPC_INCLUDE_FAN // Model the fan speed?
|
||||
|
||||
// Measured physical constants from M306
|
||||
#define MPC_BLOCK_HEAT_CAPACITY { 16.7f } // (J/K) Heat block heat capacities.
|
||||
#define MPC_SENSOR_RESPONSIVENESS { 0.22f } // (K/s per ∆K) Rate of change of sensor temperature from heat block.
|
||||
#define MPC_AMBIENT_XFER_COEFF { 0.068f } // (W/K) Heat transfer coefficients from heat block to room air with fan off.
|
||||
#if ENABLED(MPC_INCLUDE_FAN)
|
||||
#define MPC_AMBIENT_XFER_COEFF_FAN255 { 0.097f } // (W/K) Heat transfer coefficients from heat block to room air with fan on full.
|
||||
#endif
|
||||
|
||||
// For one fan and multiple hotends MPC needs to know how to apply the fan cooling effect.
|
||||
#if ENABLED(MPC_INCLUDE_FAN)
|
||||
//#define MPC_FAN_0_ALL_HOTENDS
|
||||
//#define MPC_FAN_0_ACTIVE_HOTEND
|
||||
#endif
|
||||
|
||||
#define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA).
|
||||
//#define FILAMENT_HEAT_CAPACITY_PERMM { 3.6e-3f } // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG).
|
||||
|
||||
// Advanced options
|
||||
#define MPC_SMOOTHING_FACTOR 0.5f // (0.0...1.0) Noisy temperature sensors may need a lower value for stabilization.
|
||||
#define MPC_MIN_AMBIENT_CHANGE 1.0f // (K/s) Modeled ambient temperature rate of change, when correcting model inaccuracies.
|
||||
#define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced.
|
||||
|
||||
#define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center at first layer height.
|
||||
#define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position.
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
//====================== PID > Bed Temperature Control ======================
|
||||
@@ -698,6 +792,9 @@
|
||||
//#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
|
||||
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
||||
// is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
|
||||
|
||||
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash)
|
||||
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
|
||||
#endif
|
||||
|
||||
// @section extruder
|
||||
@@ -783,12 +880,18 @@
|
||||
//#define USE_IMIN_PLUG
|
||||
//#define USE_JMIN_PLUG
|
||||
//#define USE_KMIN_PLUG
|
||||
//#define USE_UMIN_PLUG
|
||||
//#define USE_VMIN_PLUG
|
||||
//#define USE_WMIN_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
|
||||
//#define USE_UMAX_PLUG
|
||||
//#define USE_VMAX_PLUG
|
||||
//#define USE_WMAX_PLUG
|
||||
|
||||
// Enable pullup for all endstops to prevent a floating state
|
||||
#define ENDSTOPPULLUPS
|
||||
@@ -800,12 +903,18 @@
|
||||
//#define ENDSTOPPULLUP_IMIN
|
||||
//#define ENDSTOPPULLUP_JMIN
|
||||
//#define ENDSTOPPULLUP_KMIN
|
||||
//#define ENDSTOPPULLUP_UMIN
|
||||
//#define ENDSTOPPULLUP_VMIN
|
||||
//#define ENDSTOPPULLUP_WMIN
|
||||
//#define ENDSTOPPULLUP_XMAX
|
||||
//#define ENDSTOPPULLUP_YMAX
|
||||
//#define ENDSTOPPULLUP_ZMAX
|
||||
//#define ENDSTOPPULLUP_IMAX
|
||||
//#define ENDSTOPPULLUP_JMAX
|
||||
//#define ENDSTOPPULLUP_KMAX
|
||||
//#define ENDSTOPPULLUP_UMAX
|
||||
//#define ENDSTOPPULLUP_VMAX
|
||||
//#define ENDSTOPPULLUP_WMAX
|
||||
//#define ENDSTOPPULLUP_ZMIN_PROBE
|
||||
#endif
|
||||
|
||||
@@ -819,12 +928,18 @@
|
||||
//#define ENDSTOPPULLDOWN_IMIN
|
||||
//#define ENDSTOPPULLDOWN_JMIN
|
||||
//#define ENDSTOPPULLDOWN_KMIN
|
||||
//#define ENDSTOPPULLDOWN_UMIN
|
||||
//#define ENDSTOPPULLDOWN_VMIN
|
||||
//#define ENDSTOPPULLDOWN_WMIN
|
||||
//#define ENDSTOPPULLDOWN_XMAX
|
||||
//#define ENDSTOPPULLDOWN_YMAX
|
||||
//#define ENDSTOPPULLDOWN_ZMAX
|
||||
//#define ENDSTOPPULLDOWN_IMAX
|
||||
//#define ENDSTOPPULLDOWN_JMAX
|
||||
//#define ENDSTOPPULLDOWN_KMAX
|
||||
//#define ENDSTOPPULLDOWN_UMAX
|
||||
//#define ENDSTOPPULLDOWN_VMAX
|
||||
//#define ENDSTOPPULLDOWN_WMAX
|
||||
//#define ENDSTOPPULLDOWN_ZMIN_PROBE
|
||||
#endif
|
||||
|
||||
@@ -835,52 +950,20 @@
|
||||
#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 U_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
|
||||
#define V_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
|
||||
#define W_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 U_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
|
||||
#define V_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
|
||||
#define W_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.
|
||||
|
||||
/**
|
||||
* Stepper Drivers
|
||||
*
|
||||
* These settings allow Marlin to tune stepper driver timing and enable advanced options for
|
||||
* stepper drivers that support them. You may also override timing options in Configuration_adv.h.
|
||||
*
|
||||
* A4988 is assumed for unspecified drivers.
|
||||
*
|
||||
* Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
|
||||
*
|
||||
* Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01,
|
||||
* TB6560, TB6600, TMC2100,
|
||||
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
|
||||
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
|
||||
* TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE,
|
||||
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE
|
||||
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'L6470', 'L6474', 'POWERSTEP01', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC26X', 'TMC26X_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
|
||||
*/
|
||||
#define X_DRIVER_TYPE A4988
|
||||
#define Y_DRIVER_TYPE A4988
|
||||
#define Z_DRIVER_TYPE A4988
|
||||
//#define X2_DRIVER_TYPE A4988
|
||||
//#define Y2_DRIVER_TYPE A4988
|
||||
//#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 A4988
|
||||
//#define E1_DRIVER_TYPE A4988
|
||||
//#define E2_DRIVER_TYPE A4988
|
||||
//#define E3_DRIVER_TYPE A4988
|
||||
//#define E4_DRIVER_TYPE A4988
|
||||
//#define E5_DRIVER_TYPE A4988
|
||||
//#define E6_DRIVER_TYPE A4988
|
||||
//#define E7_DRIVER_TYPE A4988
|
||||
|
||||
// Enable this feature if all enabled endstop pins are interrupt-capable.
|
||||
// This will remove the need to poll the interrupt pins, saving many CPU cycles.
|
||||
//#define ENDSTOP_INTERRUPTS_FEATURE
|
||||
@@ -923,16 +1006,16 @@
|
||||
//#define DISTINCT_E_FACTORS
|
||||
|
||||
/**
|
||||
* Default Axis Steps Per Unit (steps/mm)
|
||||
* Default Axis Steps Per Unit (linear=steps/mm, rotational=steps/°)
|
||||
* Override with M92
|
||||
* X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]]
|
||||
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
|
||||
*/
|
||||
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 }
|
||||
|
||||
/**
|
||||
* Default Max Feed Rate (mm/s)
|
||||
* Default Max Feed Rate (linear=mm/s, rotational=°/s)
|
||||
* Override with M203
|
||||
* X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]]
|
||||
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
|
||||
*/
|
||||
#define DEFAULT_MAX_FEEDRATE { 300, 300, 5, 25 }
|
||||
|
||||
@@ -942,10 +1025,10 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default Max Acceleration (change/s) change = mm/s
|
||||
* Default Max Acceleration (speed change with time) (linear=mm/(s^2), rotational=°/(s^2))
|
||||
* (Maximum start speed for accelerated moves)
|
||||
* Override with M201
|
||||
* X, Y, Z [, I [, J [, K]]], E0 [, E1[, E2...]]
|
||||
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
|
||||
*/
|
||||
#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 }
|
||||
|
||||
@@ -955,7 +1038,7 @@
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default Acceleration (change/s) change = mm/s
|
||||
* Default Acceleration (speed change with time) (linear=mm/(s^2), rotational=°/(s^2))
|
||||
* Override with M204
|
||||
*
|
||||
* M204 P Acceleration
|
||||
@@ -968,7 +1051,7 @@
|
||||
|
||||
/**
|
||||
* Default Jerk limits (mm/s)
|
||||
* Override with M205 X Y Z E
|
||||
* Override with M205 X Y Z . . . E
|
||||
*
|
||||
* "Jerk" specifies the minimum speed change that requires acceleration.
|
||||
* When changing speed and direction, if the difference is less than the
|
||||
@@ -982,6 +1065,9 @@
|
||||
//#define DEFAULT_IJERK 0.3
|
||||
//#define DEFAULT_JJERK 0.3
|
||||
//#define DEFAULT_KJERK 0.3
|
||||
//#define DEFAULT_UJERK 0.3
|
||||
//#define DEFAULT_VJERK 0.3
|
||||
//#define DEFAULT_WJERK 0.3
|
||||
|
||||
//#define TRAVEL_EXTRA_XYJERK 0.0 // Additional jerk allowance for all travel moves
|
||||
|
||||
@@ -1089,6 +1175,17 @@
|
||||
*/
|
||||
//#define BLTOUCH
|
||||
|
||||
/**
|
||||
* MagLev V4 probe by MDD
|
||||
*
|
||||
* This probe is deployed and activated by powering a built-in electromagnet.
|
||||
*/
|
||||
//#define MAGLEV4
|
||||
#if ENABLED(MAGLEV4)
|
||||
//#define MAGLEV_TRIGGER_PIN 11 // Set to the connected digital output
|
||||
#define MAGLEV_TRIGGER_DELAY 15 // Changing this risks overheating the coil
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Touch-MI Probe by hotends.fr
|
||||
*
|
||||
@@ -1309,6 +1406,9 @@
|
||||
//#define I_ENABLE_ON 0
|
||||
//#define J_ENABLE_ON 0
|
||||
//#define K_ENABLE_ON 0
|
||||
//#define U_ENABLE_ON 0
|
||||
//#define V_ENABLE_ON 0
|
||||
//#define W_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!
|
||||
@@ -1318,6 +1418,9 @@
|
||||
//#define DISABLE_I false
|
||||
//#define DISABLE_J false
|
||||
//#define DISABLE_K false
|
||||
//#define DISABLE_U false
|
||||
//#define DISABLE_V false
|
||||
//#define DISABLE_W false
|
||||
|
||||
// Turn off the display blinking that warns about possible accuracy reduction
|
||||
//#define DISABLE_REDUCED_ACCURACY_WARNING
|
||||
@@ -1336,6 +1439,9 @@
|
||||
//#define INVERT_I_DIR false
|
||||
//#define INVERT_J_DIR false
|
||||
//#define INVERT_K_DIR false
|
||||
//#define INVERT_U_DIR false
|
||||
//#define INVERT_V_DIR false
|
||||
//#define INVERT_W_DIR false
|
||||
|
||||
// @section extruder
|
||||
|
||||
@@ -1374,6 +1480,9 @@
|
||||
//#define I_HOME_DIR -1
|
||||
//#define J_HOME_DIR -1
|
||||
//#define K_HOME_DIR -1
|
||||
//#define U_HOME_DIR -1
|
||||
//#define V_HOME_DIR -1
|
||||
//#define W_HOME_DIR -1
|
||||
|
||||
// @section machine
|
||||
|
||||
@@ -1381,7 +1490,7 @@
|
||||
#define X_BED_SIZE 200
|
||||
#define Y_BED_SIZE 200
|
||||
|
||||
// Travel limits (mm) after homing, corresponding to endstop positions.
|
||||
// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions.
|
||||
#define X_MIN_POS 0
|
||||
#define Y_MIN_POS 0
|
||||
#define Z_MIN_POS 0
|
||||
@@ -1394,6 +1503,12 @@
|
||||
//#define J_MAX_POS 50
|
||||
//#define K_MIN_POS 0
|
||||
//#define K_MAX_POS 50
|
||||
//#define U_MIN_POS 0
|
||||
//#define U_MAX_POS 50
|
||||
//#define V_MIN_POS 0
|
||||
//#define V_MAX_POS 50
|
||||
//#define W_MIN_POS 0
|
||||
//#define W_MAX_POS 50
|
||||
|
||||
/**
|
||||
* Software Endstops
|
||||
@@ -1413,6 +1528,9 @@
|
||||
#define MIN_SOFTWARE_ENDSTOP_I
|
||||
#define MIN_SOFTWARE_ENDSTOP_J
|
||||
#define MIN_SOFTWARE_ENDSTOP_K
|
||||
#define MIN_SOFTWARE_ENDSTOP_U
|
||||
#define MIN_SOFTWARE_ENDSTOP_V
|
||||
#define MIN_SOFTWARE_ENDSTOP_W
|
||||
#endif
|
||||
|
||||
// Max software endstops constrain movement within maximum coordinate bounds
|
||||
@@ -1424,6 +1542,9 @@
|
||||
#define MAX_SOFTWARE_ENDSTOP_I
|
||||
#define MAX_SOFTWARE_ENDSTOP_J
|
||||
#define MAX_SOFTWARE_ENDSTOP_K
|
||||
#define MAX_SOFTWARE_ENDSTOP_U
|
||||
#define MAX_SOFTWARE_ENDSTOP_V
|
||||
#define MAX_SOFTWARE_ENDSTOP_W
|
||||
#endif
|
||||
|
||||
#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
|
||||
@@ -1685,18 +1806,18 @@
|
||||
#endif
|
||||
|
||||
// Add a menu item to move between bed corners for manual bed adjustment
|
||||
//#define LEVEL_BED_CORNERS
|
||||
//#define LCD_BED_TRAMMING
|
||||
|
||||
#if ENABLED(LEVEL_BED_CORNERS)
|
||||
#define LEVEL_CORNERS_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
|
||||
#define LEVEL_CORNERS_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
|
||||
#define LEVEL_CORNERS_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
|
||||
//#define LEVEL_CENTER_TOO // Move to the center after the last corner
|
||||
//#define LEVEL_CORNERS_USE_PROBE
|
||||
#if ENABLED(LEVEL_CORNERS_USE_PROBE)
|
||||
#define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
|
||||
#define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
|
||||
//#define LEVEL_CORNERS_AUDIO_FEEDBACK
|
||||
#if ENABLED(LCD_BED_TRAMMING)
|
||||
#define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
|
||||
#define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
|
||||
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
|
||||
//#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
|
||||
//#define BED_TRAMMING_USE_PROBE
|
||||
#if ENABLED(BED_TRAMMING_USE_PROBE)
|
||||
#define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm)
|
||||
#define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
|
||||
//#define BED_TRAMMING_AUDIO_FEEDBACK
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -1716,7 +1837,7 @@
|
||||
* | 1 2 | | 1 4 | | 1 2 | | 2 |
|
||||
* LF --------- RF LF --------- RF LF --------- RF LF --------- RF
|
||||
*/
|
||||
#define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, RB, LB }
|
||||
#define BED_TRAMMING_LEVELING_ORDER { LF, RF, RB, LB }
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -1738,6 +1859,9 @@
|
||||
//#define MANUAL_I_HOME_POS 0
|
||||
//#define MANUAL_J_HOME_POS 0
|
||||
//#define MANUAL_K_HOME_POS 0
|
||||
//#define MANUAL_U_HOME_POS 0
|
||||
//#define MANUAL_V_HOME_POS 0
|
||||
//#define MANUAL_W_HOME_POS 0
|
||||
|
||||
/**
|
||||
* Use "Z Safe Homing" to avoid homing with a Z probe outside the bed area.
|
||||
@@ -1753,7 +1877,7 @@
|
||||
#define Z_SAFE_HOMING_Y_POINT Y_CENTER // Y point for Z homing
|
||||
#endif
|
||||
|
||||
// Homing speeds (mm/min)
|
||||
// Homing speeds (linear=mm/min, rotational=°/min)
|
||||
#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) }
|
||||
|
||||
// Validate that endstops are triggered on homing moves
|
||||
@@ -1832,7 +1956,7 @@
|
||||
* M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.)
|
||||
*/
|
||||
//#define EEPROM_SETTINGS // Persistent storage with M500 and M501
|
||||
//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release!
|
||||
//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release!
|
||||
#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)
|
||||
@@ -1863,7 +1987,7 @@
|
||||
// @section temperature
|
||||
|
||||
//
|
||||
// Preheat Constants - Up to 5 are supported without changes
|
||||
// Preheat Constants - Up to 6 are supported without changes
|
||||
//
|
||||
#define PREHEAT_1_LABEL "PLA"
|
||||
#define PREHEAT_1_TEMP_HOTEND 180
|
||||
@@ -1893,8 +2017,7 @@
|
||||
#if ENABLED(NOZZLE_PARK_FEATURE)
|
||||
// Specify a park position as { X, Y, Z_raise }
|
||||
#define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
|
||||
//#define NOZZLE_PARK_X_ONLY // X move only is required to park
|
||||
//#define NOZZLE_PARK_Y_ONLY // Y move only is required to park
|
||||
#define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X
|
||||
#define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance
|
||||
#define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis)
|
||||
#define NOZZLE_PARK_Z_FEEDRATE 5 // (mm/s) Z axis feedrate (not used for delta printers)
|
||||
@@ -2564,38 +2687,38 @@
|
||||
//========================== Extensible UI Displays ===========================
|
||||
//=============================================================================
|
||||
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/**
|
||||
* 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
|
||||
@@ -2609,9 +2732,6 @@
|
||||
// Touch-screen LCD for Malyan M200/M300 printers
|
||||
//
|
||||
//#define MALYAN_LCD
|
||||
#if ENABLED(MALYAN_LCD)
|
||||
#define LCD_SERIAL_PORT 1 // Default is 1 for Malyan M200
|
||||
#endif
|
||||
|
||||
//
|
||||
// Touch UI for FTDI EVE (FT800/FT810) displays
|
||||
@@ -2625,7 +2745,6 @@
|
||||
//#define ANYCUBIC_LCD_I3MEGA
|
||||
//#define ANYCUBIC_LCD_CHIRON
|
||||
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
|
||||
#define LCD_SERIAL_PORT 3 // Default is 3 for Anycubic
|
||||
//#define ANYCUBIC_LCD_DEBUG
|
||||
#endif
|
||||
|
||||
@@ -2633,9 +2752,6 @@
|
||||
// 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.
|
||||
@@ -2787,7 +2903,7 @@
|
||||
// Ender-3 v2 OEM display. A DWIN display with Rotary Encoder.
|
||||
//
|
||||
//#define DWIN_CREALITY_LCD // Creality UI
|
||||
//#define DWIN_CREALITY_LCD_ENHANCED // Enhanced UI
|
||||
//#define DWIN_LCD_PROUI // Pro UI by MRiscoC
|
||||
//#define DWIN_CREALITY_LCD_JYERSUI // Jyers UI by Jacob Myers
|
||||
//#define DWIN_MARLINUI_PORTRAIT // MarlinUI (portrait orientation)
|
||||
//#define DWIN_MARLINUI_LANDSCAPE // MarlinUI (landscape orientation)
|
||||
@@ -2800,7 +2916,7 @@
|
||||
#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_IDLE_SLEEP 300 // (s) Turn off the TFT backlight if set (5mn)
|
||||
|
||||
#define TOUCH_SCREEN_CALIBRATION
|
||||
|
||||
@@ -2910,30 +3026,31 @@
|
||||
// Support for Adafruit NeoPixel LED driver
|
||||
//#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 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.)
|
||||
#define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
|
||||
#define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255)
|
||||
//#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup
|
||||
#define NEOPIXEL_TYPE NEO_GRBW // NEO_GRBW, NEO_RGBW, NEO_GRB, NEO_RBG, etc.
|
||||
// See https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.h
|
||||
//#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.)
|
||||
#define NEOPIXEL_IS_SEQUENTIAL // Sequential display for temperature change - LED by LED. Disable to change all LEDs at once.
|
||||
#define NEOPIXEL_BRIGHTNESS 127 // Initial brightness (0-255)
|
||||
//#define NEOPIXEL_STARTUP_TEST // Cycle through colors at startup
|
||||
|
||||
// Support for second Adafruit NeoPixel LED driver controlled with M150 S1 ...
|
||||
//#define NEOPIXEL2_SEPARATE
|
||||
#if ENABLED(NEOPIXEL2_SEPARATE)
|
||||
#define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip
|
||||
#define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255)
|
||||
#define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup
|
||||
#define NEOPIXEL2_PIXELS 15 // Number of LEDs in the second strip
|
||||
#define NEOPIXEL2_BRIGHTNESS 127 // Initial brightness (0-255)
|
||||
#define NEOPIXEL2_STARTUP_TEST // Cycle through colors at startup
|
||||
#else
|
||||
//#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
|
||||
//#define NEOPIXEL2_INSERIES // Default behavior is NeoPixel 2 in parallel
|
||||
#endif
|
||||
|
||||
// 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_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
|
||||
//#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@@ -30,7 +30,7 @@
|
||||
*
|
||||
* Basic settings can be found in Configuration.h
|
||||
*/
|
||||
#define CONFIGURATION_ADV_H_VERSION 02000903
|
||||
#define CONFIGURATION_ADV_H_VERSION 02010000
|
||||
|
||||
//===========================================================================
|
||||
//============================= Thermal Settings ============================
|
||||
@@ -138,24 +138,21 @@
|
||||
#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
|
||||
* Thermocouple Options — for MAX6675 (-2), MAX31855 (-3), and MAX31865 (-5).
|
||||
*/
|
||||
//#define TEMP_SENSOR_FORCE_HW_SPI
|
||||
//#define MAX31865_SENSOR_WIRES_0 2
|
||||
//#define TEMP_SENSOR_FORCE_HW_SPI // Ignore SCK/MOSI/MISO pins; use CS and the default SPI bus.
|
||||
//#define MAX31865_SENSOR_WIRES_0 2 // (2-4) Number of wires for the probe connected to a MAX31865 board.
|
||||
//#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
|
||||
|
||||
//#define MAX31865_50HZ_FILTER // Use a 50Hz filter instead of the default 60Hz.
|
||||
//#define MAX31865_USE_READ_ERROR_DETECTION // Treat value spikes (20°C delta in under 1s) as read errors.
|
||||
|
||||
//#define MAX31865_USE_AUTO_MODE // Read faster and more often than 1-shot; bias voltage always on; slight effect on RTD temperature.
|
||||
//#define MAX31865_MIN_SAMPLING_TIME_MSEC 100 // (ms) 1-shot: minimum read interval. Reduces bias voltage effects by leaving sensor unpowered for longer intervals.
|
||||
//#define MAX31865_IGNORE_INITIAL_FAULTY_READS 10 // Ignore some read faults (keeping the temperature reading) to work around a possible issue (#23439).
|
||||
|
||||
//#define MAX31865_WIRE_OHMS_0 0.95f // For 2-wire, set the wire resistances for more accurate readings.
|
||||
//#define MAX31865_WIRE_OHMS_1 0.0f
|
||||
|
||||
/**
|
||||
* Hephestos 2 24V heated bed upgrade kit.
|
||||
@@ -252,20 +249,6 @@
|
||||
#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
|
||||
@@ -349,6 +332,14 @@
|
||||
#define WATCH_COOLER_TEMP_INCREASE 3 // Degrees Celsius
|
||||
#endif
|
||||
|
||||
#if ANY(THERMAL_PROTECTION_HOTENDS, THERMAL_PROTECTION_BED, THERMAL_PROTECTION_CHAMBER, THERMAL_PROTECTION_COOLER)
|
||||
/**
|
||||
* Thermal Protection Variance Monitor - EXPERIMENTAL.
|
||||
* Kill the machine on a stuck temperature sensor. Disable if you get false positives.
|
||||
*/
|
||||
//#define THERMAL_PROTECTION_VARIANCE_MONITOR // Detect a sensor malfunction preventing temperature updates
|
||||
#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.
|
||||
@@ -567,8 +558,8 @@
|
||||
*
|
||||
* USE_OCR2A_AS_TOP [undefined by default]
|
||||
* Boards that use TIMER2 for PWM have limitations resulting in only a few possible frequencies on TIMER2:
|
||||
* 16MHz MCUs: [62.5KHz, 31.4KHz (default), 7.8KHz, 3.92KHz, 1.95KHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz]
|
||||
* 20MHz MCUs: [78.1KHz, 39.2KHz (default), 9.77KHz, 4.9KHz, 2.44KHz, 1.22KHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz]
|
||||
* 16MHz MCUs: [62.5kHz, 31.4kHz (default), 7.8kHz, 3.92kHz, 1.95kHz, 977Hz, 488Hz, 244Hz, 60Hz, 122Hz, 30Hz]
|
||||
* 20MHz MCUs: [78.1kHz, 39.2kHz (default), 9.77kHz, 4.9kHz, 2.44kHz, 1.22kHz, 610Hz, 305Hz, 153Hz, 76Hz, 38Hz]
|
||||
* A greater range can be achieved by enabling USE_OCR2A_AS_TOP. But note that this option blocks the use of
|
||||
* 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.
|
||||
@@ -615,7 +606,6 @@
|
||||
#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
|
||||
@@ -709,73 +699,6 @@
|
||||
//#define CLOSED_LOOP_MOVE_COMPLETE_PIN -1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Dual Steppers / Dual Endstops
|
||||
*
|
||||
* This section will allow you to use extra E drivers to drive a second motor for X, Y, or Z axes.
|
||||
*
|
||||
* For example, set X_DUAL_STEPPER_DRIVERS setting to use a second motor. If the motors need to
|
||||
* spin in opposite directions set INVERT_X2_VS_X_DIR. If the second motor needs its own endstop
|
||||
* set X_DUAL_ENDSTOPS. This can adjust for "racking." Use X2_USE_ENDSTOP to set the endstop plug
|
||||
* that should be used for the second endstop. Extra endstops will appear in the output of 'M119'.
|
||||
*
|
||||
* Use X_DUAL_ENDSTOP_ADJUSTMENT to adjust for mechanical imperfection. After homing both motors
|
||||
* this offset is applied to the X2 motor. To find the offset home the X axis, and measure the error
|
||||
* in X2. Dual endstop offsets can be set at runtime with 'M666 X<offset> Y<offset> Z<offset>'.
|
||||
*/
|
||||
|
||||
//#define X_DUAL_STEPPER_DRIVERS
|
||||
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
|
||||
//#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_
|
||||
#define X2_ENDSTOP_ADJUSTMENT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//#define Y_DUAL_STEPPER_DRIVERS
|
||||
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
|
||||
//#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_
|
||||
#define Y2_ENDSTOP_ADJUSTMENT 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// For Z set the number of stepper drivers
|
||||
//
|
||||
#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_
|
||||
#define Z2_ENDSTOP_ADJUSTMENT 0
|
||||
#if NUM_Z_STEPPER_DRIVERS >= 3
|
||||
#define Z3_USE_ENDSTOP _YMAX_
|
||||
#define Z3_ENDSTOP_ADJUSTMENT 0
|
||||
#endif
|
||||
#if NUM_Z_STEPPER_DRIVERS >= 4
|
||||
#define Z4_USE_ENDSTOP _ZMAX_
|
||||
#define Z4_ENDSTOP_ADJUSTMENT 0
|
||||
#endif
|
||||
#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
|
||||
*
|
||||
@@ -806,18 +729,17 @@
|
||||
*/
|
||||
//#define DUAL_X_CARRIAGE
|
||||
#if ENABLED(DUAL_X_CARRIAGE)
|
||||
#define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS
|
||||
#define X1_MAX_POS X_BED_SIZE // Set a maximum so the first X-carriage can't hit the parked second X-carriage
|
||||
#define X2_MIN_POS 80 // Set a minimum to ensure the second X-carriage can't hit the parked first X-carriage
|
||||
#define X2_MAX_POS 353 // Set this to the distance between toolheads when both heads are homed
|
||||
#define X2_HOME_DIR 1 // Set to 1. The second X-carriage always homes to the maximum endstop position
|
||||
#define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS.
|
||||
// However: In this mode the HOTEND_OFFSET_X value for the second extruder provides a software
|
||||
// override for X2_HOME_POS. This also allow recalibration of the distance between the two endstops
|
||||
// without modifying the firmware (through the "M218 T1 X???" command).
|
||||
// Remember: you should set the second extruder x-offset to 0 in your slicer.
|
||||
#define X1_MIN_POS X_MIN_POS // Set to X_MIN_POS
|
||||
#define X1_MAX_POS X_BED_SIZE // A max coordinate so the X1 carriage can't hit the parked X2 carriage
|
||||
#define X2_MIN_POS 80 // A min coordinate so the X2 carriage can't hit the parked X1 carriage
|
||||
#define X2_MAX_POS 353 // The max position of the X2 carriage, typically also the home position
|
||||
#define X2_HOME_DIR 1 // Set to 1. The X2 carriage always homes to the max endstop position
|
||||
#define X2_HOME_POS X2_MAX_POS // Default X2 home position. Set to X2_MAX_POS.
|
||||
// NOTE: For Dual X Carriage use M218 T1 Xn to override the X2_HOME_POS.
|
||||
// This allows recalibration of endstops distance without a rebuild.
|
||||
// Remember to set the second extruder's X-offset to 0 in your slicer.
|
||||
|
||||
// This is the default power-up mode which can be later using M605.
|
||||
// This is the default power-up mode which can be changed later using M605 S<mode>.
|
||||
#define DEFAULT_DUAL_X_CARRIAGE_MODE DXC_AUTO_PARK_MODE
|
||||
|
||||
// Default x offset in duplication mode (typically set to half print bed width)
|
||||
@@ -827,6 +749,77 @@
|
||||
//#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Multi-Stepper / Multi-Endstop
|
||||
*
|
||||
* When X2_DRIVER_TYPE is defined, this indicates that the X and X2 motors work in tandem.
|
||||
* The following explanations for X also apply to Y and Z multi-stepper setups.
|
||||
* Endstop offsets may be changed by 'M666 X<offset> Y<offset> Z<offset>' and stored to EEPROM.
|
||||
*
|
||||
* - Enable INVERT_X2_VS_X_DIR if the X2 motor requires an opposite DIR signal from X.
|
||||
*
|
||||
* - Enable X_DUAL_ENDSTOPS if the second motor has its own endstop, with adjustable offset.
|
||||
*
|
||||
* - Extra endstops are included in the output of 'M119'.
|
||||
*
|
||||
* - Set X_DUAL_ENDSTOP_ADJUSTMENT to the known error in the X2 endstop.
|
||||
* Applied to the X2 motor on 'G28' / 'G28 X'.
|
||||
* Get the offset by homing X and measuring the error.
|
||||
* Also set with 'M666 X<offset>' and stored to EEPROM with 'M500'.
|
||||
*
|
||||
* - Use X2_USE_ENDSTOP to set the endstop plug by name. (_XMIN_, _XMAX_, _YMIN_, _YMAX_, _ZMIN_, _ZMAX_)
|
||||
*/
|
||||
#if HAS_X2_STEPPER && DISABLED(DUAL_X_CARRIAGE)
|
||||
//#define INVERT_X2_VS_X_DIR // X2 direction signal is the opposite of X
|
||||
//#define X_DUAL_ENDSTOPS // X2 has its own endstop
|
||||
#if ENABLED(X_DUAL_ENDSTOPS)
|
||||
#define X2_USE_ENDSTOP _XMAX_ // X2 endstop board plug. Don't forget to enable USE_*_PLUG.
|
||||
#define X2_ENDSTOP_ADJUSTMENT 0 // X2 offset relative to X endstop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_DUAL_Y_STEPPERS
|
||||
//#define INVERT_Y2_VS_Y_DIR // Y2 direction signal is the opposite of Y
|
||||
//#define Y_DUAL_ENDSTOPS // Y2 has its own endstop
|
||||
#if ENABLED(Y_DUAL_ENDSTOPS)
|
||||
#define Y2_USE_ENDSTOP _YMAX_ // Y2 endstop board plug. Don't forget to enable USE_*_PLUG.
|
||||
#define Y2_ENDSTOP_ADJUSTMENT 0 // Y2 offset relative to Y endstop
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Multi-Z steppers
|
||||
//
|
||||
#ifdef Z2_DRIVER_TYPE
|
||||
//#define INVERT_Z2_VS_Z_DIR // Z2 direction signal is the opposite of Z
|
||||
|
||||
//#define Z_MULTI_ENDSTOPS // Other Z axes have their own endstops
|
||||
#if ENABLED(Z_MULTI_ENDSTOPS)
|
||||
#define Z2_USE_ENDSTOP _XMAX_ // Z2 endstop board plug. Don't forget to enable USE_*_PLUG.
|
||||
#define Z2_ENDSTOP_ADJUSTMENT 0 // Z2 offset relative to Y endstop
|
||||
#endif
|
||||
#ifdef Z3_DRIVER_TYPE
|
||||
//#define INVERT_Z3_VS_Z_DIR // Z3 direction signal is the opposite of Z
|
||||
#if ENABLED(Z_MULTI_ENDSTOPS)
|
||||
#define Z3_USE_ENDSTOP _YMAX_ // Z3 endstop board plug. Don't forget to enable USE_*_PLUG.
|
||||
#define Z3_ENDSTOP_ADJUSTMENT 0 // Z3 offset relative to Y endstop
|
||||
#endif
|
||||
#endif
|
||||
#ifdef Z4_DRIVER_TYPE
|
||||
//#define INVERT_Z4_VS_Z_DIR // Z4 direction signal is the opposite of Z
|
||||
#if ENABLED(Z_MULTI_ENDSTOPS)
|
||||
#define Z4_USE_ENDSTOP _ZMAX_ // Z4 endstop board plug. Don't forget to enable USE_*_PLUG.
|
||||
#define Z4_ENDSTOP_ADJUSTMENT 0 // Z4 offset relative to Y endstop
|
||||
#endif
|
||||
#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 // E direction signals are opposites
|
||||
#endif
|
||||
|
||||
// Activate a solenoid on the active extruder with M380. Disable all with M381.
|
||||
// Define SOL0_PIN, SOL1_PIN, etc., for each extruder that has a solenoid.
|
||||
//#define EXT_SOLENOID
|
||||
@@ -839,12 +832,12 @@
|
||||
* the position of the toolhead relative to the workspace.
|
||||
*/
|
||||
|
||||
//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (mm) Backoff from endstops before sensorless homing
|
||||
//#define SENSORLESS_BACKOFF_MM { 2, 2, 0 } // (linear=mm, rotational=°) Backoff from endstops before sensorless homing
|
||||
|
||||
#define HOMING_BUMP_MM { 5, 5, 2 } // (mm) Backoff from endstops after first bump
|
||||
#define HOMING_BUMP_MM { 5, 5, 2 } // (linear=mm, rotational=°) Backoff from endstops after first bump
|
||||
#define HOMING_BUMP_DIVISOR { 2, 2, 4 } // Re-Bump Speed Divisor (Divides the Homing Feedrate)
|
||||
|
||||
//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (mm) Backoff from endstops after homing
|
||||
//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing
|
||||
|
||||
//#define QUICK_HOME // If G28 contains XY do a diagonal move first
|
||||
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
|
||||
@@ -958,15 +951,17 @@
|
||||
//#define Z_STEPPERS_ORIENTATION 0
|
||||
#endif
|
||||
|
||||
// Provide Z stepper positions for more rapid convergence in bed alignment.
|
||||
// Requires triple stepper drivers (i.e., set NUM_Z_STEPPER_DRIVERS to 3)
|
||||
//#define Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS
|
||||
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
|
||||
// Define Stepper XY positions for Z1, Z2, Z3 corresponding to
|
||||
// the Z screw positions in the bed carriage.
|
||||
// Define one position per Z stepper in stepper driver order.
|
||||
#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
|
||||
#else
|
||||
/**
|
||||
* Z Stepper positions for more rapid convergence in bed alignment.
|
||||
* Requires 3 or 4 Z steppers.
|
||||
*
|
||||
* Define Stepper XY positions for Z1, Z2, Z3... corresponding to the screw
|
||||
* positions in the bed carriage, with one position per Z stepper in stepper
|
||||
* driver order.
|
||||
*/
|
||||
//#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
|
||||
|
||||
#ifndef Z_STEPPER_ALIGN_STEPPER_XY
|
||||
// Amplification factor. Used to scale the correction step up or down in case
|
||||
// the stepper (spindle) position is farther out than the test point.
|
||||
#define Z_STEPPER_ALIGN_AMP 1.0 // Use a value > 1.0 NOTE: This may cause instability!
|
||||
@@ -1028,6 +1023,9 @@
|
||||
#define INVERT_I_STEP_PIN false
|
||||
#define INVERT_J_STEP_PIN false
|
||||
#define INVERT_K_STEP_PIN false
|
||||
#define INVERT_U_STEP_PIN false
|
||||
#define INVERT_V_STEP_PIN false
|
||||
#define INVERT_W_STEP_PIN false
|
||||
#define INVERT_E_STEP_PIN false
|
||||
|
||||
/**
|
||||
@@ -1042,11 +1040,14 @@
|
||||
#define DISABLE_INACTIVE_I true
|
||||
#define DISABLE_INACTIVE_J true
|
||||
#define DISABLE_INACTIVE_K true
|
||||
#define DISABLE_INACTIVE_U true
|
||||
#define DISABLE_INACTIVE_V true
|
||||
#define DISABLE_INACTIVE_W true
|
||||
#define DISABLE_INACTIVE_E true
|
||||
|
||||
// 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.
|
||||
#define DEFAULT_MINIMUMFEEDRATE 0.0 // (mm/s. °/s for rotational-only moves) Minimum feedrate. Set with M205 S.
|
||||
#define DEFAULT_MINTRAVELFEEDRATE 0.0 // (mm/s. °/s for rotational-only moves) Minimum travel feedrate. Set with M205 T.
|
||||
|
||||
// Minimum time that a segment needs to take as the buffer gets emptied
|
||||
#define DEFAULT_MINSEGMENTTIME 20000 // (µs) Set with M205 B.
|
||||
@@ -1082,7 +1083,7 @@
|
||||
#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) One value for each linear axis
|
||||
#define BACKLASH_DISTANCE_MM { 0, 0, 0 } // (linear=mm, rotational=°) 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
|
||||
@@ -1159,6 +1160,12 @@
|
||||
//#define CALIBRATION_MEASURE_JMAX
|
||||
//#define CALIBRATION_MEASURE_KMIN
|
||||
//#define CALIBRATION_MEASURE_KMAX
|
||||
//#define CALIBRATION_MEASURE_UMIN
|
||||
//#define CALIBRATION_MEASURE_UMAX
|
||||
//#define CALIBRATION_MEASURE_VMIN
|
||||
//#define CALIBRATION_MEASURE_VMAX
|
||||
//#define CALIBRATION_MEASURE_WMIN
|
||||
//#define CALIBRATION_MEASURE_WMAX
|
||||
|
||||
// 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.
|
||||
@@ -1253,7 +1260,7 @@
|
||||
|
||||
// @section lcd
|
||||
|
||||
#if ANY(HAS_LCD_MENU, EXTENSIBLE_UI, HAS_DWIN_E3V2)
|
||||
#if HAS_MANUAL_MOVE_MENU
|
||||
#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
|
||||
@@ -1276,37 +1283,41 @@
|
||||
#define FEEDRATE_CHANGE_BEEP_FREQUENCY 440
|
||||
#endif
|
||||
|
||||
#if HAS_LCD_MENU
|
||||
//
|
||||
// LCD Backlight Timeout
|
||||
//
|
||||
//#define LCD_BACKLIGHT_TIMEOUT 30 // (s) Timeout before turning off the backlight
|
||||
|
||||
#if HAS_BED_PROBE && EITHER(HAS_MARLINUI_MENU, HAS_TFT_LVGL_UI)
|
||||
//#define PROBE_OFFSET_WIZARD // Add a Probe Z Offset calibration option to the LCD menu
|
||||
#if ENABLED(PROBE_OFFSET_WIZARD)
|
||||
/**
|
||||
* Enable to init the Probe Z-Offset when starting the Wizard.
|
||||
* Use a height slightly above the estimated nozzle-to-probe Z offset.
|
||||
* For example, with an offset of -5, consider a starting height of -4.
|
||||
*/
|
||||
//#define PROBE_OFFSET_WIZARD_START_Z -4.0
|
||||
|
||||
// Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
|
||||
//#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if HAS_MARLINUI_MENU
|
||||
|
||||
// Add Probe Z Offset calibration to the Z Probe Offsets menu
|
||||
#if HAS_BED_PROBE
|
||||
//#define PROBE_OFFSET_WIZARD
|
||||
#if ENABLED(PROBE_OFFSET_WIZARD)
|
||||
//
|
||||
// Enable to init the Probe Z-Offset when starting the Wizard.
|
||||
// Use a height slightly above the estimated nozzle-to-probe Z offset.
|
||||
// For example, with an offset of -5, consider a starting height of -4.
|
||||
//
|
||||
//#define PROBE_OFFSET_WIZARD_START_Z -4.0
|
||||
|
||||
// Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
|
||||
//#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
|
||||
#endif
|
||||
|
||||
#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
|
||||
// Add calibration in the Probe Offsets menu to compensate for X-axis twist.
|
||||
//#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
|
||||
#define XATC_Z_OFFSETS { 0, 0, 0 } // Z offsets for X axis sample points
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1319,6 +1330,42 @@
|
||||
// BACK menu items keep the highlight at the top
|
||||
//#define TURBO_BACK_MENU_ITEM
|
||||
|
||||
// Insert a menu for preheating at the top level to allow for quick access
|
||||
//#define PREHEAT_SHORTCUT_MENU_ITEM
|
||||
|
||||
#endif // HAS_MARLINUI_MENU
|
||||
|
||||
#if ANY(HAS_DISPLAY, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
|
||||
//#define SOUND_MENU_ITEM // Add a mute option to the LCD menu
|
||||
#define SOUND_ON_DEFAULT // Buzzer/speaker default enabled state
|
||||
#endif
|
||||
|
||||
#if EITHER(HAS_DISPLAY, DWIN_LCD_PROUI)
|
||||
// The timeout to return to the status screen from sub-menus
|
||||
//#define LCD_TIMEOUT_TO_STATUS 15000 // (ms)
|
||||
|
||||
#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
|
||||
|
||||
// Scroll a longer status message into view
|
||||
//#define STATUS_MESSAGE_SCROLLING
|
||||
|
||||
// Apply a timeout to low-priority status messages
|
||||
//#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds)
|
||||
|
||||
// On the Info Screen, display XY with one decimal place when possible
|
||||
//#define LCD_DECIMAL_SMALL_XY
|
||||
|
||||
// Add an 'M73' G-code to set the current percentage
|
||||
//#define LCD_SET_PROGRESS_MANUALLY
|
||||
|
||||
// Show the E position (filament used) during printing
|
||||
//#define LCD_SHOW_E_TOTAL
|
||||
|
||||
/**
|
||||
* LED Control Menu
|
||||
* Add LED Control to the LCD menu
|
||||
@@ -1345,37 +1392,6 @@
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
#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
|
||||
|
||||
// Scroll a longer status message into view
|
||||
//#define STATUS_MESSAGE_SCROLLING
|
||||
|
||||
// On the Info Screen, display XY with one decimal place when possible
|
||||
//#define LCD_DECIMAL_SMALL_XY
|
||||
|
||||
// Add an 'M73' G-code to set the current percentage
|
||||
//#define LCD_SET_PROGRESS_MANUALLY
|
||||
|
||||
// Show the E position (filament used) during printing
|
||||
//#define LCD_SHOW_E_TOTAL
|
||||
#endif
|
||||
|
||||
// LCD Print Progress options
|
||||
@@ -1522,33 +1538,23 @@
|
||||
// LCD's font must contain the characters. Check your selected LCD language.
|
||||
//#define UTF_FILENAME_SUPPORT
|
||||
|
||||
// This allows hosts to request long names for files and folders with M33
|
||||
//#define LONG_FILENAME_HOST_SUPPORT
|
||||
//#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
|
||||
//#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
|
||||
|
||||
// Enable this option to scroll long filenames in the SD card menu
|
||||
//#define SCROLL_LONG_FILENAMES
|
||||
//#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu
|
||||
|
||||
// Leave the heaters on after Stop Print (not recommended!)
|
||||
//#define SD_ABORT_NO_COOLDOWN
|
||||
//#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!)
|
||||
|
||||
/**
|
||||
* This option allows you to abort SD printing when any endstop is triggered.
|
||||
* This feature must be enabled with "M540 S1" or from the LCD menu.
|
||||
* To have any effect, endstops must be enabled during SD printing.
|
||||
* Abort SD printing when any endstop is triggered.
|
||||
* This feature is enabled with 'M540 S1' or from the LCD menu.
|
||||
* Endstops must be activated for this option to work.
|
||||
*/
|
||||
//#define SD_ABORT_ON_ENDSTOP_HIT
|
||||
|
||||
/**
|
||||
* This option makes it easier to print the same SD Card file again.
|
||||
* On print completion the LCD Menu will open with the file selected.
|
||||
* You can just click to start the print, or navigate elsewhere.
|
||||
*/
|
||||
//#define SD_REPRINT_LAST_SELECTED_FILE
|
||||
//#define SD_REPRINT_LAST_SELECTED_FILE // On print completion open the LCD Menu and select the same file
|
||||
|
||||
/**
|
||||
* Auto-report SdCard status with M27 S<seconds>
|
||||
*/
|
||||
//#define AUTO_REPORT_SD_STATUS
|
||||
//#define AUTO_REPORT_SD_STATUS // Auto-report media status with 'M27 S<seconds>'
|
||||
|
||||
/**
|
||||
* Support for USB thumb drives using an Arduino USB Host Shield or
|
||||
@@ -1617,6 +1623,11 @@
|
||||
// Add an optimized binary file transfer mode, initiated with 'M28 B1'
|
||||
//#define BINARY_FILE_TRANSFER
|
||||
|
||||
#if ENABLED(BINARY_FILE_TRANSFER)
|
||||
// Include extra facilities (e.g., 'M20 F') supporting firmware upload via BINARY_FILE_TRANSFER
|
||||
//#define CUSTOM_FIRMWARE_UPLOAD
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Set this option to one of the following (or the board's defaults apply):
|
||||
*
|
||||
@@ -1631,7 +1642,10 @@
|
||||
// Enable if SD detect is rendered useless (e.g., by using an SD extender)
|
||||
//#define NO_SD_DETECT
|
||||
|
||||
// Multiple volume support - EXPERIMENTAL.
|
||||
/**
|
||||
* Multiple volume support - EXPERIMENTAL.
|
||||
* Adds 'M21 Pm' / 'M21 S' / 'M21 U' to mount SD Card / USB Drive.
|
||||
*/
|
||||
//#define MULTI_VOLUME
|
||||
#if ENABLED(MULTI_VOLUME)
|
||||
#define VOLUME_SD_ONBOARD
|
||||
@@ -1665,14 +1679,25 @@
|
||||
//#define XYZ_NO_FRAME
|
||||
#define XYZ_HOLLOW_FRAME
|
||||
|
||||
// A bigger font is available for edit items. Costs 3120 bytes of PROGMEM.
|
||||
// A bigger font is available for edit items. Costs 3120 bytes of flash.
|
||||
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
|
||||
//#define USE_BIG_EDIT_FONT
|
||||
|
||||
// A smaller font may be used on the Info Screen. Costs 2434 bytes of PROGMEM.
|
||||
// A smaller font may be used on the Info Screen. Costs 2434 bytes of flash.
|
||||
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
|
||||
//#define USE_SMALL_INFOFONT
|
||||
|
||||
/**
|
||||
* Graphical Display Sleep
|
||||
*
|
||||
* The U8G library provides sleep / wake functions for SH1106, SSD1306,
|
||||
* SSD1309, and some other DOGM displays.
|
||||
* Enable this option to save energy and prevent OLED pixel burn-in.
|
||||
* Adds the menu item Configuration > LCD Timeout (m) to set a wait period
|
||||
* from 0 (disabled) to 99 minutes.
|
||||
*/
|
||||
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen
|
||||
|
||||
/**
|
||||
* ST7920-based LCDs can emulate a 16 x 4 character display using
|
||||
* the ST7920 character-generator for very fast screen updates.
|
||||
@@ -1714,7 +1739,7 @@
|
||||
//#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_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 flash.
|
||||
|
||||
// Frivolous Game Options
|
||||
//#define MARLIN_BRICKOUT
|
||||
@@ -1739,7 +1764,6 @@
|
||||
// Additional options for DGUS / DWIN displays
|
||||
//
|
||||
#if HAS_DGUS_LCD
|
||||
#define LCD_SERIAL_PORT 3
|
||||
#define LCD_BAUDRATE 115200
|
||||
|
||||
#define DGUS_RX_BUFFER_SIZE 128
|
||||
@@ -2000,6 +2024,21 @@
|
||||
|
||||
// @section leveling
|
||||
|
||||
/**
|
||||
* Use Safe Bed Leveling coordinates to move axes to a useful position before bed probing.
|
||||
* For example, after homing a rotational axis the Z probe might not be perpendicular to the bed.
|
||||
* Choose values the orient the bed horizontally and the Z-probe vertically.
|
||||
*/
|
||||
//#define SAFE_BED_LEVELING_START_X 0.0
|
||||
//#define SAFE_BED_LEVELING_START_Y 0.0
|
||||
//#define SAFE_BED_LEVELING_START_Z 0.0
|
||||
//#define SAFE_BED_LEVELING_START_I 0.0
|
||||
//#define SAFE_BED_LEVELING_START_J 0.0
|
||||
//#define SAFE_BED_LEVELING_START_K 0.0
|
||||
//#define SAFE_BED_LEVELING_START_U 0.0
|
||||
//#define SAFE_BED_LEVELING_START_V 0.0
|
||||
//#define SAFE_BED_LEVELING_START_W 0.0
|
||||
|
||||
/**
|
||||
* Points to probe for all 3-point Leveling procedures.
|
||||
* Override if the automatically selected points are inadequate.
|
||||
@@ -2260,7 +2299,7 @@
|
||||
#define BUFSIZE 4
|
||||
|
||||
// Transmission to Host Buffer Size
|
||||
// To save 386 bytes of PROGMEM (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0.
|
||||
// To save 386 bytes of flash (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0.
|
||||
// To buffer a simple "ok" you need 4 bytes.
|
||||
// For ADVANCED_OK (M105) you need 32 bytes.
|
||||
// For debug-echo: 128 bytes for the optimal speed.
|
||||
@@ -2342,6 +2381,15 @@
|
||||
// For serial echo, the number of digits after the decimal point
|
||||
//#define SERIAL_FLOAT_PRECISION 4
|
||||
|
||||
/**
|
||||
* Set the number of proportional font spaces required to fill up a typical character space.
|
||||
* This can help to better align the output of commands like `G29 O` Mesh Output.
|
||||
*
|
||||
* For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0.
|
||||
* Otherwise, adjust according to your client and font.
|
||||
*/
|
||||
#define PROPORTIONAL_FONT_RATIO 1.0
|
||||
|
||||
// @section extras
|
||||
|
||||
/**
|
||||
@@ -2402,7 +2450,7 @@
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* stepper motor (e.g., I axis 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
|
||||
@@ -2422,7 +2470,7 @@
|
||||
#if ENABLED(TOOLCHANGE_FILAMENT_SWAP)
|
||||
// Load / Unload
|
||||
#define TOOLCHANGE_FS_LENGTH 12 // (mm) Load / Unload length
|
||||
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart, fine tune by LCD/Gcode)
|
||||
#define TOOLCHANGE_FS_EXTRA_RESUME_LENGTH 0 // (mm) Extra length for better restart. Adjust with LCD or M217 B.
|
||||
#define TOOLCHANGE_FS_RETRACT_SPEED (50*60) // (mm/min) (Unloading)
|
||||
#define TOOLCHANGE_FS_UNRETRACT_SPEED (25*60) // (mm/min) (On SINGLENOZZLE or Bowden loading must be slowed down)
|
||||
|
||||
@@ -2436,12 +2484,16 @@
|
||||
#define TOOLCHANGE_FS_FAN_SPEED 255 // 0-255
|
||||
#define TOOLCHANGE_FS_FAN_TIME 10 // (seconds)
|
||||
|
||||
// Swap uninitialized extruder with TOOLCHANGE_FS_PRIME_SPEED for all lengths (recover + prime)
|
||||
// (May break filament if not retracted beforehand.)
|
||||
//#define TOOLCHANGE_FS_INIT_BEFORE_SWAP
|
||||
// Use TOOLCHANGE_FS_PRIME_SPEED feedrate the first time each extruder is primed
|
||||
//#define TOOLCHANGE_FS_SLOW_FIRST_PRIME
|
||||
|
||||
// Prime on the first T0 (If other, TOOLCHANGE_FS_INIT_BEFORE_SWAP applied)
|
||||
// Enable it (M217 V[0/1]) before printing, to avoid unwanted priming on host connect
|
||||
/**
|
||||
* Prime T0 the first time T0 is sent to the printer:
|
||||
* [ Power-On -> T0 { Activate & Prime T0 } -> T1 { Retract T0, Activate & Prime T1 } ]
|
||||
* If disabled, no priming on T0 until switching back to T0 from another extruder:
|
||||
* [ Power-On -> T0 { T0 Activated } -> T1 { Activate & Prime T1 } -> T0 { Retract T1, Activate & Prime T0 } ]
|
||||
* Enable with M217 V1 before printing to avoid unwanted priming on host connect.
|
||||
*/
|
||||
//#define TOOLCHANGE_FS_PRIME_FIRST_USED
|
||||
|
||||
/**
|
||||
@@ -2605,6 +2657,24 @@
|
||||
#define K_MICROSTEPS 16
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_U(TMC26X)
|
||||
#define U_MAX_CURRENT 1000
|
||||
#define U_SENSE_RESISTOR 91
|
||||
#define U_MICROSTEPS 16
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_V(TMC26X)
|
||||
#define V_MAX_CURRENT 1000
|
||||
#define V_SENSE_RESISTOR 91
|
||||
#define V_MICROSTEPS 16
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_W(TMC26X)
|
||||
#define W_MAX_CURRENT 1000
|
||||
#define W_SENSE_RESISTOR 91
|
||||
#define W_MICROSTEPS 16
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_E0(TMC26X)
|
||||
#define E0_MAX_CURRENT 1000
|
||||
#define E0_SENSE_RESISTOR 91
|
||||
@@ -2793,6 +2863,36 @@
|
||||
//#define K_HOLD_MULTIPLIER 0.5
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(U)
|
||||
#define U_CURRENT 800
|
||||
#define U_CURRENT_HOME U_CURRENT
|
||||
#define U_MICROSTEPS 8
|
||||
#define U_RSENSE 0.11
|
||||
#define U_CHAIN_POS -1
|
||||
//#define U_INTERPOLATE true
|
||||
//#define U_HOLD_MULTIPLIER 0.5
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(V)
|
||||
#define V_CURRENT 800
|
||||
#define V_CURRENT_HOME V_CURRENT
|
||||
#define V_MICROSTEPS 8
|
||||
#define V_RSENSE 0.11
|
||||
#define V_CHAIN_POS -1
|
||||
//#define V_INTERPOLATE true
|
||||
//#define V_HOLD_MULTIPLIER 0.5
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(W)
|
||||
#define W_CURRENT 800
|
||||
#define W_CURRENT_HOME W_CURRENT
|
||||
#define W_MICROSTEPS 8
|
||||
#define W_RSENSE 0.11
|
||||
#define W_CHAIN_POS -1
|
||||
//#define W_INTERPOLATE true
|
||||
//#define W_HOLD_MULTIPLIER 0.5
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC(E0)
|
||||
#define E0_CURRENT 800
|
||||
#define E0_MICROSTEPS 16
|
||||
@@ -2880,6 +2980,9 @@
|
||||
//#define I_CS_PIN -1
|
||||
//#define J_CS_PIN -1
|
||||
//#define K_CS_PIN -1
|
||||
//#define U_CS_PIN -1
|
||||
//#define V_CS_PIN -1
|
||||
//#define W_CS_PIN -1
|
||||
//#define E0_CS_PIN -1
|
||||
//#define E1_CS_PIN -1
|
||||
//#define E2_CS_PIN -1
|
||||
@@ -2922,6 +3025,9 @@
|
||||
//#define I_SLAVE_ADDRESS 0
|
||||
//#define J_SLAVE_ADDRESS 0
|
||||
//#define K_SLAVE_ADDRESS 0
|
||||
//#define U_SLAVE_ADDRESS 0
|
||||
//#define V_SLAVE_ADDRESS 0
|
||||
//#define W_SLAVE_ADDRESS 0
|
||||
//#define E0_SLAVE_ADDRESS 0
|
||||
//#define E1_SLAVE_ADDRESS 0
|
||||
//#define E2_SLAVE_ADDRESS 0
|
||||
@@ -2949,6 +3055,9 @@
|
||||
#define STEALTHCHOP_I
|
||||
#define STEALTHCHOP_J
|
||||
#define STEALTHCHOP_K
|
||||
#define STEALTHCHOP_U
|
||||
#define STEALTHCHOP_V
|
||||
#define STEALTHCHOP_W
|
||||
#define STEALTHCHOP_E
|
||||
|
||||
/**
|
||||
@@ -2975,6 +3084,12 @@
|
||||
//#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 // For I Axis
|
||||
//#define CHOPPER_TIMING_J CHOPPER_TIMING // For J Axis
|
||||
//#define CHOPPER_TIMING_K CHOPPER_TIMING // For K Axis
|
||||
//#define CHOPPER_TIMING_U CHOPPER_TIMING // For U Axis
|
||||
//#define CHOPPER_TIMING_V CHOPPER_TIMING // For V Axis
|
||||
//#define CHOPPER_TIMING_W CHOPPER_TIMING // For W Axis
|
||||
//#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below)
|
||||
//#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
|
||||
//#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E
|
||||
@@ -3020,9 +3135,12 @@
|
||||
#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 I_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s]
|
||||
#define J_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s]
|
||||
#define K_HYBRID_THRESHOLD 3 // [linear=mm/s, rotational=°/s]
|
||||
#define U_HYBRID_THRESHOLD 3 // [mm/s]
|
||||
#define V_HYBRID_THRESHOLD 3
|
||||
#define W_HYBRID_THRESHOLD 3
|
||||
#define E0_HYBRID_THRESHOLD 30
|
||||
#define E1_HYBRID_THRESHOLD 30
|
||||
#define E2_HYBRID_THRESHOLD 30
|
||||
@@ -3072,6 +3190,9 @@
|
||||
//#define I_STALL_SENSITIVITY 8
|
||||
//#define J_STALL_SENSITIVITY 8
|
||||
//#define K_STALL_SENSITIVITY 8
|
||||
//#define U_STALL_SENSITIVITY 8
|
||||
//#define V_STALL_SENSITIVITY 8
|
||||
//#define W_STALL_SENSITIVITY 8
|
||||
//#define SPI_ENDSTOPS // TMC2130 only
|
||||
//#define IMPROVE_HOMING_RELIABILITY
|
||||
#endif
|
||||
@@ -3212,7 +3333,7 @@
|
||||
#define Z4_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_I(L6470)
|
||||
#if AXIS_IS_L64XX(I)
|
||||
#define I_MICROSTEPS 128
|
||||
#define I_OVERCURRENT 2000
|
||||
#define I_STALLCURRENT 1500
|
||||
@@ -3221,7 +3342,7 @@
|
||||
#define I_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_J(L6470)
|
||||
#if AXIS_IS_L64XX(J)
|
||||
#define J_MICROSTEPS 128
|
||||
#define J_OVERCURRENT 2000
|
||||
#define J_STALLCURRENT 1500
|
||||
@@ -3230,7 +3351,7 @@
|
||||
#define J_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_DRIVER_TYPE_K(L6470)
|
||||
#if AXIS_IS_L64XX(K)
|
||||
#define K_MICROSTEPS 128
|
||||
#define K_OVERCURRENT 2000
|
||||
#define K_STALLCURRENT 1500
|
||||
@@ -3239,6 +3360,33 @@
|
||||
#define K_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_L64XX(U)
|
||||
#define U_MICROSTEPS 128
|
||||
#define U_OVERCURRENT 2000
|
||||
#define U_STALLCURRENT 1500
|
||||
#define U_MAX_VOLTAGE 127
|
||||
#define U_CHAIN_POS -1
|
||||
#define U_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_L64XX(V)
|
||||
#define V_MICROSTEPS 128
|
||||
#define V_OVERCURRENT 2000
|
||||
#define V_STALLCURRENT 1500
|
||||
#define V_MAX_VOLTAGE 127
|
||||
#define V_CHAIN_POS -1
|
||||
#define V_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_L64XX(W)
|
||||
#define W_MICROSTEPS 128
|
||||
#define W_OVERCURRENT 2000
|
||||
#define W_STALLCURRENT 1500
|
||||
#define W_MAX_VOLTAGE 127
|
||||
#define W_CHAIN_POS -1
|
||||
#define W_SLEW_RATE 1
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_L64XX(E0)
|
||||
#define E0_MICROSTEPS 128
|
||||
#define E0_OVERCURRENT 2000
|
||||
@@ -3433,7 +3581,7 @@
|
||||
* You'll need to select a pin for the ON/OFF function and optionally choose a 0-5V
|
||||
* hardware PWM pin for the speed control and a pin for the rotation direction.
|
||||
*
|
||||
* See https://marlinfw.org/docs/configuration/laser_spindle.html for more config details.
|
||||
* See https://marlinfw.org/docs/configuration/2.0.9/laser_spindle.html for more config details.
|
||||
*/
|
||||
//#define SPINDLE_FEATURE
|
||||
//#define LASER_FEATURE
|
||||
@@ -3443,7 +3591,7 @@
|
||||
#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)
|
||||
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC)
|
||||
#endif
|
||||
|
||||
//#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11
|
||||
@@ -3520,6 +3668,16 @@
|
||||
#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
|
||||
|
||||
/**
|
||||
* Laser Safety Timeout
|
||||
*
|
||||
* The laser should be turned off when there is no movement for a period of time.
|
||||
* Consider material flammability, cut rate, and G-code order when setting this
|
||||
* value. Too low and it could turn off during a very slow move; too high and
|
||||
* the material could ignite.
|
||||
*/
|
||||
#define LASER_SAFETY_TIMEOUT_MS 1000 // (ms)
|
||||
|
||||
/**
|
||||
* Enable inline laser power to be handled in the planner / stepper routines.
|
||||
* Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I)
|
||||
@@ -3604,6 +3762,20 @@
|
||||
#define I2C_AMMETER_SHUNT_RESISTOR 0.1 // (Ohms) Calibration shunt resistor value
|
||||
#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
|
||||
|
||||
#endif
|
||||
#endif // SPINDLE_FEATURE || LASER_FEATURE
|
||||
|
||||
@@ -3717,6 +3889,9 @@
|
||||
* Auto-report temperatures with M155 S<seconds>
|
||||
*/
|
||||
#define AUTO_REPORT_TEMPERATURES
|
||||
#if ENABLED(AUTO_REPORT_TEMPERATURES) && TEMP_SENSOR_REDUNDANT
|
||||
//#define AUTO_REPORT_REDUNDANT // Include the "R" sensor in the auto-report
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Auto-report position with M154 S<seconds>
|
||||
@@ -3782,15 +3957,6 @@
|
||||
|
||||
//#define REPORT_FAN_CHANGE // Report the new fan speed when changed by M106 (and others)
|
||||
|
||||
/**
|
||||
* Set the number of proportional font spaces required to fill up a typical character space.
|
||||
* This can help to better align the output of commands like `G29 O` Mesh Output.
|
||||
*
|
||||
* For clients that use a fixed-width font (like OctoPrint), leave this set to 1.0.
|
||||
* Otherwise, adjust according to your client and font.
|
||||
*/
|
||||
#define PROPORTIONAL_FONT_RATIO 1.0
|
||||
|
||||
/**
|
||||
* Spend 28 bytes of SRAM to optimize the G-code parser
|
||||
*/
|
||||
@@ -3954,10 +4120,13 @@
|
||||
*/
|
||||
//#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_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down
|
||||
//#define HOST_PAUSE_M76 // Tell the host to pause in response to M76
|
||||
//#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
//#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications
|
||||
#endif
|
||||
//#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
|
||||
|
||||
/**
|
||||
@@ -4092,12 +4261,12 @@
|
||||
|
||||
/**
|
||||
* 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
|
||||
#define FREEZE_STATE LOW // State of pin indicating freeze
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
@@ -132,7 +132,7 @@ CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ )
|
||||
CC_PATCHLEVEL:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_PATCHLEVEL__ | cut -f3 -d\ )
|
||||
CC_VER:=$(shell echo $$(( $(CC_MAJ) * 10000 + $(CC_MIN) * 100 + $(CC_PATCHLEVEL) )))
|
||||
ifeq ($(shell test $(CC_VER) -lt 40901 && echo 1),1)
|
||||
@echo This version of GCC is likely broken. Enabling relocation workaround.
|
||||
$(warning This GCC version $(CC_VER) is likely broken. Enabling relocation workaround.)
|
||||
RELOC_WORKAROUND = 1
|
||||
endif
|
||||
|
||||
@@ -512,7 +512,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1324)
|
||||
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)
|
||||
# Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
|
||||
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
|
||||
# Geeetech GT2560 Rev B for A20(M/T/D)
|
||||
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
|
||||
|
@@ -28,7 +28,7 @@
|
||||
/**
|
||||
* Marlin release version identifier
|
||||
*/
|
||||
//#define SHORT_BUILD_VERSION "2.0.9.3"
|
||||
//#define SHORT_BUILD_VERSION "2.1.0.1"
|
||||
|
||||
/**
|
||||
* Verbose version identifier which should contain a reference to the location
|
||||
@@ -41,7 +41,7 @@
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
//#define STRING_DISTRIBUTION_DATE "2021-12-25"
|
||||
//#define STRING_DISTRIBUTION_DATE "2023-07-19"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
|
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "HAL.h"
|
||||
#include <avr/wdt.h>
|
||||
|
||||
#ifdef USBCON
|
||||
DefaultSerial1 MSerial0(false, Serial);
|
||||
@@ -36,7 +37,7 @@
|
||||
// ------------------------
|
||||
|
||||
// Don't initialize/override variable (which would happen in .init4)
|
||||
uint8_t reset_reason __attribute__((section(".noinit")));
|
||||
uint8_t MarlinHAL::reset_reason __attribute__((section(".noinit")));
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
@@ -45,22 +46,22 @@ uint8_t reset_reason __attribute__((section(".noinit")));
|
||||
__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() {
|
||||
void save_reset_reason() {
|
||||
#if ENABLED(OPTIBOOT_RESET_REASON)
|
||||
__asm__ __volatile__(
|
||||
A("STS %0, r2")
|
||||
: "=m"(reset_reason)
|
||||
: "=m"(hal.reset_reason)
|
||||
);
|
||||
#else
|
||||
reset_reason = MCUSR;
|
||||
hal.reset_reason = MCUSR;
|
||||
#endif
|
||||
|
||||
// Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop
|
||||
MCUSR = 0;
|
||||
hal.clear_reset_source();
|
||||
wdt_disable();
|
||||
}
|
||||
|
||||
void HAL_init() {
|
||||
void MarlinHAL::init() {
|
||||
// Init Servo Pins
|
||||
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
|
||||
#if HAS_SERVO_0
|
||||
@@ -75,9 +76,11 @@ void HAL_init() {
|
||||
#if HAS_SERVO_3
|
||||
INIT_SERVO(3);
|
||||
#endif
|
||||
|
||||
init_pwm_timers(); // Init user timers to default frequency - 1000HZ
|
||||
}
|
||||
|
||||
void HAL_reboot() {
|
||||
void MarlinHAL::reboot() {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
while (1) { /* run out the watchdog */ }
|
||||
#else
|
||||
@@ -86,6 +89,62 @@ void HAL_reboot() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// Watchdog Timer
|
||||
// ------------------------
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#include <avr/wdt.h>
|
||||
#include "../../MarlinCore.h"
|
||||
|
||||
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
|
||||
void MarlinHAL::watchdog_init() {
|
||||
#if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S)
|
||||
#define WDTO_NS WDTO_8S
|
||||
#else
|
||||
#define WDTO_NS WDTO_4S
|
||||
#endif
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// Enable the watchdog timer, but only for the interrupt.
|
||||
// Take care, as this requires the correct order of operation, with interrupts disabled.
|
||||
// See the datasheet of any AVR chip for details.
|
||||
wdt_reset();
|
||||
cli();
|
||||
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
|
||||
_WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5
|
||||
// So worked for up to WDTO_2S
|
||||
sei();
|
||||
wdt_reset();
|
||||
#else
|
||||
wdt_enable(WDTO_NS); // The function handles the upper bit correct.
|
||||
#endif
|
||||
//delay(10000); // test it!
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//=================================== ISR ===================================
|
||||
//===========================================================================
|
||||
|
||||
// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled.
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
ISR(WDT_vect) {
|
||||
sei(); // With the interrupt driven serial we need to allow interrupts.
|
||||
SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED);
|
||||
minkill(); // interrupt-safe final kill and infinite loop
|
||||
}
|
||||
#endif
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or AVR will go into emergency procedures.
|
||||
void MarlinHAL::watchdog_refresh() { wdt_reset(); }
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
|
||||
#include "../../sd/SdFatUtil.h"
|
||||
@@ -93,20 +152,20 @@ void HAL_reboot() {
|
||||
|
||||
#else // !SDSUPPORT
|
||||
|
||||
extern "C" {
|
||||
extern char __bss_end;
|
||||
extern char __heap_start;
|
||||
extern void* __brkval;
|
||||
extern "C" {
|
||||
extern char __bss_end;
|
||||
extern char __heap_start;
|
||||
extern void* __brkval;
|
||||
|
||||
int freeMemory() {
|
||||
int free_memory;
|
||||
if ((int)__brkval == 0)
|
||||
free_memory = ((int)&free_memory) - ((int)&__bss_end);
|
||||
else
|
||||
free_memory = ((int)&free_memory) - ((int)__brkval);
|
||||
return free_memory;
|
||||
int freeMemory() {
|
||||
int free_memory;
|
||||
if ((int)__brkval == 0)
|
||||
free_memory = ((int)&free_memory) - ((int)&__bss_end);
|
||||
else
|
||||
free_memory = ((int)&free_memory) - ((int)__brkval);
|
||||
return free_memory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // !SDSUPPORT
|
||||
|
||||
|
@@ -19,16 +19,18 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* HAL for Arduino AVR
|
||||
*/
|
||||
|
||||
#include "../shared/Marduino.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "watchdog.h"
|
||||
#include "math.h"
|
||||
|
||||
#ifdef USBCON
|
||||
#include <HardwareSerial.h>
|
||||
#else
|
||||
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
|
||||
#include "MarlinSerial.h"
|
||||
#endif
|
||||
|
||||
@@ -74,9 +76,9 @@
|
||||
#define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli()
|
||||
#define CRITICAL_SECTION_END() SREG = _sreg
|
||||
#endif
|
||||
#define ISRS_ENABLED() TEST(SREG, SREG_I)
|
||||
#define ENABLE_ISRS() sei()
|
||||
#define DISABLE_ISRS() cli()
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
#define PWM_FREQUENCY 1000 // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency()
|
||||
|
||||
// ------------------------
|
||||
// Types
|
||||
@@ -84,16 +86,15 @@
|
||||
|
||||
typedef int8_t pin_t;
|
||||
|
||||
#define SHARED_SERVOS HAS_SERVOS
|
||||
#define HAL_SERVO_LIB Servo
|
||||
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
|
||||
|
||||
class Servo;
|
||||
typedef Servo hal_servo_t;
|
||||
|
||||
// ------------------------
|
||||
// Public Variables
|
||||
// ------------------------
|
||||
|
||||
extern uint8_t reset_reason;
|
||||
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
#ifdef USBCON
|
||||
#include "../../core/serial_hook.h"
|
||||
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
|
||||
@@ -142,57 +143,15 @@ extern uint8_t reset_reason;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
|
||||
void HAL_init();
|
||||
|
||||
//void cli();
|
||||
|
||||
//void _delay_ms(const int delay);
|
||||
|
||||
inline void HAL_clear_reset_source() { }
|
||||
inline uint8_t HAL_get_reset_source() { return reset_reason; }
|
||||
|
||||
void HAL_reboot();
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
extern "C" int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
//
|
||||
// ADC
|
||||
#ifdef DIDR2
|
||||
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
|
||||
#else
|
||||
#define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind);
|
||||
#endif
|
||||
|
||||
inline void HAL_adc_init() {
|
||||
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
|
||||
DIDR0 = 0;
|
||||
#ifdef DIDR2
|
||||
DIDR2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC)
|
||||
#ifdef MUX5
|
||||
#define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
|
||||
#else
|
||||
#define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
|
||||
#endif
|
||||
|
||||
//
|
||||
#define HAL_ADC_VREF 5.0
|
||||
#define HAL_ADC_RESOLUTION 10
|
||||
#define HAL_READ_ADC() ADC
|
||||
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
|
||||
|
||||
//
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
@@ -206,23 +165,113 @@ inline void HAL_adc_init() {
|
||||
// AVR compatibility
|
||||
#define strtof strtod
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
/**
|
||||
* set_pwm_frequency
|
||||
* Sets the frequency of the timer corresponding to the provided pin
|
||||
* as close as possible to the provided desired frequency. Internally
|
||||
* calculates the required waveform generation mode, prescaler and
|
||||
* resolution values required and sets the timer registers accordingly.
|
||||
* NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
|
||||
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
|
||||
*/
|
||||
void set_pwm_frequency(const pin_t pin, int f_desired);
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* set_pwm_duty
|
||||
* Set the PWM duty cycle of the provided pin to the provided value
|
||||
* Optionally allows inverting the duty cycle [default = false]
|
||||
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
extern "C" int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return TEST(SREG, SREG_I); }
|
||||
static void isr_on() { sei(); }
|
||||
static void isr_off() { cli(); }
|
||||
|
||||
static void delay_ms(const int ms) { _delay_ms(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask() {}
|
||||
|
||||
// Reset
|
||||
static uint8_t reset_reason;
|
||||
static uint8_t get_reset_source() { return reset_reason; }
|
||||
static void clear_reset_source() { MCUSR = 0; }
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {
|
||||
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
|
||||
DIDR0 = 0;
|
||||
#ifdef DIDR2
|
||||
DIDR2 = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const uint8_t ch) {
|
||||
#ifdef DIDR2
|
||||
if (ch > 7) { SBI(DIDR2, ch & 0x07); return; }
|
||||
#endif
|
||||
SBI(DIDR0, ch);
|
||||
}
|
||||
|
||||
// Begin ADC sampling on the given channel. Called from Temperature::isr!
|
||||
static void adc_start(const uint8_t ch) {
|
||||
#ifdef MUX5
|
||||
ADCSRB = ch > 7 ? _BV(MUX5) : 0;
|
||||
#else
|
||||
ADCSRB = 0;
|
||||
#endif
|
||||
ADMUX = _BV(REFS0) | (ch & 0x07);
|
||||
SBI(ADCSRA, ADSC);
|
||||
}
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return !TEST(ADCSRA, ADSC); }
|
||||
|
||||
// The current value of the ADC register
|
||||
static __typeof__(ADC) adc_value() { return ADC; }
|
||||
|
||||
/**
|
||||
* init_pwm_timers
|
||||
* Set the default frequency for timers 2-5 to 1000HZ
|
||||
*/
|
||||
static void init_pwm_timers();
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* Optionally invert the duty cycle [default = false]
|
||||
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
/**
|
||||
* Set the frequency of the timer for the given pin as close as
|
||||
* possible to the provided desired frequency. Internally calculate
|
||||
* the required waveform generation mode, prescaler, and resolution
|
||||
* values and set timer registers accordingly.
|
||||
* NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
|
||||
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST_PWM_FAN Settings)
|
||||
*/
|
||||
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
|
||||
};
|
||||
|
@@ -35,22 +35,20 @@
|
||||
|
||||
void spiBegin() {
|
||||
#if PIN_EXISTS(SD_SS)
|
||||
OUT_WRITE(SD_SS_PIN, HIGH);
|
||||
// Do not init HIGH for boards with pin 4 used as Fans or Heaters or otherwise, not likely to have multiple SPI devices anyway.
|
||||
#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
|
||||
// SS must be in output mode even it is not chip select
|
||||
SET_OUTPUT(SD_SS_PIN);
|
||||
#else
|
||||
// set SS high - may be chip select for another SPI device
|
||||
OUT_WRITE(SD_SS_PIN, HIGH);
|
||||
#endif
|
||||
#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(SD_SS_PIN);
|
||||
// set SS high - may be chip select for another SPI device
|
||||
//#if SET_SPI_SS_HIGH
|
||||
//WRITE(SD_SS_PIN, HIGH);
|
||||
//#endif
|
||||
// set a default rate
|
||||
spiInit(1);
|
||||
#endif
|
||||
IF_DISABLED(SOFTWARE_SPI, spiInit(SPI_HALF_SPEED));
|
||||
}
|
||||
|
||||
#if NONE(SOFTWARE_SPI, FORCE_SOFT_SPI)
|
||||
|
@@ -486,7 +486,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
|
||||
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
||||
|
||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||
if (!ISRS_ENABLED()) {
|
||||
if (!hal.isr_state()) {
|
||||
|
||||
// Make room by polling if it is possible to transmit, and do so!
|
||||
while (i == tx_buffer.tail) {
|
||||
@@ -534,7 +534,7 @@ void MarlinSerial<Cfg>::flushTX() {
|
||||
if (!_written) return;
|
||||
|
||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||
if (!ISRS_ENABLED()) {
|
||||
if (!hal.isr_state()) {
|
||||
|
||||
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
|
||||
while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
|
||||
|
@@ -191,13 +191,13 @@
|
||||
rx_framing_errors;
|
||||
static ring_buffer_pos_t rx_max_enqueued;
|
||||
|
||||
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_head();
|
||||
FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_head();
|
||||
|
||||
static volatile bool rx_tail_value_not_stable;
|
||||
static volatile uint16_t rx_tail_value_backup;
|
||||
|
||||
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
|
||||
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
|
||||
FORCE_INLINE static void atomic_set_rx_tail(ring_buffer_pos_t value);
|
||||
FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_tail();
|
||||
|
||||
public:
|
||||
FORCE_INLINE static void store_rxd_char();
|
||||
@@ -217,7 +217,7 @@
|
||||
#endif
|
||||
|
||||
enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
|
||||
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; }
|
||||
|
@@ -213,6 +213,51 @@ void setup_endstop_interrupts() {
|
||||
pciSetup(K_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
#if (digitalPinToInterrupt(U_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(U_MAX_PIN);
|
||||
#else
|
||||
static_assert(digitalPinHasPCICR(U_MAX_PIN), "U_MAX_PIN is not interrupt-capable");
|
||||
pciSetup(U_MAX_PIN);
|
||||
#endif
|
||||
#elif HAS_U_MIN
|
||||
#if (digitalPinToInterrupt(U_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(U_MIN_PIN);
|
||||
#else
|
||||
static_assert(digitalPinHasPCICR(U_MIN_PIN), "U_MIN_PIN is not interrupt-capable");
|
||||
pciSetup(U_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
#if (digitalPinToInterrupt(V_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(V_MAX_PIN);
|
||||
#else
|
||||
static_assert(digitalPinHasPCICR(V_MAX_PIN), "V_MAX_PIN is not interrupt-capable");
|
||||
pciSetup(V_MAX_PIN);
|
||||
#endif
|
||||
#elif HAS_V_MIN
|
||||
#if (digitalPinToInterrupt(V_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(V_MIN_PIN);
|
||||
#else
|
||||
static_assert(digitalPinHasPCICR(V_MIN_PIN), "V_MIN_PIN is not interrupt-capable");
|
||||
pciSetup(V_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
#if (digitalPinToInterrupt(W_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(W_MAX_PIN);
|
||||
#else
|
||||
static_assert(digitalPinHasPCICR(W_MAX_PIN), "W_MAX_PIN is not interrupt-capable");
|
||||
pciSetup(W_MAX_PIN);
|
||||
#endif
|
||||
#elif HAS_W_MIN
|
||||
#if (digitalPinToInterrupt(W_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(W_MIN_PIN);
|
||||
#else
|
||||
static_assert(digitalPinHasPCICR(W_MIN_PIN), "W_MIN_PIN is not interrupt-capable");
|
||||
pciSetup(W_MIN_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#if HAS_X2_MAX
|
||||
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||
_ATTACH(X2_MAX_PIN);
|
||||
@@ -301,5 +346,6 @@ 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.
|
||||
}
|
||||
|
@@ -21,10 +21,7 @@
|
||||
*/
|
||||
#ifdef __AVR__
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
#include "HAL.h"
|
||||
|
||||
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
struct Timer {
|
||||
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
|
||||
@@ -32,229 +29,194 @@ struct Timer {
|
||||
volatile uint16_t* ICRn; // max 1 ICR register per timer
|
||||
uint8_t n; // the timer number [0->5]
|
||||
uint8_t q; // the timer output [0->2] (A->C)
|
||||
bool isPWM; // True if pin is a "hardware timer"
|
||||
bool isProtected; // True if timer is protected
|
||||
};
|
||||
|
||||
// Macros for the Timer structure
|
||||
#define _SET_WGMnQ(T, V) do{ \
|
||||
*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
|
||||
*(T.TCCRnQ)[1] = (*(T.TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
|
||||
}while(0)
|
||||
|
||||
// Set TCCR CS bits
|
||||
#define _SET_CSn(T, V) (*(T.TCCRnQ)[1] = (*(T.TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
|
||||
|
||||
// Set TCCR COM bits
|
||||
#define _SET_COMnQ(T, Q, V) (*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q))))
|
||||
|
||||
// Set OCRnQ register
|
||||
#define _SET_OCRnQ(T, Q, V) (*(T.OCRnQ)[Q] = int(V) & 0xFFFF)
|
||||
|
||||
// Set ICRn register (one per timer)
|
||||
#define _SET_ICRn(T, V) (*(T.ICRn) = int(V) & 0xFFFF)
|
||||
|
||||
/**
|
||||
* get_pwm_timer
|
||||
* Get the timer information and register of the provided pin.
|
||||
* Return a Timer struct containing this information.
|
||||
* Used by set_pwm_frequency, set_pwm_duty
|
||||
* Return a Timer struct describing a pin's timer.
|
||||
*/
|
||||
Timer get_pwm_timer(const pin_t pin) {
|
||||
const Timer get_pwm_timer(const pin_t pin) {
|
||||
|
||||
uint8_t q = 0;
|
||||
|
||||
switch (digitalPinToTimer(pin)) {
|
||||
// Protect reserved timers (TIMER0 & TIMER1)
|
||||
#ifdef TCCR0A
|
||||
#if !AVR_AT90USB1286_FAMILY
|
||||
case TIMER0A:
|
||||
#endif
|
||||
case TIMER0B:
|
||||
IF_DISABLED(AVR_AT90USB1286_FAMILY, case TIMER0A:)
|
||||
#endif
|
||||
#ifdef TCCR1A
|
||||
case TIMER1A: case TIMER1B:
|
||||
#endif
|
||||
break;
|
||||
#if HAS_TCCR2 || defined(TCCR2A)
|
||||
#if HAS_TCCR2
|
||||
case TIMER2: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR2, nullptr, nullptr },
|
||||
/*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr },
|
||||
/*ICRn*/ nullptr,
|
||||
/*n, q*/ 2, 0
|
||||
};
|
||||
}
|
||||
#elif defined(TCCR2A)
|
||||
#if ENABLED(USE_OCR2A_AS_TOP)
|
||||
case TIMER2A: break; // protect TIMER2A
|
||||
case TIMER2B: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
|
||||
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
|
||||
/*ICRn*/ nullptr,
|
||||
/*n, q*/ 2, 1
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
#else
|
||||
case TIMER2B: ++q;
|
||||
case TIMER2A: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
|
||||
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
|
||||
/*ICRn*/ nullptr,
|
||||
2, q
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
break; // Protect reserved timers (TIMER0 & TIMER1)
|
||||
|
||||
#ifdef TCCR0A
|
||||
case TIMER0B: // Protected timer, but allow setting the duty cycle on OCR0B for pin D4 only
|
||||
return Timer({ { &TCCR0A, nullptr, nullptr }, { (uint16_t*)&OCR0A, (uint16_t*)&OCR0B, nullptr }, nullptr, 0, 1, true, true });
|
||||
#endif
|
||||
|
||||
#if HAS_TCCR2
|
||||
case TIMER2:
|
||||
return Timer({ { &TCCR2, nullptr, nullptr }, { (uint16_t*)&OCR2, nullptr, nullptr }, nullptr, 2, 0, true, false });
|
||||
#elif ENABLED(USE_OCR2A_AS_TOP)
|
||||
case TIMER2A: break; // Protect TIMER2A since its OCR is used by TIMER2B
|
||||
case TIMER2B:
|
||||
return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, 1, true, false });
|
||||
#elif defined(TCCR2A)
|
||||
case TIMER2B: ++q; case TIMER2A:
|
||||
return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, q, true, false });
|
||||
#endif
|
||||
|
||||
#ifdef OCR3C
|
||||
case TIMER3C: ++q;
|
||||
case TIMER3B: ++q;
|
||||
case TIMER3A: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C },
|
||||
/*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C },
|
||||
/*ICRn*/ &ICR3,
|
||||
/*n, q*/ 3, q
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A:
|
||||
return Timer({ { &TCCR3A, &TCCR3B, &TCCR3C }, { &OCR3A, &OCR3B, &OCR3C }, &ICR3, 3, q, true, false });
|
||||
#elif defined(OCR3B)
|
||||
case TIMER3B: ++q;
|
||||
case TIMER3A: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr },
|
||||
/*OCRnQ*/ { &OCR3A, &OCR3B, nullptr },
|
||||
/*ICRn*/ &ICR3,
|
||||
/*n, q*/ 3, q
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
case TIMER3B: ++q; case TIMER3A:
|
||||
return Timer({ { &TCCR3A, &TCCR3B, nullptr }, { &OCR3A, &OCR3B, nullptr }, &ICR3, 3, q, true, false });
|
||||
#endif
|
||||
|
||||
#ifdef TCCR4A
|
||||
case TIMER4C: ++q;
|
||||
case TIMER4B: ++q;
|
||||
case TIMER4A: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C },
|
||||
/*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C },
|
||||
/*ICRn*/ &ICR4,
|
||||
/*n, q*/ 4, q
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A:
|
||||
return Timer({ { &TCCR4A, &TCCR4B, &TCCR4C }, { &OCR4A, &OCR4B, &OCR4C }, &ICR4, 4, q, true, false });
|
||||
#endif
|
||||
|
||||
#ifdef TCCR5A
|
||||
case TIMER5C: ++q;
|
||||
case TIMER5B: ++q;
|
||||
case TIMER5A: {
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C },
|
||||
/*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C },
|
||||
/*ICRn*/ &ICR5,
|
||||
/*n, q*/ 5, q
|
||||
};
|
||||
return timer;
|
||||
}
|
||||
case TIMER5C: ++q; case TIMER5B: ++q; case TIMER5A:
|
||||
return Timer({ { &TCCR5A, &TCCR5B, &TCCR5C }, { &OCR5A, &OCR5B, &OCR5C }, &ICR5, 5, q, true, false });
|
||||
#endif
|
||||
}
|
||||
Timer timer = {
|
||||
/*TCCRnQ*/ { nullptr, nullptr, nullptr },
|
||||
/*OCRnQ*/ { nullptr, nullptr, nullptr },
|
||||
/*ICRn*/ nullptr,
|
||||
0, 0
|
||||
};
|
||||
return timer;
|
||||
|
||||
return Timer();
|
||||
}
|
||||
|
||||
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 recognized
|
||||
uint16_t size;
|
||||
if (timer.n == 2) size = 255; else size = 65535;
|
||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
|
||||
const Timer timer = get_pwm_timer(pin);
|
||||
if (timer.isProtected || !timer.isPWM) return; // Don't proceed if protected timer or not recognized
|
||||
|
||||
uint16_t res = 255; // resolution (TOP value)
|
||||
uint8_t j = 0; // prescaler index
|
||||
uint8_t wgm = 1; // waveform generation mode
|
||||
const bool is_timer2 = timer.n == 2;
|
||||
const uint16_t maxtop = is_timer2 ? 0xFF : 0xFFFF;
|
||||
|
||||
uint16_t res = 0xFF; // resolution (TOP value)
|
||||
uint8_t j = CS_NONE; // prescaler index
|
||||
uint8_t wgm = WGM_PWM_PC_8; // waveform generation mode
|
||||
|
||||
// Calculating the prescaler and resolution to use to achieve closest frequency
|
||||
if (f_desired != 0) {
|
||||
int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable
|
||||
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
|
||||
constexpr uint16_t prescaler[] = { 1, 8, (32), 64, (128), 256, 1024 }; // (*) are Timer 2 only
|
||||
uint16_t f = (F_CPU) / (2 * 1024 * maxtop) + 1; // Start with the lowest non-zero frequency achievable (1 or 31)
|
||||
|
||||
// loop over prescaler values
|
||||
LOOP_S_L_N(i, 1, 8) {
|
||||
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
|
||||
if (timer.n == 2) {
|
||||
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
|
||||
#if ENABLED(USE_OCR2A_AS_TOP)
|
||||
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
|
||||
res_temp_fast = rtf - 1;
|
||||
res_temp_phase_correct = rtf / 2;
|
||||
LOOP_L_N(i, COUNT(prescaler)) { // Loop through all prescaler values
|
||||
const uint16_t p = prescaler[i];
|
||||
uint16_t res_fast_temp, res_pc_temp;
|
||||
if (is_timer2) {
|
||||
#if ENABLED(USE_OCR2A_AS_TOP) // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
|
||||
const uint16_t rft = (F_CPU) / (p * f_desired);
|
||||
res_fast_temp = rft - 1;
|
||||
res_pc_temp = rft / 2;
|
||||
#else
|
||||
res_fast_temp = res_pc_temp = maxtop;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
// Skip TIMER2 specific prescalers when not TIMER2
|
||||
if (i == 3 || i == 5) continue;
|
||||
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
|
||||
res_temp_fast = rtf - 1;
|
||||
res_temp_phase_correct = rtf / 2;
|
||||
if (p == 32 || p == 128) continue; // Skip TIMER2 specific prescalers when not TIMER2
|
||||
const uint16_t rft = (F_CPU) / (p * f_desired);
|
||||
res_fast_temp = rft - 1;
|
||||
res_pc_temp = rft / 2;
|
||||
}
|
||||
|
||||
LIMIT(res_temp_fast, 1U, size);
|
||||
LIMIT(res_temp_phase_correct, 1U, size);
|
||||
LIMIT(res_fast_temp, 1U, maxtop);
|
||||
LIMIT(res_pc_temp, 1U, maxtop);
|
||||
|
||||
// Calculate frequencies of test prescaler and resolution values
|
||||
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
|
||||
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
|
||||
f_diff = ABS(f - f_desired),
|
||||
f_fast_diff = ABS(f_temp_fast - f_desired),
|
||||
f_phase_diff = ABS(f_temp_phase_correct - f_desired);
|
||||
const uint32_t f_diff = _MAX(f, f_desired) - _MIN(f, f_desired),
|
||||
f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)),
|
||||
f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired),
|
||||
f_pc_temp = (F_CPU) / (2 * p * res_pc_temp),
|
||||
f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired);
|
||||
|
||||
// If FAST values are closest to desired f
|
||||
if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) {
|
||||
// Remember this combination
|
||||
f = f_temp_fast;
|
||||
res = res_temp_fast;
|
||||
j = i;
|
||||
if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f
|
||||
// Set the Wave Generation Mode to FAST PWM
|
||||
if (timer.n == 2)
|
||||
wgm = TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM);
|
||||
else
|
||||
wgm = WGM_FAST_PWM_ICRn;
|
||||
wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn);
|
||||
// Remember this combination
|
||||
f = f_fast_temp; res = res_fast_temp; j = i + 1;
|
||||
}
|
||||
// If PHASE CORRECT values are closes to desired f
|
||||
else if (f_phase_diff < f_diff) {
|
||||
f = f_temp_phase_correct;
|
||||
res = res_temp_phase_correct;
|
||||
j = i;
|
||||
else if (f_pc_diff < f_diff) { // PHASE CORRECT values are closes to desired f
|
||||
// Set the Wave Generation Mode to PWM PHASE CORRECT
|
||||
if (timer.n == 2)
|
||||
wgm = TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_FAST_PWM);
|
||||
else
|
||||
wgm = WGM_PWM_PC_ICRn;
|
||||
wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_PWM_PC)) : uint8_t(WGM_PWM_PC_ICRn);
|
||||
f = f_pc_temp; res = res_pc_temp; j = i + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
_SET_WGMnQ(timer.TCCRnQ, wgm);
|
||||
_SET_CSn(timer.TCCRnQ, j);
|
||||
|
||||
if (timer.n == 2) {
|
||||
TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer.OCRnQ, 0, res)); // Set OCR2A value (TOP) = res
|
||||
_SET_WGMnQ(timer, wgm);
|
||||
_SET_CSn(timer, j);
|
||||
|
||||
if (is_timer2) {
|
||||
TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer, 0, res)); // Set OCR2A value (TOP) = res
|
||||
}
|
||||
else
|
||||
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
|
||||
_SET_ICRn(timer, 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 NEEDS_HARDWARE_PWM
|
||||
|
||||
// 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
|
||||
void MarlinHAL::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 {
|
||||
const Timer timer = get_pwm_timer(pin);
|
||||
if (timer.isPWM) {
|
||||
if (timer.n == 0) {
|
||||
_SET_COMnQ(timer, timer.q, COM_CLEAR_SET); // Only allow a TIMER0B select...
|
||||
_SET_OCRnQ(timer, timer.q, v); // ...and OCR0B duty update. For output pin D4 no frequency changes are permitted.
|
||||
}
|
||||
else if (!timer.isProtected) {
|
||||
const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
|
||||
_SET_COMnQ(timer, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2
|
||||
_SET_OCRnQ(timer, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value
|
||||
}
|
||||
}
|
||||
else
|
||||
digitalWrite(pin, v < v_size / 2 ? LOW : HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
void MarlinHAL::init_pwm_timers() {
|
||||
// Init some timer frequencies to a default 1KHz
|
||||
const pin_t pwm_pin[] = {
|
||||
#ifdef __AVR_ATmega2560__
|
||||
10, 5, 6, 46
|
||||
#elif defined(__AVR_ATmega1280__)
|
||||
12, 31
|
||||
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284__)
|
||||
15, 6
|
||||
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128)
|
||||
16, 24
|
||||
#endif
|
||||
};
|
||||
|
||||
analogWrite(pin, v);
|
||||
UNUSED(v_size);
|
||||
UNUSED(invert);
|
||||
|
||||
#endif
|
||||
LOOP_L_N(i, COUNT(pwm_pin))
|
||||
set_pwm_frequency(pwm_pin[i], 1000);
|
||||
}
|
||||
|
||||
#endif // __AVR__
|
||||
|
@@ -245,7 +245,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
|
||||
float count = 0;
|
||||
if (hz > 0 && (dca || dcb || dcc)) {
|
||||
count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq.
|
||||
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5KHz (>31)
|
||||
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5kHz (>31)
|
||||
|
||||
if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); }
|
||||
else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); }
|
||||
@@ -257,7 +257,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
|
||||
const float pwm_top = round(count); // Get the rounded count
|
||||
|
||||
ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP
|
||||
OCR5A = pwm_top * ABS(dca); // Update and scale DCs
|
||||
OCR5A = pwm_top * ABS(dca); // Update and scale DCs
|
||||
OCR5B = pwm_top * ABS(dcb);
|
||||
OCR5C = pwm_top * ABS(dcc);
|
||||
_SET_COM(5, A, dca ? (dca < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); // Set compare modes
|
||||
@@ -277,7 +277,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
|
||||
// Restore the default for Timer 5
|
||||
SET_WGM(5, PWM_PC_8); // PWM 8-bit (Phase Correct)
|
||||
SET_COMS(5, NORMAL, NORMAL, NORMAL); // Do nothing
|
||||
SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250KHz
|
||||
SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250kHz
|
||||
OCR5A = OCR5B = OCR5C = 0;
|
||||
}
|
||||
return round(count);
|
||||
|
@@ -118,7 +118,7 @@
|
||||
*/
|
||||
|
||||
// Waveform Generation Modes
|
||||
enum WaveGenMode : char {
|
||||
enum WaveGenMode : uint8_t {
|
||||
WGM_NORMAL, // 0
|
||||
WGM_PWM_PC_8, // 1
|
||||
WGM_PWM_PC_9, // 2
|
||||
@@ -138,19 +138,19 @@ enum WaveGenMode : char {
|
||||
};
|
||||
|
||||
// Wavefore Generation Modes (Timer 2 only)
|
||||
enum WaveGenMode2 : char {
|
||||
WGM2_NORMAL, // 0
|
||||
WGM2_PWM_PC, // 1
|
||||
WGM2_CTC_OCR2A, // 2
|
||||
WGM2_FAST_PWM, // 3
|
||||
WGM2_reserved_1, // 4
|
||||
WGM2_PWM_PC_OCR2A, // 5
|
||||
WGM2_reserved_2, // 6
|
||||
WGM2_FAST_PWM_OCR2A, // 7
|
||||
enum WaveGenMode2 : uint8_t {
|
||||
WGM2_NORMAL, // 0
|
||||
WGM2_PWM_PC, // 1
|
||||
WGM2_CTC_OCR2A, // 2
|
||||
WGM2_FAST_PWM, // 3
|
||||
WGM2_reserved_1, // 4
|
||||
WGM2_PWM_PC_OCR2A, // 5
|
||||
WGM2_reserved_2, // 6
|
||||
WGM2_FAST_PWM_OCR2A, // 7
|
||||
};
|
||||
|
||||
// Compare Modes
|
||||
enum CompareMode : char {
|
||||
enum CompareMode : uint8_t {
|
||||
COM_NORMAL, // 0
|
||||
COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
|
||||
COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
|
||||
@@ -158,7 +158,7 @@ enum CompareMode : char {
|
||||
};
|
||||
|
||||
// Clock Sources
|
||||
enum ClockSource : char {
|
||||
enum ClockSource : uint8_t {
|
||||
CS_NONE, // 0
|
||||
CS_PRESCALER_1, // 1
|
||||
CS_PRESCALER_8, // 2
|
||||
@@ -170,7 +170,7 @@ enum ClockSource : char {
|
||||
};
|
||||
|
||||
// Clock Sources (Timer 2 only)
|
||||
enum ClockSource2 : char {
|
||||
enum ClockSource2 : uint8_t {
|
||||
CS2_NONE, // 0
|
||||
CS2_PRESCALER_1, // 1
|
||||
CS2_PRESCALER_8, // 2
|
||||
@@ -203,11 +203,6 @@ enum ClockSource2 : char {
|
||||
TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
|
||||
}while(0)
|
||||
#define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
|
||||
// Runtime (see set_pwm_frequency):
|
||||
#define _SET_WGMnQ(TCCRnQ, V) do{ \
|
||||
*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
|
||||
*(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
|
||||
}while(0)
|
||||
|
||||
// Set Clock Select bits
|
||||
// Ex: SET_CS3(PRESCALER_64);
|
||||
@@ -235,8 +230,6 @@ enum ClockSource2 : char {
|
||||
#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) (*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
|
||||
|
||||
// Set Compare Mode bits
|
||||
// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET);
|
||||
@@ -246,16 +239,6 @@ enum ClockSource2 : char {
|
||||
#define SET_COMB(T,V) SET_COM(T,B,V)
|
||||
#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) (*(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) (*(OCRnQ)[Q] = int(V) & 0xFFFF)
|
||||
|
||||
// Set ICRn register (one per timer)
|
||||
// Runtime (see set_pwm_frequency)
|
||||
#define _SET_ICRn(ICRn, V) (*(ICRn) = int(V) & 0xFFFF)
|
||||
|
||||
// Set Noise Canceler bit
|
||||
// Ex: SET_ICNC(2,1)
|
||||
|
@@ -25,11 +25,43 @@
|
||||
* Test AVR-specific configuration values for errors at compile-time.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check for common serial pin conflicts
|
||||
*/
|
||||
#define CHECK_SERIAL_PIN(N) ( \
|
||||
X_STOP_PIN == N || Y_STOP_PIN == N || Z_STOP_PIN == N \
|
||||
|| X_MIN_PIN == N || Y_MIN_PIN == N || Z_MIN_PIN == N \
|
||||
|| X_MAX_PIN == N || Y_MAX_PIN == N || Z_MAX_PIN == N \
|
||||
|| X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_PIN == N \
|
||||
|| X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \
|
||||
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
|
||||
)
|
||||
#if CONF_SERIAL_IS(0) // D0-D1. No known conflicts.
|
||||
#endif
|
||||
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19))
|
||||
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
|
||||
#endif
|
||||
#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
|
||||
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
|
||||
#endif
|
||||
#if CONF_SERIAL_IS(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15))
|
||||
#error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board."
|
||||
#endif
|
||||
#undef CHECK_SERIAL_PIN
|
||||
|
||||
/**
|
||||
* Checks for FAST PWM
|
||||
*/
|
||||
#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"
|
||||
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2."
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Checks for SOFT PWM
|
||||
*/
|
||||
#if HAS_FAN0 && FAN_PIN == 9 && DISABLED(FAN_SOFT_PWM) && ENABLED(SPEAKER)
|
||||
#error "FAN_PIN 9 Hardware PWM uses Timer 2 which conflicts with Arduino AVR Tone Timer (for SPEAKER)."
|
||||
#error "Disable SPEAKER or enable FAN_SOFT_PWM."
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -42,7 +74,7 @@
|
||||
#elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
|
||||
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
|
||||
#endif
|
||||
#elif defined(SPINDLE_LASER_FREQUENCY)
|
||||
#elif SPINDLE_LASER_FREQUENCY
|
||||
#error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM."
|
||||
#endif
|
||||
|
||||
@@ -63,3 +95,7 @@
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
#error "POSTMORTEM_DEBUGGING is not supported on AVR boards."
|
||||
#endif
|
||||
|
||||
#if USING_PULLDOWNS
|
||||
#error "PULLDOWN pin mode is not available on AVR boards."
|
||||
#endif
|
||||
|
@@ -35,7 +35,7 @@
|
||||
// C B A is longIn1
|
||||
// D C B A is longIn2
|
||||
//
|
||||
static FORCE_INLINE uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
|
||||
FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
|
||||
uint8_t tmp1;
|
||||
uint8_t tmp2;
|
||||
uint16_t intRes;
|
||||
@@ -89,7 +89,7 @@ static FORCE_INLINE uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
|
||||
// uses:
|
||||
// r26 to store 0
|
||||
// r27 to store the byte 1 of the 24 bit result
|
||||
static FORCE_INLINE uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
|
||||
FORCE_INLINE static uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
|
||||
uint8_t tmp;
|
||||
uint16_t intRes;
|
||||
__asm__ __volatile__ (
|
||||
|
@@ -74,7 +74,7 @@
|
||||
#define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin
|
||||
|
||||
void PRINT_ARRAY_NAME(uint8_t x) {
|
||||
char *name_mem_pointer = (char*)pgm_read_ptr(&pin_array[x].name);
|
||||
PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name);
|
||||
LOOP_L_N(y, MAX_NAME_LENGTH) {
|
||||
char temp_char = pgm_read_byte(name_mem_pointer + y);
|
||||
if (temp_char != 0)
|
||||
|
@@ -58,9 +58,9 @@ typedef uint16_t hal_timer_t;
|
||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
|
||||
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
|
||||
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
|
||||
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0A)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0A)
|
||||
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0A)
|
||||
|
||||
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
||||
switch (timer_num) {
|
||||
@@ -87,7 +87,7 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
||||
case MF_TIMER_TEMP:
|
||||
// Use timer0 for temperature measurement
|
||||
// Interleave temperature interrupt with millies interrupt
|
||||
OCR0B = 128;
|
||||
OCR0A = 128;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -109,12 +109,12 @@ 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(T)
|
||||
#define HAL_timer_isr_epilogue(T)
|
||||
#define HAL_timer_isr_prologue(T) NOOP
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
|
||||
/* 18 cycles maximum latency */
|
||||
#ifndef HAL_STEP_TIMER_ISR
|
||||
|
||||
/* 18 cycles maximum latency */
|
||||
#define HAL_STEP_TIMER_ISR() \
|
||||
extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
||||
extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||
@@ -180,7 +180,7 @@ void TIMER1_COMPA_vect() { \
|
||||
: \
|
||||
: [timsk0] "i" ((uint16_t)&TIMSK0), \
|
||||
[timsk1] "i" ((uint16_t)&TIMSK1), \
|
||||
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
|
||||
[msk0] "M" ((uint8_t)(1<<OCIE0A)),\
|
||||
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
|
||||
: \
|
||||
); \
|
||||
@@ -193,9 +193,9 @@ void TIMER1_COMPA_vect_bottom()
|
||||
|
||||
/* 14 cycles maximum latency */
|
||||
#define HAL_TEMP_TIMER_ISR() \
|
||||
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
||||
extern "C" void TIMER0_COMPB_vect_bottom() asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||
void TIMER0_COMPB_vect() { \
|
||||
extern "C" void TIMER0_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
||||
extern "C" void TIMER0_COMPA_vect_bottom() asm ("TIMER0_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||
void TIMER0_COMPA_vect() { \
|
||||
__asm__ __volatile__ ( \
|
||||
A("push r16") /* 2 Save R16 */ \
|
||||
A("in r16, __SREG__") /* 1 Get SREG */ \
|
||||
@@ -223,7 +223,7 @@ void TIMER0_COMPB_vect() { \
|
||||
A("push r30") \
|
||||
A("push r31") \
|
||||
A("clr r1") /* C runtime expects this register to be 0 */ \
|
||||
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
||||
A("call TIMER0_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
|
||||
A("pop r31") \
|
||||
A("pop r30") \
|
||||
A("pop r27") \
|
||||
@@ -251,10 +251,10 @@ void TIMER0_COMPB_vect() { \
|
||||
A("reti") /* 4 Return from interrupt */ \
|
||||
: \
|
||||
: [timsk0] "i"((uint16_t)&TIMSK0), \
|
||||
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
|
||||
[msk0] "M" ((uint8_t)(1<<OCIE0A)) \
|
||||
: \
|
||||
); \
|
||||
} \
|
||||
void TIMER0_COMPB_vect_bottom()
|
||||
void TIMER0_COMPA_vect_bottom()
|
||||
|
||||
#endif // HAL_TEMP_TIMER_ISR
|
||||
|
@@ -1,70 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef __AVR__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#include "watchdog.h"
|
||||
|
||||
#include "../../MarlinCore.h"
|
||||
|
||||
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
|
||||
void watchdog_init() {
|
||||
#if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S)
|
||||
#define WDTO_NS WDTO_8S
|
||||
#else
|
||||
#define WDTO_NS WDTO_4S
|
||||
#endif
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// Enable the watchdog timer, but only for the interrupt.
|
||||
// Take care, as this requires the correct order of operation, with interrupts disabled.
|
||||
// See the datasheet of any AVR chip for details.
|
||||
wdt_reset();
|
||||
cli();
|
||||
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
|
||||
_WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5
|
||||
// So worked for up to WDTO_2S
|
||||
sei();
|
||||
wdt_reset();
|
||||
#else
|
||||
wdt_enable(WDTO_NS); // The function handles the upper bit correct.
|
||||
#endif
|
||||
//delay(10000); // test it!
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//=================================== ISR ===================================
|
||||
//===========================================================================
|
||||
|
||||
// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled.
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
ISR(WDT_vect) {
|
||||
sei(); // With the interrupt driven serial we need to allow interrupts.
|
||||
SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED);
|
||||
minkill(); // interrupt-safe final kill and infinite loop
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
#endif // __AVR__
|
@@ -25,7 +25,7 @@
|
||||
#ifdef ARDUINO_ARCH_SAM
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "HAL.h"
|
||||
#include "../../MarlinCore.h"
|
||||
|
||||
#include <Wire.h>
|
||||
#include "usb/usb_task.h"
|
||||
@@ -34,39 +34,33 @@
|
||||
// Public Variables
|
||||
// ------------------------
|
||||
|
||||
uint16_t HAL_adc_result;
|
||||
uint16_t MarlinHAL::adc_result;
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
extern void install_min_serial();
|
||||
#endif
|
||||
|
||||
// HAL initialization task
|
||||
void HAL_init() {
|
||||
// Initialize the USB stack
|
||||
void MarlinHAL::init() {
|
||||
#if ENABLED(SDSUPPORT)
|
||||
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
|
||||
#endif
|
||||
usb_task_init();
|
||||
usb_task_init(); // Initialize the USB stack
|
||||
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
|
||||
}
|
||||
|
||||
// HAL idle task
|
||||
void HAL_idletask() {
|
||||
// Perform USB stack housekeeping
|
||||
usb_task_idle();
|
||||
void MarlinHAL::init_board() {
|
||||
#ifdef BOARD_INIT
|
||||
BOARD_INIT();
|
||||
#endif
|
||||
}
|
||||
|
||||
// Disable interrupts
|
||||
void cli() { noInterrupts(); }
|
||||
void MarlinHAL::idletask() { usb_task_idle(); } // Perform USB stack housekeeping
|
||||
|
||||
// Enable interrupts
|
||||
void sei() { interrupts(); }
|
||||
|
||||
void HAL_clear_reset_source() { }
|
||||
|
||||
uint8_t HAL_get_reset_source() {
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
switch ((RSTC->RSTC_SR >> 8) & 0x07) {
|
||||
case 0: return RST_POWER_ON;
|
||||
case 1: return RST_BACKUP;
|
||||
@@ -77,13 +71,105 @@ uint8_t HAL_get_reset_source() {
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_reboot() { rstc_start_software_reset(RSTC); }
|
||||
void MarlinHAL::reboot() { rstc_start_software_reset(RSTC); }
|
||||
|
||||
void _delay_ms(const int delay_ms) {
|
||||
// Todo: port for Due?
|
||||
delay(delay_ms);
|
||||
// ------------------------
|
||||
// Watchdog Timer
|
||||
// ------------------------
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
// Initialize watchdog - On SAM3X, Watchdog was already configured
|
||||
// and enabled or disabled at startup, so no need to reconfigure it
|
||||
// here.
|
||||
void MarlinHAL::watchdog_init() { WDT_Restart(WDT); } // Reset watchdog to start clean
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or AVR will go into emergency procedures.
|
||||
void MarlinHAL::watchdog_refresh() { watchdogReset(); }
|
||||
|
||||
#endif
|
||||
|
||||
// Override Arduino runtime to either config or disable the watchdog
|
||||
//
|
||||
// We need to configure the watchdog as soon as possible in the boot
|
||||
// process, because watchdog initialization at hardware reset on SAM3X8E
|
||||
// is unreliable, and there is risk of unintended resets if we delay
|
||||
// that initialization to a later time.
|
||||
void watchdogSetup() {
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
// 4 seconds timeout
|
||||
uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000);
|
||||
|
||||
// Calculate timeout value in WDT counter ticks: This assumes
|
||||
// the slow clock is running at 32.768 kHz watchdog
|
||||
// frequency is therefore 32768 / 128 = 256 Hz
|
||||
timeout = (timeout << 8) / 1000;
|
||||
if (timeout == 0)
|
||||
timeout = 1;
|
||||
else if (timeout > 0xFFF)
|
||||
timeout = 0xFFF;
|
||||
|
||||
// We want to enable the watchdog with the specified timeout
|
||||
uint32_t value =
|
||||
WDT_MR_WDV(timeout) | // With the specified timeout
|
||||
WDT_MR_WDD(timeout) | // and no invalid write window
|
||||
#if !(SAMV70 || SAMV71 || SAME70 || SAMS70)
|
||||
WDT_MR_WDRPROC | // WDT fault resets processor only - We want
|
||||
// to keep PIO controller state
|
||||
#endif
|
||||
WDT_MR_WDDBGHLT | // WDT stops in debug state.
|
||||
WDT_MR_WDIDLEHLT; // WDT stops in idle state.
|
||||
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// We enable the watchdog timer, but only for the interrupt.
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
value |= WDT_MR_WDFIEN; // Enable WDT fault interrupt.
|
||||
|
||||
// Disable WDT interrupt (just in case, to avoid triggering it!)
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
|
||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// Initialize WDT with the given parameters
|
||||
WDT_Enable(WDT, value);
|
||||
|
||||
// Configure and enable WDT interrupt.
|
||||
NVIC_ClearPendingIRQ(WDT_IRQn);
|
||||
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
|
||||
#else
|
||||
|
||||
// a WDT fault triggers a reset
|
||||
value |= WDT_MR_WDRSTEN;
|
||||
|
||||
// Initialize WDT with the given parameters
|
||||
WDT_Enable(WDT, value);
|
||||
|
||||
#endif
|
||||
|
||||
// Reset the watchdog
|
||||
WDT_Restart(WDT);
|
||||
|
||||
#else
|
||||
|
||||
// Make sure to completely disable the Watchdog
|
||||
WDT_Disable(WDT);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
extern "C" {
|
||||
extern unsigned int _ebss; // end of bss section
|
||||
}
|
||||
@@ -95,18 +181,9 @@ int freeMemory() {
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// ADC
|
||||
// Serial Ports
|
||||
// ------------------------
|
||||
|
||||
void HAL_adc_start_conversion(const uint8_t ch) {
|
||||
HAL_adc_result = analogRead(ch);
|
||||
}
|
||||
|
||||
uint16_t HAL_adc_get_result() {
|
||||
// nop
|
||||
return HAL_adc_result;
|
||||
}
|
||||
|
||||
// Forward the default serial ports
|
||||
#if USING_HW_SERIAL0
|
||||
DefaultSerial1 MSerial0(false, Serial);
|
||||
|
@@ -32,12 +32,15 @@
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "../../core/serial_hook.h"
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
|
||||
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
|
||||
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
|
||||
@@ -97,60 +100,38 @@ extern DefaultSerial4 MSerial3;
|
||||
#include "MarlinSerial.h"
|
||||
#include "MarlinSerialUSB.h"
|
||||
|
||||
// On AVR this is in math.h?
|
||||
#define square(x) ((x)*(x))
|
||||
// ------------------------
|
||||
// Types
|
||||
// ------------------------
|
||||
|
||||
typedef int8_t pin_t;
|
||||
|
||||
#define SHARED_SERVOS HAS_SERVOS
|
||||
#define HAL_SERVO_LIB Servo
|
||||
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
|
||||
|
||||
class Servo;
|
||||
typedef Servo hal_servo_t;
|
||||
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
|
||||
#define ISRS_ENABLED() (!__get_PRIMASK())
|
||||
#define ENABLE_ISRS() __enable_irq()
|
||||
#define DISABLE_ISRS() __disable_irq()
|
||||
#define sei() interrupts()
|
||||
#define cli() noInterrupts()
|
||||
|
||||
void cli(); // Disable interrupts
|
||||
void sei(); // Enable interrupts
|
||||
|
||||
void HAL_clear_reset_source(); // clear reset reason
|
||||
uint8_t HAL_get_reset_source(); // get reset reason
|
||||
|
||||
void HAL_reboot();
|
||||
#define CRITICAL_SECTION_START() const bool _irqon = hal.isr_state(); hal.isr_off()
|
||||
#define CRITICAL_SECTION_END() if (_irqon) hal.isr_on()
|
||||
|
||||
//
|
||||
// ADC
|
||||
//
|
||||
extern uint16_t HAL_adc_result; // result of last ADC conversion
|
||||
#define HAL_ADC_VREF 3.3
|
||||
#define HAL_ADC_RESOLUTION 10
|
||||
|
||||
#ifndef analogInputToDigitalPin
|
||||
#define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
|
||||
#endif
|
||||
|
||||
#define HAL_ANALOG_SELECT(ch)
|
||||
|
||||
inline void HAL_adc_init() {}//todo
|
||||
|
||||
#define HAL_ADC_VREF 3.3
|
||||
#define HAL_ADC_RESOLUTION 10
|
||||
#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
|
||||
#define HAL_READ_ADC() HAL_adc_result
|
||||
#define HAL_ADC_READY() true
|
||||
|
||||
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
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
@@ -159,27 +140,18 @@ inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255,
|
||||
//
|
||||
// Tone
|
||||
//
|
||||
void toneInit();
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
|
||||
void noTone(const pin_t _pin);
|
||||
|
||||
// Enable hooks into idle and setup for HAL
|
||||
#define HAL_IDLETASK 1
|
||||
void HAL_idletask();
|
||||
void HAL_init();
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
void _delay_ms(const int delay);
|
||||
// ------------------------
|
||||
// Class Utilities
|
||||
// ------------------------
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#ifdef __cplusplus
|
||||
@@ -189,3 +161,73 @@ char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// Return free RAM between end of heap (or end bss) and whatever is current
|
||||
int freeMemory();
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board(); // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return !__get_PRIMASK(); }
|
||||
static void isr_on() { __enable_irq(); }
|
||||
static void isr_off() { __disable_irq(); }
|
||||
|
||||
static void delay_ms(const int ms) { delay(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source() {}
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
static uint16_t adc_result;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const uint8_t ch) {}
|
||||
|
||||
// Begin ADC sampling on the given channel. Called from Temperature::isr!
|
||||
static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return adc_result; }
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* No inverting the duty cycle in this HAL.
|
||||
* No changing the maximum size of the provided value to enable finer PWM duty control in this HAL.
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
|
||||
analogWrite(pin, v);
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -31,8 +31,6 @@
|
||||
|
||||
/**
|
||||
* HAL for Arduino Due and compatible (SAM3X8E)
|
||||
*
|
||||
* For ARDUINO_ARCH_SAM
|
||||
*/
|
||||
|
||||
#ifdef ARDUINO_ARCH_SAM
|
||||
|
@@ -406,7 +406,7 @@ size_t MarlinSerial<Cfg>::write(const uint8_t c) {
|
||||
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
||||
|
||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||
if (!ISRS_ENABLED()) {
|
||||
if (!hal.isr_state()) {
|
||||
|
||||
// Make room by polling if it is possible to transmit, and do so!
|
||||
while (i == tx_buffer.tail) {
|
||||
@@ -454,7 +454,7 @@ void MarlinSerial<Cfg>::flushTX() {
|
||||
if (!_written) return;
|
||||
|
||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||
if (!ISRS_ENABLED()) {
|
||||
if (!hal.isr_state()) {
|
||||
|
||||
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
|
||||
while (tx_buffer.head != tx_buffer.tail || !(HWUART->UART_SR & UART_SR_TXEMPTY)) {
|
||||
|
@@ -118,7 +118,7 @@ public:
|
||||
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; }
|
||||
|
@@ -41,7 +41,7 @@ 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;
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
|
||||
#include "../shared/HAL_MinSerial.h"
|
||||
#include "../shared/MinSerial.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@@ -35,7 +35,7 @@
|
||||
static pin_t tone_pin;
|
||||
volatile static int32_t toggles;
|
||||
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) {
|
||||
tone_pin = _pin;
|
||||
toggles = 2 * frequency * duration / 1000;
|
||||
HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
|
||||
|
@@ -199,8 +199,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
||||
for (i = 0; i <PageSize >> 2; i++)
|
||||
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM PageWrite ", page);
|
||||
DEBUG_ECHO_MSG("EEPROM PageWrite ", page);
|
||||
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
|
||||
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
|
||||
DEBUG_FLUSH();
|
||||
@@ -245,8 +244,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
||||
// Reenable interrupts
|
||||
__enable_irq();
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ", page);
|
||||
DEBUG_ECHO_MSG("EEPROM Unlock failure for page ", page);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -270,8 +268,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
||||
// Reenable interrupts
|
||||
__enable_irq();
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Write failure for page ", page);
|
||||
DEBUG_ECHO_MSG("EEPROM Write failure for page ", page);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -286,8 +283,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
||||
if (memcmp(getFlashStorage(page),data,PageSize)) {
|
||||
|
||||
#ifdef EE_EMU_DEBUG
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Verify Write failure for page ", page);
|
||||
DEBUG_ECHO_MSG("EEPROM Verify Write failure for page ", page);
|
||||
|
||||
ee_Dump( page, (uint32_t *)addrflash);
|
||||
ee_Dump(-page, data);
|
||||
@@ -325,8 +321,7 @@ static bool ee_PageErase(uint16_t page) {
|
||||
uint16_t i;
|
||||
uint32_t addrflash = uint32_t(getFlashStorage(page));
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM PageErase ", page);
|
||||
DEBUG_ECHO_MSG("EEPROM PageErase ", page);
|
||||
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
|
||||
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
|
||||
DEBUG_FLUSH();
|
||||
@@ -370,8 +365,7 @@ static bool ee_PageErase(uint16_t page) {
|
||||
// Reenable interrupts
|
||||
__enable_irq();
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ",page);
|
||||
DEBUG_ECHO_MSG("EEPROM Unlock failure for page ",page);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -394,8 +388,7 @@ static bool ee_PageErase(uint16_t page) {
|
||||
// Reenable interrupts
|
||||
__enable_irq();
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Erase failure for page ",page);
|
||||
DEBUG_ECHO_MSG("EEPROM Erase failure for page ",page);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -410,8 +403,7 @@ static bool ee_PageErase(uint16_t page) {
|
||||
uint32_t * aligned_src = (uint32_t *) addrflash;
|
||||
for (i = 0; i < PageSize >> 2; i++) {
|
||||
if (*aligned_src++ != 0xFFFFFFFF) {
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Verify Erase failure for page ",page);
|
||||
DEBUG_ECHO_MSG("EEPROM Verify Erase failure for page ",page);
|
||||
ee_Dump(page, (uint32_t *)addrflash);
|
||||
return false;
|
||||
}
|
||||
@@ -921,8 +913,7 @@ static void ee_Init() {
|
||||
// If all groups seem to be used, default to first group
|
||||
if (curGroup >= GroupCount) curGroup = 0;
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Current Group: ",curGroup);
|
||||
DEBUG_ECHO_MSG("EEPROM Current Group: ",curGroup);
|
||||
DEBUG_FLUSH();
|
||||
|
||||
// Now, validate that all the other group pages are empty
|
||||
@@ -931,8 +922,7 @@ static void ee_Init() {
|
||||
|
||||
for (int page = 0; page < PagesPerGroup; page++) {
|
||||
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on group ", grp);
|
||||
DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on group ", grp);
|
||||
DEBUG_FLUSH();
|
||||
ee_PageErase(grp * PagesPerGroup + page);
|
||||
}
|
||||
@@ -948,15 +938,13 @@ static void ee_Init() {
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_ECHO_START();
|
||||
DEBUG_ECHOLNPGM("EEPROM Active page: ", curPage);
|
||||
DEBUG_ECHO_MSG("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_ECHOLNPGM("EEPROM Page ", page, " not clean on active group ", curGroup);
|
||||
DEBUG_ECHO_MSG("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);
|
||||
|
@@ -70,4 +70,10 @@ void setup_endstop_interrupts() {
|
||||
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
|
||||
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
|
||||
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
|
||||
TERN_(HAS_U_MAX, _ATTACH(U_MAX_PIN));
|
||||
TERN_(HAS_U_MIN, _ATTACH(U_MIN_PIN));
|
||||
TERN_(HAS_V_MAX, _ATTACH(V_MAX_PIN));
|
||||
TERN_(HAS_V_MIN, _ATTACH(V_MIN_PIN));
|
||||
TERN_(HAS_W_MAX, _ATTACH(W_MAX_PIN));
|
||||
TERN_(HAS_W_MIN, _ATTACH(W_MIN_PIN));
|
||||
}
|
||||
|
@@ -25,7 +25,7 @@
|
||||
* is NOT used to directly toggle pins. The ISR writes to the pin assigned to
|
||||
* that interrupt.
|
||||
*
|
||||
* All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to
|
||||
* All PWMs use the same repetition rate. The G2 needs about 10kHz min in order to
|
||||
* not have obvious ripple on the Vref signals.
|
||||
*
|
||||
* The data structures are setup to minimize the computation done by the ISR which
|
||||
|
@@ -25,6 +25,30 @@
|
||||
* Test Arduino Due specific configuration values for errors at compile-time.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Check for common serial pin conflicts
|
||||
*/
|
||||
#define CHECK_SERIAL_PIN(N) ( \
|
||||
X_STOP_PIN == N || Y_STOP_PIN == N || Z_STOP_PIN == N \
|
||||
|| X_MIN_PIN == N || Y_MIN_PIN == N || Z_MIN_PIN == N \
|
||||
|| X_MAX_PIN == N || Y_MAX_PIN == N || Z_MAX_PIN == N \
|
||||
|| X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_PIN == N \
|
||||
|| X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \
|
||||
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
|
||||
)
|
||||
#if CONF_SERIAL_IS(0) // D0-D1. No known conflicts.
|
||||
#endif
|
||||
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19))
|
||||
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
|
||||
#endif
|
||||
#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
|
||||
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
|
||||
#endif
|
||||
#if CONF_SERIAL_IS(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15))
|
||||
#error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board."
|
||||
#endif
|
||||
#undef CHECK_SERIAL_PIN
|
||||
|
||||
/**
|
||||
* HARDWARE VS. SOFTWARE SPI COMPATIBILITY
|
||||
*
|
||||
@@ -59,3 +83,7 @@
|
||||
#if HAS_TMC_SW_SERIAL
|
||||
#error "TMC220x Software Serial is not supported on the DUE platform."
|
||||
#endif
|
||||
|
||||
#if USING_PULLDOWNS
|
||||
#error "PULLDOWN pin mode is not available on DUE boards."
|
||||
#endif
|
||||
|
@@ -53,7 +53,7 @@
|
||||
* The net result is that both the g_pinStatus[pin] array and the PIO_OSR register
|
||||
* needs to be looked at when determining if a pin is an input or an output.
|
||||
*
|
||||
* b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1KHz
|
||||
* b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1kHz
|
||||
*
|
||||
* c) NUM_DIGITAL_PINS does not include the analog pins
|
||||
*
|
||||
@@ -86,7 +86,6 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
|
||||
|| pwm_status(pin));
|
||||
}
|
||||
|
||||
|
||||
void pwm_details(int32_t pin) {
|
||||
if (pwm_status(pin)) {
|
||||
uint32_t chan = g_APinDescription[pin].ulPWMChannel;
|
||||
|
@@ -125,4 +125,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
|
||||
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
|
||||
}
|
||||
|
||||
#define HAL_timer_isr_epilogue(T)
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
|
@@ -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
|
||||
|
@@ -1,114 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef ARDUINO_ARCH_SAM
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../../MarlinCore.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
// Override Arduino runtime to either config or disable the watchdog
|
||||
//
|
||||
// We need to configure the watchdog as soon as possible in the boot
|
||||
// process, because watchdog initialization at hardware reset on SAM3X8E
|
||||
// is unreliable, and there is risk of unintended resets if we delay
|
||||
// that initialization to a later time.
|
||||
void watchdogSetup() {
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
// 4 seconds timeout
|
||||
uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000);
|
||||
|
||||
// Calculate timeout value in WDT counter ticks: This assumes
|
||||
// the slow clock is running at 32.768 kHz watchdog
|
||||
// frequency is therefore 32768 / 128 = 256 Hz
|
||||
timeout = (timeout << 8) / 1000;
|
||||
if (timeout == 0)
|
||||
timeout = 1;
|
||||
else if (timeout > 0xFFF)
|
||||
timeout = 0xFFF;
|
||||
|
||||
// We want to enable the watchdog with the specified timeout
|
||||
uint32_t value =
|
||||
WDT_MR_WDV(timeout) | // With the specified timeout
|
||||
WDT_MR_WDD(timeout) | // and no invalid write window
|
||||
#if !(SAMV70 || SAMV71 || SAME70 || SAMS70)
|
||||
WDT_MR_WDRPROC | // WDT fault resets processor only - We want
|
||||
// to keep PIO controller state
|
||||
#endif
|
||||
WDT_MR_WDDBGHLT | // WDT stops in debug state.
|
||||
WDT_MR_WDIDLEHLT; // WDT stops in idle state.
|
||||
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// We enable the watchdog timer, but only for the interrupt.
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
value |= WDT_MR_WDFIEN; // Enable WDT fault interrupt.
|
||||
|
||||
// Disable WDT interrupt (just in case, to avoid triggering it!)
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
|
||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// Initialize WDT with the given parameters
|
||||
WDT_Enable(WDT, value);
|
||||
|
||||
// Configure and enable WDT interrupt.
|
||||
NVIC_ClearPendingIRQ(WDT_IRQn);
|
||||
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
|
||||
#else
|
||||
|
||||
// a WDT fault triggers a reset
|
||||
value |= WDT_MR_WDRSTEN;
|
||||
|
||||
// Initialize WDT with the given parameters
|
||||
WDT_Enable(WDT, value);
|
||||
|
||||
#endif
|
||||
|
||||
// Reset the watchdog
|
||||
WDT_Restart(WDT);
|
||||
|
||||
#else
|
||||
|
||||
// Make sure to completely disable the Watchdog
|
||||
WDT_Disable(WDT);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
// Initialize watchdog - On SAM3X, Watchdog was already configured
|
||||
// and enabled or disabled at startup, so no need to reconfigure it
|
||||
// here.
|
||||
void watchdog_init() {
|
||||
// Reset watchdog to start clean
|
||||
WDT_Restart(WDT);
|
||||
}
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
#endif
|
@@ -1,33 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Arduino Due core now has watchdog support
|
||||
|
||||
#include "HAL.h"
|
||||
|
||||
// Initialize watchdog with a 4 second interrupt time
|
||||
void watchdog_init();
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or AVR will go into emergency procedures.
|
||||
inline void HAL_watchdog_refresh() { watchdogReset(); }
|
@@ -52,7 +52,7 @@
|
||||
// Externs
|
||||
// ------------------------
|
||||
|
||||
portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
portMUX_TYPE MarlinHAL::spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
// ------------------------
|
||||
// Local defines
|
||||
@@ -64,7 +64,7 @@ portMUX_TYPE spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
// Public Variables
|
||||
// ------------------------
|
||||
|
||||
uint16_t HAL_adc_result;
|
||||
uint16_t MarlinHAL::adc_result;
|
||||
|
||||
// ------------------------
|
||||
// Private Variables
|
||||
@@ -73,9 +73,16 @@ uint16_t HAL_adc_result;
|
||||
esp_adc_cal_characteristics_t characteristics[ADC_ATTEN_MAX];
|
||||
adc_atten_t attenuations[ADC1_CHANNEL_MAX] = {};
|
||||
uint32_t thresholds[ADC_ATTEN_MAX];
|
||||
volatile int numPWMUsed = 0,
|
||||
pwmPins[MAX_PWM_PINS],
|
||||
pwmValues[MAX_PWM_PINS];
|
||||
|
||||
volatile int numPWMUsed = 0;
|
||||
volatile struct { pin_t pin; int value; } pwmState[MAX_PWM_PINS];
|
||||
|
||||
pin_t chan_pin[CHANNEL_MAX_NUM + 1] = { 0 }; // PWM capable IOpins - not 0 or >33 on ESP32
|
||||
|
||||
struct {
|
||||
uint32_t freq; // ledcReadFreq doesn't work if a duty hasn't been set yet!
|
||||
uint16_t res;
|
||||
} pwmInfo[(CHANNEL_MAX_NUM + 1) / 2];
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
@@ -95,20 +102,22 @@ volatile int numPWMUsed = 0,
|
||||
#endif
|
||||
|
||||
#if ENABLED(USE_ESP32_EXIO)
|
||||
|
||||
HardwareSerial YSerial2(2);
|
||||
|
||||
void Write_EXIO(uint8_t IO, uint8_t v) {
|
||||
if (ISRS_ENABLED()) {
|
||||
DISABLE_ISRS();
|
||||
if (hal.isr_state()) {
|
||||
hal.isr_off();
|
||||
YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
|
||||
ENABLE_ISRS();
|
||||
hal.isr_on();
|
||||
}
|
||||
else
|
||||
YSerial2.write(0x80 | (((char)v) << 5) | (IO - 100));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void HAL_init_board() {
|
||||
void MarlinHAL::init_board() {
|
||||
#if ENABLED(USE_ESP32_TASK_WDT)
|
||||
esp_task_wdt_init(10, true);
|
||||
#endif
|
||||
@@ -154,27 +163,51 @@ void HAL_init_board() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_idletask() {
|
||||
void MarlinHAL::idletask() {
|
||||
#if BOTH(WIFISUPPORT, OTASUPPORT)
|
||||
OTA_handle();
|
||||
#endif
|
||||
TERN_(ESP3D_WIFISUPPORT, esp3dlib.idletask());
|
||||
}
|
||||
|
||||
void HAL_clear_reset_source() { }
|
||||
uint8_t MarlinHAL::get_reset_source() { return rtc_get_reset_reason(1); }
|
||||
|
||||
uint8_t HAL_get_reset_source() { return rtc_get_reset_reason(1); }
|
||||
|
||||
void HAL_reboot() { ESP.restart(); }
|
||||
void MarlinHAL::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
|
||||
int freeMemory() { return ESP.getFreeHeap(); }
|
||||
int MarlinHAL::freeMemory() { return ESP.getFreeHeap(); }
|
||||
|
||||
// ------------------------
|
||||
// Watchdog Timer
|
||||
// ------------------------
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
|
||||
|
||||
extern "C" {
|
||||
esp_err_t esp_task_wdt_reset();
|
||||
}
|
||||
|
||||
void watchdogSetup() {
|
||||
// do whatever. don't remove this function.
|
||||
}
|
||||
|
||||
void MarlinHAL::watchdog_init() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
// Reset watchdog.
|
||||
void MarlinHAL::watchdog_refresh() { esp_task_wdt_reset(); }
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------
|
||||
// ADC
|
||||
// ------------------------
|
||||
|
||||
#define ADC1_CHANNEL(pin) ADC1_GPIO ## pin ## _CHANNEL
|
||||
|
||||
adc1_channel_t get_channel(int pin) {
|
||||
@@ -196,22 +229,24 @@ void adc1_set_attenuation(adc1_channel_t chan, adc_atten_t atten) {
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_adc_init() {
|
||||
void MarlinHAL::adc_init() {
|
||||
// Configure ADC
|
||||
adc1_config_width(ADC_WIDTH_12Bit);
|
||||
|
||||
// Configure channels only if used as (re-)configuring a pin for ADC that is used elsewhere might have adverse effects
|
||||
TERN_(HAS_TEMP_ADC_0, adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_1, adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_2, adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_3, adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_4, adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_5, adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_6, adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_0, adc1_set_attenuation(get_channel(TEMP_0_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_1, adc1_set_attenuation(get_channel(TEMP_1_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_2, adc1_set_attenuation(get_channel(TEMP_2_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_3, adc1_set_attenuation(get_channel(TEMP_3_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_4, adc1_set_attenuation(get_channel(TEMP_4_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_5, adc1_set_attenuation(get_channel(TEMP_5_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_6, adc2_set_attenuation(get_channel(TEMP_6_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_PROBE, adc1_set_attenuation(get_channel(TEMP_PROBE_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
|
||||
TERN_(HAS_TEMP_BOARD, adc1_set_attenuation(get_channel(TEMP_BOARD_PIN), ADC_ATTEN_11db));
|
||||
TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
|
||||
|
||||
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
|
||||
@@ -226,11 +261,16 @@ void HAL_adc_init() {
|
||||
}
|
||||
}
|
||||
|
||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
|
||||
const adc1_channel_t chan = get_channel(adc_pin);
|
||||
#ifndef ADC_REFERENCE_VOLTAGE
|
||||
#define ADC_REFERENCE_VOLTAGE 3.3
|
||||
#endif
|
||||
|
||||
void MarlinHAL::adc_start(const pin_t pin) {
|
||||
const adc1_channel_t chan = get_channel(pin);
|
||||
uint32_t mv;
|
||||
esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
|
||||
HAL_adc_result = mv * 1023.0 / 3300.0;
|
||||
|
||||
adc_result = mv * isr_float_t(1023) / isr_float_t(ADC_REFERENCE_VOLTAGE) / isr_float_t(1000);
|
||||
|
||||
// Change the attenuation level based on the new reading
|
||||
adc_atten_t atten;
|
||||
@@ -247,25 +287,81 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
|
||||
adc1_set_attenuation(chan, atten);
|
||||
}
|
||||
|
||||
void analogWrite(pin_t pin, int value) {
|
||||
// Use ledc hardware for internal pins
|
||||
if (pin < 34) {
|
||||
static int cnt_channel = 1, pin_to_channel[40] = { 0 };
|
||||
if (pin_to_channel[pin] == 0) {
|
||||
ledcAttachPin(pin, cnt_channel);
|
||||
ledcSetup(cnt_channel, 490, 8);
|
||||
ledcWrite(cnt_channel, value);
|
||||
pin_to_channel[pin] = cnt_channel++;
|
||||
// ------------------------
|
||||
// PWM
|
||||
// ------------------------
|
||||
|
||||
int8_t channel_for_pin(const uint8_t pin) {
|
||||
for (int i = 0; i <= CHANNEL_MAX_NUM; i++)
|
||||
if (chan_pin[i] == pin) return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// get PWM channel for pin - if none then attach a new one
|
||||
// return -1 if fail or invalid pin#, channel # (0-15) if success
|
||||
int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res) {
|
||||
if (!WITHIN(pin, 1, MAX_PWM_IOPIN)) return -1; // Not a hardware PWM pin!
|
||||
int8_t cid = channel_for_pin(pin);
|
||||
if (cid >= 0) return cid;
|
||||
|
||||
// Find an empty adjacent channel (same timer & freq/res)
|
||||
for (int i = 0; i <= CHANNEL_MAX_NUM; i++) {
|
||||
if (chan_pin[i] == 0) {
|
||||
if (chan_pin[i ^ 0x1] != 0) {
|
||||
if (pwmInfo[i / 2].freq == freq && pwmInfo[i / 2].res == res) {
|
||||
chan_pin[i] = pin; // Allocate PWM to this channel
|
||||
ledcAttachPin(pin, i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else if (cid == -1) // Pair of empty channels?
|
||||
cid = i & 0xFE; // Save lower channel number
|
||||
}
|
||||
ledcWrite(pin_to_channel[pin], value);
|
||||
}
|
||||
// not attached, is an empty timer slot avail?
|
||||
if (cid >= 0) {
|
||||
chan_pin[cid] = pin;
|
||||
pwmInfo[cid / 2].freq = freq;
|
||||
pwmInfo[cid / 2].res = res;
|
||||
ledcSetup(cid, freq, res);
|
||||
ledcAttachPin(pin, cid);
|
||||
}
|
||||
return cid; // -1 if no channel avail
|
||||
}
|
||||
|
||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=_BV(PWM_RESOLUTION)-1*/, const bool invert/*=false*/) {
|
||||
const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION);
|
||||
if (cid >= 0) {
|
||||
uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1);
|
||||
ledcWrite(cid, duty);
|
||||
}
|
||||
}
|
||||
|
||||
int8_t MarlinHAL::set_pwm_frequency(const pin_t pin, const uint32_t f_desired) {
|
||||
const int8_t cid = channel_for_pin(pin);
|
||||
if (cid >= 0) {
|
||||
if (f_desired == ledcReadFreq(cid)) return cid; // no freq change
|
||||
ledcDetachPin(chan_pin[cid]);
|
||||
chan_pin[cid] = 0; // remove old freq channel
|
||||
}
|
||||
return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one
|
||||
}
|
||||
|
||||
// use hardware PWM if avail, if not then ISR
|
||||
void analogWrite(const pin_t pin, const uint16_t value, const uint32_t freq/*=PWM_FREQUENCY*/, const uint16_t res/*=8*/) { // always 8 bit resolution!
|
||||
// Use ledc hardware for internal pins
|
||||
const int8_t cid = get_pwm_channel(pin, freq, res);
|
||||
if (cid >= 0) {
|
||||
ledcWrite(cid, value); // set duty value
|
||||
return;
|
||||
}
|
||||
|
||||
// not a hardware PWM pin OR no PWM channels available
|
||||
int idx = -1;
|
||||
|
||||
// Search Pin
|
||||
for (int i = 0; i < numPWMUsed; ++i)
|
||||
if (pwmPins[i] == pin) { idx = i; break; }
|
||||
if (pwmState[i].pin == pin) { idx = i; break; }
|
||||
|
||||
// not found ?
|
||||
if (idx < 0) {
|
||||
@@ -274,7 +370,7 @@ void analogWrite(pin_t pin, int value) {
|
||||
|
||||
// Take new slot for pin
|
||||
idx = numPWMUsed;
|
||||
pwmPins[idx] = pin;
|
||||
pwmState[idx].pin = pin;
|
||||
// Start timer on first use
|
||||
if (idx == 0) HAL_timer_start(MF_TIMER_PWM, PWM_TIMER_FREQUENCY);
|
||||
|
||||
@@ -282,7 +378,7 @@ void analogWrite(pin_t pin, int value) {
|
||||
}
|
||||
|
||||
// Use 7bit internal value - add 1 to have 100% high at 255
|
||||
pwmValues[idx] = (value + 1) / 2;
|
||||
pwmState[idx].value = (value + 1) / 2;
|
||||
}
|
||||
|
||||
// Handle PWM timer interrupt
|
||||
@@ -293,9 +389,9 @@ HAL_PWM_TIMER_ISR() {
|
||||
|
||||
for (int i = 0; i < numPWMUsed; ++i) {
|
||||
if (count == 0) // Start of interval
|
||||
WRITE(pwmPins[i], pwmValues[i] ? HIGH : LOW);
|
||||
else if (pwmValues[i] == count) // End of duration
|
||||
WRITE(pwmPins[i], LOW);
|
||||
digitalWrite(pwmState[i].pin, pwmState[i].value ? HIGH : LOW);
|
||||
else if (pwmState[i].value == count) // End of duration
|
||||
digitalWrite(pwmState[i].pin, LOW);
|
||||
}
|
||||
|
||||
// 128 for 7 Bit resolution
|
||||
|
@@ -32,7 +32,6 @@
|
||||
#include "../shared/HAL_SPI.h"
|
||||
|
||||
#include "fastio.h"
|
||||
#include "watchdog.h"
|
||||
#include "i2s.h"
|
||||
|
||||
#if ENABLED(WIFISUPPORT)
|
||||
@@ -49,8 +48,6 @@
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
extern portMUX_TYPE spinlock;
|
||||
|
||||
#define MYSERIAL1 flushableSerial
|
||||
|
||||
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
|
||||
@@ -65,24 +62,22 @@ extern portMUX_TYPE spinlock;
|
||||
|
||||
#define CRITICAL_SECTION_START() portENTER_CRITICAL(&spinlock)
|
||||
#define CRITICAL_SECTION_END() portEXIT_CRITICAL(&spinlock)
|
||||
#define ISRS_ENABLED() (spinlock.owner == portMUX_FREE_VAL)
|
||||
#define ENABLE_ISRS() if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock)
|
||||
#define DISABLE_ISRS() portENTER_CRITICAL(&spinlock)
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
#define PWM_FREQUENCY 1000u // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency()
|
||||
#define PWM_RESOLUTION 10u // Default PWM bit resolution
|
||||
#define CHANNEL_MAX_NUM 15u // max PWM channel # to allocate (7 to only use low speed, 15 to use low & high)
|
||||
#define MAX_PWM_IOPIN 33u // hardware pwm pins < 34
|
||||
|
||||
// ------------------------
|
||||
// Types
|
||||
// ------------------------
|
||||
|
||||
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
|
||||
typedef int16_t pin_t;
|
||||
|
||||
#define HAL_SERVO_LIB Servo
|
||||
|
||||
// ------------------------
|
||||
// Public Variables
|
||||
// ------------------------
|
||||
|
||||
/** result of last ADC conversion */
|
||||
extern uint16_t HAL_adc_result;
|
||||
class Servo;
|
||||
typedef Servo hal_servo_t;
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
@@ -91,59 +86,18 @@ extern uint16_t HAL_adc_result;
|
||||
//
|
||||
// Tone
|
||||
//
|
||||
void toneInit();
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
|
||||
void noTone(const pin_t _pin);
|
||||
int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res);
|
||||
void analogWrite(const pin_t pin, const uint16_t value, const uint32_t freq=PWM_FREQUENCY, const uint16_t res=8);
|
||||
|
||||
// clear reset reason
|
||||
void HAL_clear_reset_source();
|
||||
|
||||
// reset reason
|
||||
uint8_t HAL_get_reset_source();
|
||||
|
||||
void HAL_reboot();
|
||||
|
||||
void _delay_ms(int delay);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void analogWrite(pin_t pin, int value);
|
||||
|
||||
// ADC
|
||||
#define HAL_ANALOG_SELECT(pin)
|
||||
|
||||
void HAL_adc_init();
|
||||
|
||||
#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
|
||||
|
||||
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
|
||||
//
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
|
||||
// Enable hooks into idle and setup for HAL
|
||||
#define HAL_IDLETASK 1
|
||||
#define BOARD_INIT() HAL_init_board();
|
||||
void HAL_idletask();
|
||||
inline void HAL_init() {}
|
||||
void HAL_init_board();
|
||||
|
||||
#if ENABLED(USE_ESP32_EXIO)
|
||||
void Write_EXIO(uint8_t IO, uint8_t v);
|
||||
#endif
|
||||
@@ -188,3 +142,94 @@ FORCE_INLINE static void DELAY_CYCLES(uint32_t x) {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// Class Utilities
|
||||
// ------------------------
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
void _delay_ms(const int ms);
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
#define HAL_ADC_VREF 3.3
|
||||
#define HAL_ADC_RESOLUTION 10
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
static void init() {} // Called early in setup()
|
||||
static void init_board(); // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware
|
||||
|
||||
// Interrupts
|
||||
static portMUX_TYPE spinlock;
|
||||
static bool isr_state() { return spinlock.owner == portMUX_FREE_VAL; }
|
||||
static void isr_on() { if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock); }
|
||||
static void isr_off() { portENTER_CRITICAL(&spinlock); }
|
||||
|
||||
static void delay_ms(const int ms) { _delay_ms(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source() {}
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory();
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
static uint16_t adc_result;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init();
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const pin_t pin) {}
|
||||
|
||||
// Begin ADC sampling on the given pin. Called from Temperature::isr!
|
||||
static void adc_start(const pin_t pin);
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return adc_result; }
|
||||
|
||||
/**
|
||||
* If not already allocated, allocate a hardware PWM channel
|
||||
* to the pin and set the duty cycle..
|
||||
* Optionally invert the duty cycle [default = false]
|
||||
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
/**
|
||||
* Allocate and set the frequency of a hardware PWM pin
|
||||
* Returns -1 if no pin available.
|
||||
*/
|
||||
static int8_t set_pwm_frequency(const pin_t pin, const uint32_t f_desired);
|
||||
|
||||
};
|
||||
|
@@ -31,20 +31,18 @@
|
||||
// so we only allocate servo channels up high to avoid side effects with regards to analogWrite (fans, leds, laser pwm etc.)
|
||||
int Servo::channel_next_free = 12;
|
||||
|
||||
Servo::Servo() {
|
||||
channel = channel_next_free++;
|
||||
}
|
||||
Servo::Servo() {}
|
||||
|
||||
int8_t Servo::attach(const int inPin) {
|
||||
if (channel >= CHANNEL_MAX_NUM) return -1;
|
||||
if (inPin > 0) pin = inPin;
|
||||
|
||||
ledcSetup(channel, 50, 16); // channel X, 50 Hz, 16-bit depth
|
||||
ledcAttachPin(pin, channel);
|
||||
return true;
|
||||
channel = get_pwm_channel(pin, 50u, 16u);
|
||||
return channel; // -1 if no PWM avail.
|
||||
}
|
||||
|
||||
void Servo::detach() { ledcDetachPin(pin); }
|
||||
// leave channel connected to servo - set duty to zero
|
||||
void Servo::detach() {
|
||||
if (channel >= 0) ledcWrite(channel, 0);
|
||||
}
|
||||
|
||||
int Servo::read() { return degrees; }
|
||||
|
||||
@@ -52,7 +50,7 @@ void Servo::write(int inDegrees) {
|
||||
degrees = constrain(inDegrees, MIN_ANGLE, MAX_ANGLE);
|
||||
int us = map(degrees, MIN_ANGLE, MAX_ANGLE, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
|
||||
int duty = map(us, 0, TAU_USEC, 0, MAX_COMPARE);
|
||||
ledcWrite(channel, duty);
|
||||
if (channel >= 0) ledcWrite(channel, duty); // don't save duty for servos!
|
||||
}
|
||||
|
||||
void Servo::move(const int value) {
|
||||
|
@@ -30,8 +30,7 @@ class Servo {
|
||||
MAX_PULSE_WIDTH = 2400, // Longest pulse sent to a servo
|
||||
TAU_MSEC = 20,
|
||||
TAU_USEC = (TAU_MSEC * 1000),
|
||||
MAX_COMPARE = _BV(16) - 1, // 65535
|
||||
CHANNEL_MAX_NUM = 16;
|
||||
MAX_COMPARE = _BV(16) - 1; // 65535
|
||||
|
||||
public:
|
||||
Servo();
|
||||
|
@@ -35,7 +35,7 @@
|
||||
static pin_t tone_pin;
|
||||
volatile static int32_t toggles;
|
||||
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) {
|
||||
tone_pin = _pin;
|
||||
toggles = 2 * frequency * duration / 1000;
|
||||
HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
|
||||
|
@@ -65,4 +65,10 @@ void setup_endstop_interrupts() {
|
||||
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
|
||||
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
|
||||
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
|
||||
TERN_(HAS_U_MAX, _ATTACH(U_MAX_PIN));
|
||||
TERN_(HAS_U_MIN, _ATTACH(U_MIN_PIN));
|
||||
TERN_(HAS_V_MAX, _ATTACH(V_MAX_PIN));
|
||||
TERN_(HAS_V_MIN, _ATTACH(V_MIN_PIN));
|
||||
TERN_(HAS_W_MAX, _ATTACH(W_MAX_PIN));
|
||||
TERN_(HAS_W_MIN, _ATTACH(W_MIN_PIN));
|
||||
}
|
||||
|
@@ -25,8 +25,8 @@
|
||||
#error "EMERGENCY_PARSER is not yet implemented for ESP32. Disable EMERGENCY_PARSER to continue."
|
||||
#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 ESP32."
|
||||
#if (ENABLED(SPINDLE_LASER_USE_PWM) && SPINDLE_LASER_FREQUENCY > 78125) || (ENABLED(FAST_PWM_FAN_FREQUENCY) && FAST_PWM_FAN_FREQUENCY > 78125)
|
||||
#error "SPINDLE_LASER_FREQUENCY and FAST_PWM_FREQUENCY maximum value is 78125Hz for ESP32."
|
||||
#endif
|
||||
|
||||
#if HAS_TMC_SW_SERIAL
|
||||
@@ -40,3 +40,11 @@
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
#error "POSTMORTEM_DEBUGGING is not yet supported on ESP32."
|
||||
#endif
|
||||
|
||||
#if MB(MKS_TINYBEE) && ENABLED(FAST_PWM_FAN)
|
||||
#error "FAST_PWM_FAN is not available on TinyBee."
|
||||
#endif
|
||||
|
||||
#if USING_PULLDOWNS
|
||||
#error "PULLDOWN pin mode is not available on ESP32 boards."
|
||||
#endif
|
||||
|
@@ -81,7 +81,7 @@ void IRAM_ATTR timer_isr(void *para) {
|
||||
* @param timer_num timer number to initialize
|
||||
* @param frequency frequency of the timer
|
||||
*/
|
||||
void HAL_timer_start(const uint8_t timer_num, uint32_t frequency) {
|
||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
||||
const tTimerConfig timer = timer_config[timer_num];
|
||||
|
||||
timer_config_t config;
|
||||
|
@@ -127,7 +127,7 @@ extern const tTimerConfig timer_config[];
|
||||
// Public functions
|
||||
// ------------------------
|
||||
|
||||
void HAL_timer_start (const uint8_t timer_num, uint32_t frequency);
|
||||
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 count);
|
||||
hal_timer_t HAL_timer_get_compare(const uint8_t timer_num);
|
||||
hal_timer_t HAL_timer_get_count(const uint8_t timer_num);
|
||||
@@ -136,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(T)
|
||||
#define HAL_timer_isr_epilogue(T)
|
||||
#define HAL_timer_isr_prologue(T) NOOP
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
|
94
Marlin/src/HAL/ESP32/u8g_esp32_spi.cpp
Normal file
94
Marlin/src/HAL/ESP32/u8g_esp32_spi.cpp
Normal file
@@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2022 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if EITHER(MKS_MINI_12864, FYSETC_MINI_12864_2_1)
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "HAL.h"
|
||||
#include "SPI.h"
|
||||
|
||||
static SPISettings spiConfig;
|
||||
|
||||
|
||||
#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_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
|
||||
if (msgInitCount) {
|
||||
if (msg == U8G_COM_MSG_INIT) msgInitCount--;
|
||||
if (msgInitCount) return -1;
|
||||
}
|
||||
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_STOP: break;
|
||||
|
||||
case U8G_COM_MSG_INIT:
|
||||
OUT_WRITE(DOGLCD_CS, HIGH);
|
||||
OUT_WRITE(DOGLCD_A0, HIGH);
|
||||
OUT_WRITE(LCD_RESET_PIN, HIGH);
|
||||
u8g_Delay(5);
|
||||
spiBegin();
|
||||
spiInit(LCD_SPI_SPEED);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
WRITE(DOGLCD_A0, arg_val ? HIGH : LOW);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT: /* arg_val == 0 means HIGH level of U8G_PI_CS */
|
||||
WRITE(DOGLCD_CS, arg_val ? LOW : HIGH);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
WRITE(LCD_RESET_PIN, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
spiSend((uint8_t)arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ:
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
spiSend(*ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // EITHER(MKS_MINI_12864, FYSETC_MINI_12864_2_1)
|
||||
|
||||
#endif // ARDUINO_ARCH_ESP32
|
@@ -1,42 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef ARDUINO_ARCH_ESP32
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
|
||||
|
||||
#include "watchdog.h"
|
||||
|
||||
void watchdogSetup() {
|
||||
// do whatever. don't remove this function.
|
||||
}
|
||||
|
||||
void watchdog_init() {
|
||||
// TODO
|
||||
}
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
#endif // ARDUINO_ARCH_ESP32
|
@@ -28,6 +28,7 @@
|
||||
#endif
|
||||
|
||||
#include HAL_PATH(.,HAL.h)
|
||||
extern MarlinHAL hal;
|
||||
|
||||
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
|
||||
|
||||
@@ -44,7 +45,3 @@
|
||||
#ifndef PGMSTR
|
||||
#define PGMSTR(NAM,STR) const char NAM[] = STR
|
||||
#endif
|
||||
|
||||
inline void watchdog_refresh() {
|
||||
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
|
||||
}
|
||||
|
@@ -24,6 +24,10 @@
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../shared/Delay.h"
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true));
|
||||
|
||||
// U8glib required functions
|
||||
@@ -37,42 +41,21 @@ extern "C" {
|
||||
//************************//
|
||||
|
||||
// return free heap space
|
||||
int freeMemory() {
|
||||
return 0;
|
||||
}
|
||||
int freeMemory() { return 0; }
|
||||
|
||||
// ------------------------
|
||||
// ADC
|
||||
// ------------------------
|
||||
|
||||
void HAL_adc_init() {
|
||||
uint8_t MarlinHAL::active_ch = 0;
|
||||
|
||||
}
|
||||
|
||||
void HAL_adc_enable_channel(const uint8_t ch) {
|
||||
|
||||
}
|
||||
|
||||
uint8_t active_ch = 0;
|
||||
void HAL_adc_start_conversion(const uint8_t ch) {
|
||||
active_ch = ch;
|
||||
}
|
||||
|
||||
bool HAL_adc_finished() {
|
||||
return true;
|
||||
}
|
||||
|
||||
uint16_t HAL_adc_get_result() {
|
||||
pin_t pin = analogInputToDigitalPin(active_ch);
|
||||
uint16_t MarlinHAL::adc_value() {
|
||||
const pin_t pin = analogInputToDigitalPin(active_ch);
|
||||
if (!VALID_PIN(pin)) return 0;
|
||||
uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF);
|
||||
const uint16_t data = ((Gpio::get(pin) >> 2) & 0x3FF);
|
||||
return data; // return 10bit value as Marlin expects
|
||||
}
|
||||
|
||||
void HAL_pwm_init() {
|
||||
|
||||
}
|
||||
|
||||
void HAL_reboot() { /* Reset the application state and GPIO */ }
|
||||
void MarlinHAL::reboot() { /* Reset the application state and GPIO */ }
|
||||
|
||||
#endif // __PLAT_LINUX__
|
||||
|
@@ -21,25 +21,42 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define CPU_32_BIT
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
|
||||
#define F_CPU 100000000UL
|
||||
#define SystemCoreClock F_CPU
|
||||
#include <iostream>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
void _printf (const char *format, ...);
|
||||
#include "hardware/Clock.h"
|
||||
#include "../shared/Marduino.h"
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "serial.h"
|
||||
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
#define CPU_32_BIT
|
||||
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
|
||||
|
||||
#define F_CPU 100000000UL
|
||||
#define SystemCoreClock F_CPU
|
||||
|
||||
#define DELAY_CYCLES(x) Clock::delayCycles(x)
|
||||
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
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
|
||||
@@ -49,36 +66,27 @@ uint8_t _getc();
|
||||
#define B01 1
|
||||
#define B10 2
|
||||
|
||||
#include "hardware/Clock.h"
|
||||
|
||||
#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
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
extern MSerialT usb_serial;
|
||||
#define MYSERIAL1 usb_serial
|
||||
|
||||
#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() {}
|
||||
// ADC
|
||||
#define HAL_ADC_VREF 5.0
|
||||
#define HAL_ADC_RESOLUTION 10
|
||||
|
||||
// ------------------------
|
||||
// Class Utilities
|
||||
// ------------------------
|
||||
|
||||
// Utility functions
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
@@ -88,29 +96,70 @@ 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
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
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();
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// PWM
|
||||
inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) { analogWrite(pin, v); }
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Reset source
|
||||
inline void HAL_clear_reset_source(void) {}
|
||||
inline uint8_t HAL_get_reset_source(void) { return RST_POWER_ON; }
|
||||
// Watchdog
|
||||
static void watchdog_init() {}
|
||||
static void watchdog_refresh() {}
|
||||
|
||||
void HAL_reboot(); // Reset the application state and GPIO
|
||||
static void init() {} // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Reset the application state and GPIO
|
||||
|
||||
/* ---------------- Delay in cycles */
|
||||
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
|
||||
Clock::delayCycles(x);
|
||||
}
|
||||
// Interrupts
|
||||
static bool isr_state() { return true; }
|
||||
static void isr_on() {}
|
||||
static void isr_off() {}
|
||||
|
||||
static void delay_ms(const int ms) { _delay_ms(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask() {}
|
||||
|
||||
// Reset
|
||||
static constexpr uint8_t reset_reason = RST_POWER_ON;
|
||||
static uint8_t get_reset_source() { return reset_reason; }
|
||||
static void clear_reset_source() {}
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
static uint8_t active_ch;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const uint8_t) {}
|
||||
|
||||
// Begin ADC sampling on the given channel
|
||||
static void adc_start(const uint8_t ch) { active_ch = ch; }
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value();
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* No option to change the resolution or invert the duty cycle.
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
|
||||
analogWrite(pin, v);
|
||||
}
|
||||
|
||||
static void set_pwm_frequency(const pin_t, int) {}
|
||||
};
|
||||
|
@@ -31,9 +31,7 @@ void cli() { } // Disable
|
||||
void sei() { } // Enable
|
||||
|
||||
// Time functions
|
||||
void _delay_ms(const int delay_ms) {
|
||||
delay(delay_ms);
|
||||
}
|
||||
void _delay_ms(const int ms) { delay(ms); }
|
||||
|
||||
uint32_t millis() {
|
||||
return (uint32_t)Clock::millis();
|
||||
|
@@ -59,10 +59,9 @@ typedef uint8_t byte;
|
||||
#endif
|
||||
|
||||
#define sq(v) ((v) * (v))
|
||||
#define square(v) sq(v)
|
||||
#define constrain(value, arg_min, arg_max) ((value) < (arg_min) ? (arg_min) :((value) > (arg_max) ? (arg_max) : (value)))
|
||||
|
||||
//Interrupts
|
||||
// Interrupts
|
||||
void cli(); // Disable
|
||||
void sei(); // Enable
|
||||
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
|
||||
@@ -74,8 +73,8 @@ extern "C" {
|
||||
}
|
||||
|
||||
// Time functions
|
||||
extern "C" void delay(const int milis);
|
||||
void _delay_ms(const int delay);
|
||||
extern "C" void delay(const int ms);
|
||||
void _delay_ms(const int ms);
|
||||
void delayMicroseconds(unsigned long);
|
||||
uint32_t millis();
|
||||
|
||||
|
@@ -92,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(T)
|
||||
#define HAL_timer_isr_epilogue(T)
|
||||
#define HAL_timer_isr_prologue(T) NOOP
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
|
@@ -1,37 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef __PLAT_LINUX__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#include "watchdog.h"
|
||||
|
||||
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
|
||||
|
||||
void watchdog_init() {}
|
||||
void HAL_watchdog_refresh() {}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // __PLAT_LINUX__
|
@@ -25,13 +25,9 @@
|
||||
#include "../shared/Delay.h"
|
||||
#include "../../../gcode/parser.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
#include "watchdog.h"
|
||||
#endif
|
||||
|
||||
DefaultSerial1 USBSerial(false, UsbSerial);
|
||||
|
||||
uint32_t HAL_adc_reading = 0;
|
||||
uint32_t MarlinHAL::adc_result = 0;
|
||||
|
||||
// U8glib required functions
|
||||
extern "C" {
|
||||
@@ -41,8 +37,6 @@ extern "C" {
|
||||
void u8g_Delay(uint16_t val) { delay(val); }
|
||||
}
|
||||
|
||||
//************************//
|
||||
|
||||
// return free heap space
|
||||
int freeMemory() {
|
||||
char stack_end;
|
||||
@@ -54,7 +48,71 @@ int freeMemory() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// scan command line for code
|
||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
|
||||
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void MarlinHAL::clear_reset_source() { watchdog_clear_timeout_flag(); }
|
||||
|
||||
void flashFirmware(const int16_t) {
|
||||
delay(500); // Give OS time to disconnect
|
||||
USB_Connect(false); // USB clear connection
|
||||
delay(1000); // Give OS time to notice
|
||||
hal.reboot();
|
||||
}
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#include <lpc17xx_wdt.h>
|
||||
|
||||
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
|
||||
|
||||
void MarlinHAL::watchdog_init() {
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// We enable the watchdog timer, but only for the interrupt.
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
// Disable WDT interrupt (just in case, to avoid triggering it!)
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
|
||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
// Initialize WDT with the given parameters
|
||||
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_INT_ONLY);
|
||||
|
||||
// Configure and enable WDT interrupt.
|
||||
NVIC_ClearPendingIRQ(WDT_IRQn);
|
||||
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
#else
|
||||
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
|
||||
#endif
|
||||
WDT_Start(WDT_TIMEOUT_US);
|
||||
}
|
||||
|
||||
void MarlinHAL::watchdog_refresh() {
|
||||
WDT_Feed();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
#endif
|
||||
}
|
||||
|
||||
// Timeout state
|
||||
bool MarlinHAL::watchdog_timed_out() { return TEST(WDT_ReadTimeOutFlag(), 0); }
|
||||
void MarlinHAL::watchdog_clear_timeout_flag() { WDT_ClrTimeOutFlag(); }
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
// For M42/M43, scan command line for pin code
|
||||
// return index into pin map array if found and the pin is valid.
|
||||
// return dval if not found or not a valid pin.
|
||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
@@ -63,24 +121,4 @@ int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
return ind > -1 ? ind : dval;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
uint8_t HAL_get_reset_source(void) {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void HAL_reboot() { NVIC_SystemReset(); }
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
|
@@ -28,8 +28,6 @@
|
||||
|
||||
#define CPU_32_BIT
|
||||
|
||||
void HAL_init();
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <algorithm>
|
||||
@@ -40,19 +38,15 @@ extern "C" volatile uint32_t _millis;
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "watchdog.h"
|
||||
#include "MarlinSerial.h"
|
||||
|
||||
#include <adc.h>
|
||||
#include <pinmapping.h>
|
||||
#include <CDCSerial.h>
|
||||
|
||||
//
|
||||
// Default graphical display delays
|
||||
//
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
|
||||
extern DefaultSerial1 USBSerial;
|
||||
@@ -114,26 +108,12 @@ extern DefaultSerial1 USBSerial;
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
|
||||
#define ISRS_ENABLED() (!__get_PRIMASK())
|
||||
#define ENABLE_ISRS() __enable_irq()
|
||||
#define DISABLE_ISRS() __disable_irq()
|
||||
|
||||
#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (irqon) __enable_irq()
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
//
|
||||
// ADC API
|
||||
// ADC
|
||||
//
|
||||
|
||||
#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
|
||||
@@ -152,20 +132,9 @@ int freeMemory();
|
||||
#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t
|
||||
#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
|
||||
|
||||
using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
|
||||
extern uint32_t HAL_adc_reading;
|
||||
[[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_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_adc_start_conversion(pin)
|
||||
#define HAL_READ_ADC() HAL_adc_get_result()
|
||||
#define HAL_ADC_READY() (true)
|
||||
//
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
|
||||
// Test whether the pin is valid
|
||||
constexpr bool VALID_PIN(const pin_t pin) {
|
||||
@@ -192,32 +161,107 @@ 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_IDLETASK 1
|
||||
void HAL_idletask();
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
#define PLATFORM_M997_SUPPORT
|
||||
void flashFirmware(const int16_t);
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
|
||||
/**
|
||||
* set_pwm_frequency
|
||||
* Set the frequency of the timer corresponding to the provided pin
|
||||
* All Hardware PWM pins run at the same frequency and all
|
||||
* Software PWM pins run at the same frequency
|
||||
*/
|
||||
void set_pwm_frequency(const pin_t pin, int f_desired);
|
||||
// Default graphical display delays
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
/**
|
||||
* set_pwm_duty
|
||||
* Set the PWM duty cycle of the provided pin to the provided value
|
||||
* Optionally allows inverting the duty cycle [default = false]
|
||||
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
// Reset source
|
||||
void HAL_clear_reset_source(void);
|
||||
uint8_t HAL_get_reset_source(void);
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
void HAL_reboot();
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return !__get_PRIMASK(); }
|
||||
static void isr_on() { __enable_irq(); }
|
||||
static void isr_off() { __disable_irq(); }
|
||||
|
||||
static void delay_ms(const int ms) { _delay_ms(ms); }
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; });
|
||||
static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source();
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const pin_t pin) {
|
||||
FilteredADC::enable_channel(pin);
|
||||
}
|
||||
|
||||
// Begin ADC sampling on the given pin. Called from Temperature::isr!
|
||||
static uint32_t adc_result;
|
||||
static void adc_start(const pin_t pin) {
|
||||
adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
|
||||
}
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return uint16_t(adc_result); }
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* Optionally invert the duty cycle [default = false]
|
||||
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
/**
|
||||
* Set the frequency of the timer corresponding to the provided pin
|
||||
* All Hardware PWM pins will run at the same frequency and
|
||||
* All Software PWM pins will run at the same frequency
|
||||
*/
|
||||
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
|
||||
};
|
||||
|
@@ -26,7 +26,7 @@
|
||||
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
|
||||
#include "../shared/HAL_MinSerial.h"
|
||||
#include "../shared/MinSerial.h"
|
||||
#include <debug_frmwrk.h>
|
||||
|
||||
static void TX(char c) { _DBC(c); }
|
@@ -65,4 +65,5 @@ class libServo: public Servo {
|
||||
}
|
||||
};
|
||||
|
||||
#define HAL_SERVO_LIB libServo
|
||||
class libServo;
|
||||
typedef libServo hal_servo_t;
|
||||
|
@@ -34,7 +34,7 @@
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
#ifndef MARLIN_EEPROM_SIZE
|
||||
#define MARLIN_EEPROM_SIZE 0x8000 // 32KB
|
||||
#define MARLIN_EEPROM_SIZE 0x8000 // 32K
|
||||
#endif
|
||||
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
|
||||
|
||||
|
@@ -155,4 +155,37 @@ void setup_endstop_interrupts() {
|
||||
#endif
|
||||
_ATTACH(K_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(U_MAX_PIN)
|
||||
#error "U_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(U_MAX_PIN);
|
||||
#elif HAS_U_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(U_MIN_PIN)
|
||||
#error "U_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(U_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(V_MAX_PIN)
|
||||
#error "V_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(V_MAX_PIN);
|
||||
#elif HAS_V_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(V_MIN_PIN)
|
||||
#error "V_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(V_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(W_MAX_PIN)
|
||||
#error "W_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(W_MAX_PIN);
|
||||
#elif HAS_W_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(W_MIN_PIN)
|
||||
#error "W_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(W_MIN_PIN);
|
||||
#endif
|
||||
}
|
||||
|
@@ -21,21 +21,17 @@
|
||||
*/
|
||||
#ifdef TARGET_LPC1768
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include <pwm.h>
|
||||
|
||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
|
||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
|
||||
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
|
||||
}
|
||||
|
||||
#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
|
||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
|
||||
LPC176x::pwm_set_frequency(pin, f_desired);
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
|
@@ -113,7 +113,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
|
||||
#define _IS_RX1_1 IS_RX1
|
||||
#if IS_TX1(TMC_SW_SCK)
|
||||
#error "Serial port pins (1) conflict with other pins!"
|
||||
#elif HAS_WIRED_LCD
|
||||
#elif HAS_ROTARY_ENCODER
|
||||
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
|
||||
#error "Serial port pins (1) conflict with Encoder Buttons!"
|
||||
#elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \
|
||||
|
@@ -77,7 +77,7 @@ public:
|
||||
|
||||
//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
|
||||
|
@@ -29,7 +29,7 @@
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if MB(MKS_SBASE)
|
||||
#if ENABLED(DIGIPOT_MCP4451) && MB(MKS_SBASE)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@@ -37,35 +37,6 @@
|
||||
|
||||
#include "digipot_mcp4451_I2C_routines.h"
|
||||
|
||||
// These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to
|
||||
// to the lpc17xx_i2c.c routines so had to copy them into this file & rename them.
|
||||
|
||||
static uint32_t _I2C_Start(LPC_I2C_TypeDef *I2Cx) {
|
||||
// Reset STA, STO, SI
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
|
||||
|
||||
// Enter to Master Transmitter mode
|
||||
I2Cx->I2CONSET = I2C_I2CONSET_STA;
|
||||
|
||||
// Wait for complete
|
||||
while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
|
||||
return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
|
||||
}
|
||||
|
||||
static void _I2C_Stop(LPC_I2C_TypeDef *I2Cx) {
|
||||
// Make sure start bit is not active
|
||||
if (I2Cx->I2CONSET & I2C_I2CONSET_STA)
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
|
||||
|
||||
I2Cx->I2CONSET = I2C_I2CONSET_STO|I2C_I2CONSET_AA;
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
}
|
||||
|
||||
I2C_M_SETUP_Type transferMCfg;
|
||||
|
||||
#define I2C_status (LPC_I2C1->I2STAT & I2C_STAT_CODE_BITMASK)
|
||||
|
||||
uint8_t digipot_mcp4451_start(uint8_t sla) { // send slave address and write bit
|
||||
// Sometimes TX data ACK or NAK status is returned. That mean the start state didn't
|
||||
// happen which means only the value of the slave address was send. Keep looping until
|
||||
@@ -102,5 +73,5 @@ uint8_t digipot_mcp4451_send_byte(uint8_t data) {
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // MB(MKS_SBASE)
|
||||
#endif // DIGIPOT_MCP4451 && MKS_SBASE
|
||||
#endif // TARGET_LPC1768
|
||||
|
@@ -63,6 +63,32 @@ void configure_i2c(const uint8_t clock_option) {
|
||||
I2C_Cmd(I2CDEV_M, I2C_MASTER_MODE, ENABLE);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to
|
||||
// to the lpc17xx_i2c.c routines so had to copy them into this file & rename them.
|
||||
|
||||
uint32_t _I2C_Start(LPC_I2C_TypeDef *I2Cx) {
|
||||
// Reset STA, STO, SI
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
|
||||
|
||||
// Enter to Master Transmitter mode
|
||||
I2Cx->I2CONSET = I2C_I2CONSET_STA;
|
||||
|
||||
// Wait for complete
|
||||
while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
|
||||
return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
|
||||
}
|
||||
|
||||
void _I2C_Stop(LPC_I2C_TypeDef *I2Cx) {
|
||||
/* Make sure start bit is not active */
|
||||
if (I2Cx->I2CONSET & I2C_I2CONSET_STA)
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
|
||||
|
||||
I2Cx->I2CONSET = I2C_I2CONSET_STO|I2C_I2CONSET_AA;
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -51,6 +51,11 @@
|
||||
|
||||
void configure_i2c(const uint8_t clock_option);
|
||||
|
||||
uint32_t _I2C_Start(LPC_I2C_TypeDef *I2Cx);
|
||||
void _I2C_Stop(LPC_I2C_TypeDef *I2Cx);
|
||||
|
||||
#define I2C_status (LPC_I2C1->I2STAT & I2C_STAT_CODE_BITMASK)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -48,7 +48,7 @@ void SysTick_Callback() { disk_timerproc(); }
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
|
||||
|
||||
void HAL_init() {
|
||||
void MarlinHAL::init() {
|
||||
|
||||
// Init LEDs
|
||||
#if PIN_EXISTS(LED)
|
||||
@@ -130,7 +130,7 @@ void HAL_init() {
|
||||
const millis_t usb_timeout = millis() + 2000;
|
||||
while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
|
||||
delay(50);
|
||||
HAL_idletask();
|
||||
idletask();
|
||||
#if PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // Flash quickly during USB initialization
|
||||
#endif
|
||||
@@ -142,7 +142,7 @@ void HAL_init() {
|
||||
}
|
||||
|
||||
// HAL idle task
|
||||
void HAL_idletask() {
|
||||
void MarlinHAL::idletask() {
|
||||
#if HAS_SHARED_MEDIA
|
||||
// If Marlin is using the SD card we need to lock it to prevent access from
|
||||
// a PC via USB.
|
||||
|
@@ -65,8 +65,8 @@ private:
|
||||
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
|
||||
|
@@ -170,4 +170,4 @@ FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
|
||||
}
|
||||
}
|
||||
|
||||
#define HAL_timer_isr_epilogue(T)
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
|
@@ -36,40 +36,7 @@ extern int millis();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to
|
||||
// to the lpc17xx_i2c.c routines so had to copy them into this file & rename them.
|
||||
|
||||
static uint32_t _I2C_Start(LPC_I2C_TypeDef *I2Cx) {
|
||||
// Reset STA, STO, SI
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_SIC|I2C_I2CONCLR_STOC|I2C_I2CONCLR_STAC;
|
||||
|
||||
// Enter to Master Transmitter mode
|
||||
I2Cx->I2CONSET = I2C_I2CONSET_STA;
|
||||
|
||||
// Wait for complete
|
||||
while (!(I2Cx->I2CONSET & I2C_I2CONSET_SI));
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
|
||||
return (I2Cx->I2STAT & I2C_STAT_CODE_BITMASK);
|
||||
}
|
||||
|
||||
static void _I2C_Stop (LPC_I2C_TypeDef *I2Cx) {
|
||||
/* Make sure start bit is not active */
|
||||
if (I2Cx->I2CONSET & I2C_I2CONSET_STA)
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_STAC;
|
||||
|
||||
I2Cx->I2CONSET = I2C_I2CONSET_STO|I2C_I2CONSET_AA;
|
||||
I2Cx->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define I2CDEV_S_ADDR 0x78 // from SSD1306 //actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write
|
||||
|
||||
#define BUFFER_SIZE 0x1 // only do single byte transfers with LCDs
|
||||
|
||||
I2C_M_SETUP_Type transferMCfg;
|
||||
|
||||
#define I2C_status (LPC_I2C1->I2STAT & I2C_STAT_CODE_BITMASK)
|
||||
#define I2CDEV_S_ADDR 0x78 // From SSD1306 (actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write)
|
||||
|
||||
// Send slave address and write bit
|
||||
uint8_t u8g_i2c_start(const uint8_t sla) {
|
||||
@@ -115,7 +82,6 @@ uint8_t u8g_i2c_send_byte(uint8_t data) {
|
||||
void u8g_i2c_stop() {
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -1,72 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC1768
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#include <lpc17xx_wdt.h>
|
||||
#include "watchdog.h"
|
||||
|
||||
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
|
||||
|
||||
void watchdog_init() {
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// We enable the watchdog timer, but only for the interrupt.
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
// Disable WDT interrupt (just in case, to avoid triggering it!)
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
|
||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
// Initialize WDT with the given parameters
|
||||
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_INT_ONLY);
|
||||
|
||||
// Configure and enable WDT interrupt.
|
||||
NVIC_ClearPendingIRQ(WDT_IRQn);
|
||||
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
#else
|
||||
WDT_Init(WDT_CLKSRC_IRC, WDT_MODE_RESET);
|
||||
#endif
|
||||
WDT_Start(WDT_TIMEOUT_US);
|
||||
}
|
||||
|
||||
void HAL_watchdog_refresh() {
|
||||
WDT_Feed();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
#endif
|
||||
}
|
||||
|
||||
// Timeout state
|
||||
bool watchdog_timed_out() { return TEST(WDT_ReadTimeOutFlag(), 0); }
|
||||
void watchdog_clear_timeout_flag() { WDT_ClrTimeOutFlag(); }
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
#endif // TARGET_LPC1768
|
@@ -1,28 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
void watchdog_init();
|
||||
void HAL_watchdog_refresh();
|
||||
|
||||
bool watchdog_timed_out();
|
||||
void watchdog_clear_timeout_flag();
|
@@ -21,18 +21,10 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define CPU_32_BIT
|
||||
#define HAL_IDLETASK
|
||||
void HAL_idletask();
|
||||
|
||||
#define F_CPU 100000000
|
||||
#define SystemCoreClock F_CPU
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#undef min
|
||||
#undef max
|
||||
|
||||
#include <algorithm>
|
||||
#include "pinmapping.h"
|
||||
|
||||
@@ -40,8 +32,6 @@ 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
|
||||
@@ -55,10 +45,25 @@ uint8_t _getc();
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "watchdog.h"
|
||||
#include "serial.h"
|
||||
|
||||
#define SHARED_SERVOS HAS_SERVOS
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
#define CPU_32_BIT
|
||||
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
|
||||
|
||||
#define F_CPU 100000000
|
||||
#define SystemCoreClock F_CPU
|
||||
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
extern MSerialT serial_stream_0;
|
||||
extern MSerialT serial_stream_1;
|
||||
@@ -98,49 +103,19 @@ extern MSerialT serial_stream_3;
|
||||
#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 */
|
||||
|
||||
@@ -159,29 +134,22 @@ 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;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (lhs == nullptr || rhs == nullptr)
|
||||
return rhs != nullptr ? -1 : 1;
|
||||
}
|
||||
|
||||
for (std::size_t i = 0; i < count; ++i) {
|
||||
if (lhs[i] != rhs[i]) {
|
||||
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') {
|
||||
else if (lhs[i] == '\0')
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -193,14 +161,11 @@ constexpr inline const char* strstr_constexpr(const char* str, const char* targe
|
||||
do {
|
||||
char sc = {};
|
||||
do {
|
||||
if ((sc = *str++) == '\0') {
|
||||
return nullptr;
|
||||
}
|
||||
if ((sc = *str++) == '\0') return nullptr;
|
||||
} while (sc != c);
|
||||
} while (strncmp_constexpr(str, target, len) != 0);
|
||||
--str;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@@ -211,12 +176,91 @@ constexpr inline char* strstr_constexpr(char* str, const char* target) {
|
||||
do {
|
||||
char sc = {};
|
||||
do {
|
||||
if ((sc = *str++) == '\0') {
|
||||
return nullptr;
|
||||
}
|
||||
if ((sc = *str++) == '\0') return nullptr;
|
||||
} while (sc != c);
|
||||
} while (strncmp_constexpr(str, target, len) != 0);
|
||||
--str;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
static void init() {} // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return true; }
|
||||
static void isr_on() {}
|
||||
static void isr_off() {}
|
||||
|
||||
static void delay_ms(const int ms) { _delay_ms(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static constexpr uint8_t reset_reason = RST_POWER_ON;
|
||||
static uint8_t get_reset_source() { return reset_reason; }
|
||||
static void clear_reset_source() {}
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
static uint8_t active_ch;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init();
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const uint8_t ch);
|
||||
|
||||
// Begin ADC sampling on the given channel. Called from Temperature::isr!
|
||||
static void adc_start(const uint8_t ch);
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready();
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value();
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* No option to invert the duty cycle [default = false]
|
||||
* No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
|
||||
analogWrite(pin, v);
|
||||
}
|
||||
|
||||
};
|
||||
|
@@ -62,8 +62,8 @@ private:
|
||||
static uint16_t getRawData(const XPTCoordinate coordinate);
|
||||
static bool isTouched();
|
||||
|
||||
static inline void DataTransferBegin();
|
||||
static inline void DataTransferEnd();
|
||||
static void DataTransferBegin();
|
||||
static void DataTransferEnd();
|
||||
#if ENABLED(TOUCH_BUTTONS_HW_SPI)
|
||||
static uint16_t HardwareIO(uint16_t data);
|
||||
#endif
|
||||
|
@@ -87,5 +87,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(T)
|
||||
#define HAL_timer_isr_epilogue(T)
|
||||
#define HAL_timer_isr_prologue(T) NOOP
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
|
@@ -38,13 +38,13 @@
|
||||
#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?
|
||||
}
|
||||
|
||||
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
|
||||
|
@@ -42,10 +42,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// ------------------------
|
||||
// Local defines
|
||||
// ------------------------
|
||||
|
||||
#define GET_TEMP_0_ADC() TERN(HAS_TEMP_ADC_0, PIN_TO_ADC(TEMP_0_PIN), -1)
|
||||
#define GET_TEMP_1_ADC() TERN(HAS_TEMP_ADC_1, PIN_TO_ADC(TEMP_1_PIN), -1)
|
||||
#define GET_TEMP_2_ADC() TERN(HAS_TEMP_ADC_2, PIN_TO_ADC(TEMP_2_PIN), -1)
|
||||
@@ -54,22 +50,28 @@
|
||||
#define GET_TEMP_5_ADC() TERN(HAS_TEMP_ADC_5, PIN_TO_ADC(TEMP_5_PIN), -1)
|
||||
#define GET_TEMP_6_ADC() TERN(HAS_TEMP_ADC_6, PIN_TO_ADC(TEMP_6_PIN), -1)
|
||||
#define GET_TEMP_7_ADC() TERN(HAS_TEMP_ADC_7, PIN_TO_ADC(TEMP_7_PIN), -1)
|
||||
#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_PROBE_ADC() TERN(HAS_TEMP_ADC_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1)
|
||||
#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1)
|
||||
#define GET_BOARD_ADC() TERN(HAS_TEMP_ADC_BOARD, PIN_TO_ADC(TEMP_BOARD_PIN), -1)
|
||||
#define GET_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)
|
||||
#define GET_JOY_ADC_X() TERN(HAS_JOY_ADC_X, PIN_TO_ADC(JOY_X_PIN), -1)
|
||||
#define GET_JOY_ADC_Y() TERN(HAS_JOY_ADC_Y, PIN_TO_ADC(JOY_Y_PIN), -1)
|
||||
#define GET_JOY_ADC_Z() TERN(HAS_JOY_ADC_Z, PIN_TO_ADC(JOY_Z_PIN), -1)
|
||||
|
||||
#define IS_ADC_REQUIRED(n) ( \
|
||||
GET_TEMP_0_ADC() == n || GET_TEMP_1_ADC() == n || GET_TEMP_2_ADC() == n || GET_TEMP_3_ADC() == n \
|
||||
|| GET_TEMP_4_ADC() == n || GET_TEMP_5_ADC() == n || GET_TEMP_6_ADC() == n || GET_TEMP_7_ADC() == n \
|
||||
|| GET_PROBE_ADC() == n \
|
||||
|| GET_BED_ADC() == n \
|
||||
|| GET_CHAMBER_ADC() == n \
|
||||
|| GET_COOLER_ADC() == n \
|
||||
|| GET_BED_ADC() == n \
|
||||
|| GET_CHAMBER_ADC() == n \
|
||||
|| GET_PROBE_ADC() == n \
|
||||
|| GET_COOLER_ADC() == n \
|
||||
|| GET_BOARD_ADC() == n \
|
||||
|| GET_FILAMENT_WIDTH_ADC() == n \
|
||||
|| GET_BUTTONS_ADC() == n \
|
||||
|| GET_BUTTONS_ADC() == n \
|
||||
|| GET_JOY_ADC_X() == n || GET_JOY_ADC_Y() == n || GET_JOY_ADC_Z() == n \
|
||||
)
|
||||
|
||||
#if IS_ADC_REQUIRED(0)
|
||||
@@ -89,6 +91,152 @@
|
||||
#define DMA_IS_REQUIRED 1
|
||||
#endif
|
||||
|
||||
enum ADCIndex {
|
||||
#if GET_TEMP_0_ADC() == 0
|
||||
TEMP_0,
|
||||
#endif
|
||||
#if GET_TEMP_1_ADC() == 0
|
||||
TEMP_1,
|
||||
#endif
|
||||
#if GET_TEMP_2_ADC() == 0
|
||||
TEMP_2,
|
||||
#endif
|
||||
#if GET_TEMP_3_ADC() == 0
|
||||
TEMP_3,
|
||||
#endif
|
||||
#if GET_TEMP_4_ADC() == 0
|
||||
TEMP_4,
|
||||
#endif
|
||||
#if GET_TEMP_5_ADC() == 0
|
||||
TEMP_5,
|
||||
#endif
|
||||
#if GET_TEMP_6_ADC() == 0
|
||||
TEMP_6,
|
||||
#endif
|
||||
#if GET_TEMP_7_ADC() == 0
|
||||
TEMP_7,
|
||||
#endif
|
||||
#if GET_BED_ADC() == 0
|
||||
TEMP_BED,
|
||||
#endif
|
||||
#if GET_CHAMBER_ADC() == 0
|
||||
TEMP_CHAMBER,
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 0
|
||||
TEMP_PROBE,
|
||||
#endif
|
||||
#if GET_COOLER_ADC() == 0
|
||||
TEMP_COOLER,
|
||||
#endif
|
||||
#if GET_BOARD_ADC() == 0
|
||||
TEMP_BOARD,
|
||||
#endif
|
||||
#if GET_FILAMENT_WIDTH_ADC() == 0
|
||||
FILWIDTH,
|
||||
#endif
|
||||
#if GET_BUTTONS_ADC() == 0
|
||||
ADC_KEY,
|
||||
#endif
|
||||
#if GET_JOY_ADC_X() == 0
|
||||
JOY_X,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Y() == 0
|
||||
JOY_Y,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Z() == 0
|
||||
JOY_Z,
|
||||
#endif
|
||||
#if GET_TEMP_0_ADC() == 1
|
||||
TEMP_0,
|
||||
#endif
|
||||
#if GET_TEMP_1_ADC() == 1
|
||||
TEMP_1,
|
||||
#endif
|
||||
#if GET_TEMP_2_ADC() == 1
|
||||
TEMP_2,
|
||||
#endif
|
||||
#if GET_TEMP_3_ADC() == 1
|
||||
TEMP_3,
|
||||
#endif
|
||||
#if GET_TEMP_4_ADC() == 1
|
||||
TEMP_4,
|
||||
#endif
|
||||
#if GET_TEMP_5_ADC() == 1
|
||||
TEMP_5,
|
||||
#endif
|
||||
#if GET_TEMP_6_ADC() == 1
|
||||
TEMP_6,
|
||||
#endif
|
||||
#if GET_TEMP_7_ADC() == 1
|
||||
TEMP_7,
|
||||
#endif
|
||||
#if GET_BED_ADC() == 1
|
||||
TEMP_BED,
|
||||
#endif
|
||||
#if GET_CHAMBER_ADC() == 1
|
||||
TEMP_CHAMBER,
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 1
|
||||
TEMP_PROBE,
|
||||
#endif
|
||||
#if GET_COOLER_ADC() == 1
|
||||
TEMP_COOLER,
|
||||
#endif
|
||||
#if GET_BOARD_ADC() == 1
|
||||
TEMP_BOARD,
|
||||
#endif
|
||||
#if GET_FILAMENT_WIDTH_ADC() == 1
|
||||
FILWIDTH,
|
||||
#endif
|
||||
#if GET_BUTTONS_ADC() == 1
|
||||
ADC_KEY,
|
||||
#endif
|
||||
#if GET_JOY_ADC_X() == 1
|
||||
JOY_X,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Y() == 1
|
||||
JOY_Y,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Z() == 1
|
||||
JOY_Z,
|
||||
#endif
|
||||
ADC_COUNT
|
||||
};
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#define WDT_TIMEOUT_REG TERN(WATCHDOG_DURATION_8S, WDT_CONFIG_PER_CYC8192, WDT_CONFIG_PER_CYC4096) // 4 or 8 second timeout
|
||||
|
||||
void MarlinHAL::watchdog_init() {
|
||||
// The low-power oscillator used by the WDT runs at 32,768 Hz with
|
||||
// a 1:32 prescale, thus 1024 Hz, though probably not super precise.
|
||||
|
||||
// Setup WDT clocks
|
||||
MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
|
||||
MCLK->APBAMASK.bit.WDT_ = true;
|
||||
OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
|
||||
|
||||
WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
|
||||
SYNC(WDT->SYNCBUSY.bit.ENABLE);
|
||||
|
||||
WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
|
||||
WDT->CONFIG.reg = WDT_TIMEOUT_REG; // Set a 4s or 8s period for chip reset
|
||||
|
||||
hal.watchdog_refresh();
|
||||
|
||||
WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
|
||||
SYNC(WDT->SYNCBUSY.bit.ENABLE);
|
||||
}
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or SAMD will go into emergency procedures.
|
||||
void MarlinHAL::watchdog_refresh() {
|
||||
SYNC(WDT->SYNCBUSY.bit.CLEAR); // Test first if previous is 'ongoing' to save time waiting for command execution
|
||||
WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// ------------------------
|
||||
// Types
|
||||
// ------------------------
|
||||
@@ -106,12 +254,10 @@
|
||||
// Private Variables
|
||||
// ------------------------
|
||||
|
||||
uint16_t HAL_adc_result;
|
||||
|
||||
#if ADC_IS_REQUIRED
|
||||
|
||||
// Pins used by ADC inputs. Order must be ADC0 inputs first then ADC1
|
||||
const uint8_t adc_pins[] = {
|
||||
static constexpr uint8_t adc_pins[ADC_COUNT] = {
|
||||
// ADC0 pins
|
||||
#if GET_TEMP_0_ADC() == 0
|
||||
TEMP_0_PIN,
|
||||
@@ -137,24 +283,36 @@ uint16_t HAL_adc_result;
|
||||
#if GET_TEMP_7_ADC() == 0
|
||||
TEMP_7_PIN,
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 0
|
||||
TEMP_PROBE_PIN,
|
||||
#endif
|
||||
#if GET_BED_ADC() == 0
|
||||
TEMP_BED_PIN,
|
||||
#endif
|
||||
#if GET_CHAMBER_ADC() == 0
|
||||
TEMP_CHAMBER_PIN,
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 0
|
||||
TEMP_PROBE_PIN,
|
||||
#endif
|
||||
#if GET_COOLER_ADC() == 0
|
||||
TEMP_COOLER_PIN,
|
||||
#endif
|
||||
#if GET_BOARD_ADC() == 0
|
||||
TEMP_BOARD_PIN,
|
||||
#endif
|
||||
#if GET_FILAMENT_WIDTH_ADC() == 0
|
||||
FILWIDTH_PIN,
|
||||
#endif
|
||||
#if GET_BUTTONS_ADC() == 0
|
||||
ADC_KEYPAD_PIN,
|
||||
#endif
|
||||
#if GET_JOY_ADC_X() == 0
|
||||
JOY_X_PIN,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Y() == 0
|
||||
JOY_Y_PIN,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Z() == 0
|
||||
JOY_Z_PIN,
|
||||
#endif
|
||||
// ADC1 pins
|
||||
#if GET_TEMP_0_ADC() == 1
|
||||
TEMP_0_PIN,
|
||||
@@ -180,33 +338,44 @@ uint16_t HAL_adc_result;
|
||||
#if GET_TEMP_7_ADC() == 1
|
||||
TEMP_7_PIN,
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 1
|
||||
TEMP_PROBE_PIN,
|
||||
#endif
|
||||
#if GET_BED_ADC() == 1
|
||||
TEMP_BED_PIN,
|
||||
#endif
|
||||
#if GET_CHAMBER_ADC() == 1
|
||||
TEMP_CHAMBER_PIN,
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 1
|
||||
TEMP_PROBE_PIN,
|
||||
#endif
|
||||
#if GET_COOLER_ADC() == 1
|
||||
TEMP_COOLER_PIN,
|
||||
#endif
|
||||
#if GET_BOARD_ADC() == 1
|
||||
TEMP_BOARD_PIN,
|
||||
#endif
|
||||
#if GET_FILAMENT_WIDTH_ADC() == 1
|
||||
FILWIDTH_PIN,
|
||||
#endif
|
||||
#if GET_BUTTONS_ADC() == 1
|
||||
ADC_KEYPAD_PIN,
|
||||
#endif
|
||||
#if GET_JOY_ADC_X() == 1
|
||||
JOY_X_PIN,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Y() == 1
|
||||
JOY_Y_PIN,
|
||||
#endif
|
||||
#if GET_JOY_ADC_Z() == 1
|
||||
JOY_Z_PIN,
|
||||
#endif
|
||||
};
|
||||
|
||||
uint16_t HAL_adc_results[COUNT(adc_pins)];
|
||||
static uint16_t adc_results[ADC_COUNT];
|
||||
|
||||
#if ADC0_IS_REQUIRED
|
||||
Adafruit_ZeroDMA adc0DMAProgram,
|
||||
adc0DMARead;
|
||||
Adafruit_ZeroDMA adc0DMAProgram, adc0DMARead;
|
||||
|
||||
const HAL_DMA_DAC_Registers adc0_dma_regs_list[] = {
|
||||
static constexpr HAL_DMA_DAC_Registers adc0_dma_regs_list[ADC_COUNT] = {
|
||||
#if GET_TEMP_0_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_0_PIN) },
|
||||
#endif
|
||||
@@ -231,34 +400,45 @@ uint16_t HAL_adc_result;
|
||||
#if GET_TEMP_7_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_7_PIN) },
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
|
||||
#endif
|
||||
#if GET_BED_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
|
||||
#endif
|
||||
#if GET_CHAMBER_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
|
||||
#endif
|
||||
#if GET_COOLER_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
|
||||
#endif
|
||||
#if GET_BOARD_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(TEMP_BOARD_PIN) },
|
||||
#endif
|
||||
#if GET_FILAMENT_WIDTH_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
|
||||
#endif
|
||||
#if GET_BUTTONS_ADC() == 0
|
||||
{ PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
|
||||
#endif
|
||||
#if GET_JOY_ADC_X() == 0
|
||||
{ PIN_TO_INPUTCTRL(JOY_X_PIN) },
|
||||
#endif
|
||||
#if GET_JOY_ADC_Y() == 0
|
||||
{ PIN_TO_INPUTCTRL(JOY_Y_PIN) },
|
||||
#endif
|
||||
#if GET_JOY_ADC_Z() == 0
|
||||
{ PIN_TO_INPUTCTRL(JOY_Z_PIN) },
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ADC0_AINCOUNT COUNT(adc0_dma_regs_list)
|
||||
#endif // ADC0_IS_REQUIRED
|
||||
|
||||
#if ADC1_IS_REQUIRED
|
||||
Adafruit_ZeroDMA adc1DMAProgram,
|
||||
adc1DMARead;
|
||||
Adafruit_ZeroDMA adc1DMAProgram, adc1DMARead;
|
||||
|
||||
const HAL_DMA_DAC_Registers adc1_dma_regs_list[] = {
|
||||
static constexpr HAL_DMA_DAC_Registers adc1_dma_regs_list[ADC_COUNT] = {
|
||||
#if GET_TEMP_0_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_0_PIN) },
|
||||
#endif
|
||||
@@ -283,24 +463,36 @@ uint16_t HAL_adc_result;
|
||||
#if GET_TEMP_7_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_7_PIN) },
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
|
||||
#endif
|
||||
#if GET_BED_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_BED_PIN) },
|
||||
#endif
|
||||
#if GET_CHAMBER_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
|
||||
#endif
|
||||
#if GET_PROBE_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_PROBE_PIN) },
|
||||
#endif
|
||||
#if GET_COOLER_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
|
||||
#endif
|
||||
#if GET_BOARD_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(TEMP_BOARD_PIN) },
|
||||
#endif
|
||||
#if GET_FILAMENT_WIDTH_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
|
||||
#endif
|
||||
#if GET_BUTTONS_ADC() == 1
|
||||
{ PIN_TO_INPUTCTRL(ADC_KEYPAD_PIN) },
|
||||
#endif
|
||||
#if GET_JOY_ADC_X() == 1
|
||||
{ PIN_TO_INPUTCTRL(JOY_X_PIN) },
|
||||
#endif
|
||||
#if GET_JOY_ADC_Y() == 1
|
||||
{ PIN_TO_INPUTCTRL(JOY_Y_PIN) },
|
||||
#endif
|
||||
#if GET_JOY_ADC_Z() == 1
|
||||
{ PIN_TO_INPUTCTRL(JOY_Z_PIN) },
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ADC1_AINCOUNT COUNT(adc1_dma_regs_list)
|
||||
@@ -312,9 +504,10 @@ uint16_t HAL_adc_result;
|
||||
// Private functions
|
||||
// ------------------------
|
||||
|
||||
#if DMA_IS_REQUIRED
|
||||
void MarlinHAL::dma_init() {
|
||||
|
||||
#if DMA_IS_REQUIRED
|
||||
|
||||
void dma_init() {
|
||||
DmacDescriptor *descriptor;
|
||||
|
||||
#if ADC0_IS_REQUIRED
|
||||
@@ -343,7 +536,7 @@ uint16_t HAL_adc_result;
|
||||
if (adc0DMARead.allocate() == DMA_STATUS_OK) {
|
||||
adc0DMARead.addDescriptor(
|
||||
(void *)&ADC0->RESULT.reg, // SRC
|
||||
&HAL_adc_results, // DEST
|
||||
&adc_results, // DEST
|
||||
ADC0_AINCOUNT, // CNT
|
||||
DMA_BEAT_SIZE_HWORD,
|
||||
false, // SRCINC
|
||||
@@ -380,7 +573,7 @@ uint16_t HAL_adc_result;
|
||||
if (adc1DMARead.allocate() == DMA_STATUS_OK) {
|
||||
adc1DMARead.addDescriptor(
|
||||
(void *)&ADC1->RESULT.reg, // SRC
|
||||
&HAL_adc_results[ADC0_AINCOUNT], // DEST
|
||||
&adc_results[ADC0_AINCOUNT], // DEST
|
||||
ADC1_AINCOUNT, // CNT
|
||||
DMA_BEAT_SIZE_HWORD,
|
||||
false, // SRCINC
|
||||
@@ -393,16 +586,16 @@ uint16_t HAL_adc_result;
|
||||
#endif
|
||||
|
||||
DMAC->PRICTRL0.bit.RRLVLEN0 = true; // Activate round robin for DMA channels required by ADCs
|
||||
}
|
||||
|
||||
#endif // DMA_IS_REQUIRED
|
||||
#endif // DMA_IS_REQUIRED
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
|
||||
// HAL initialization task
|
||||
void HAL_init() {
|
||||
void MarlinHAL::init() {
|
||||
TERN_(DMA_IS_REQUIRED, dma_init());
|
||||
#if ENABLED(SDSUPPORT)
|
||||
#if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT)
|
||||
@@ -412,17 +605,9 @@ void HAL_init() {
|
||||
#endif
|
||||
}
|
||||
|
||||
// HAL idle task
|
||||
/*
|
||||
void HAL_idletask() {
|
||||
}
|
||||
*/
|
||||
|
||||
void HAL_clear_reset_source() { }
|
||||
|
||||
#pragma push_macro("WDT")
|
||||
#undef WDT // Required to be able to use '.bit.WDT'. Compiler wrongly replace struct field with WDT define
|
||||
uint8_t HAL_get_reset_source() {
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
RSTC_RCAUSE_Type resetCause;
|
||||
|
||||
resetCause.reg = REG_RSTC_RCAUSE;
|
||||
@@ -436,7 +621,7 @@ uint8_t HAL_get_reset_source() {
|
||||
}
|
||||
#pragma pop_macro("WDT")
|
||||
|
||||
void HAL_reboot() { NVIC_SystemReset(); }
|
||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
|
||||
|
||||
extern "C" {
|
||||
void * _sbrk(int incr);
|
||||
@@ -454,9 +639,11 @@ int freeMemory() {
|
||||
// ADC
|
||||
// ------------------------
|
||||
|
||||
void HAL_adc_init() {
|
||||
uint16_t MarlinHAL::adc_result;
|
||||
|
||||
void MarlinHAL::adc_init() {
|
||||
#if ADC_IS_REQUIRED
|
||||
memset(HAL_adc_results, 0xFF, sizeof(HAL_adc_results)); // Fill result with invalid values
|
||||
memset(adc_results, 0xFF, sizeof(adc_results)); // Fill result with invalid values
|
||||
|
||||
LOOP_L_N(pi, COUNT(adc_pins))
|
||||
pinPeripheral(adc_pins[pi], PIO_ANALOG);
|
||||
@@ -491,17 +678,13 @@ void HAL_adc_init() {
|
||||
#endif // ADC_IS_REQUIRED
|
||||
}
|
||||
|
||||
void HAL_adc_start_conversion(const uint8_t adc_pin) {
|
||||
void MarlinHAL::adc_start(const pin_t pin) {
|
||||
#if ADC_IS_REQUIRED
|
||||
LOOP_L_N(pi, COUNT(adc_pins)) {
|
||||
if (adc_pin == adc_pins[pi]) {
|
||||
HAL_adc_result = HAL_adc_results[pi];
|
||||
return;
|
||||
}
|
||||
}
|
||||
LOOP_L_N(pi, COUNT(adc_pins))
|
||||
if (pin == adc_pins[pi]) { adc_result = adc_results[pi]; return; }
|
||||
#endif
|
||||
|
||||
HAL_adc_result = 0xFFFF;
|
||||
adc_result = 0xFFFF;
|
||||
}
|
||||
|
||||
#endif // __SAMD51__
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "watchdog.h"
|
||||
|
||||
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
|
||||
#include "MarlinSerial_AGCM4.h"
|
||||
@@ -89,51 +88,30 @@
|
||||
|
||||
typedef int8_t pin_t;
|
||||
|
||||
#define SHARED_SERVOS HAS_SERVOS
|
||||
#define HAL_SERVO_LIB Servo
|
||||
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
|
||||
|
||||
class Servo;
|
||||
typedef Servo hal_servo_t;
|
||||
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
|
||||
#define ISRS_ENABLED() (!__get_PRIMASK())
|
||||
#define ENABLE_ISRS() __enable_irq()
|
||||
#define DISABLE_ISRS() __disable_irq()
|
||||
#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (irqon) __enable_irq()
|
||||
|
||||
#define cli() __disable_irq() // Disable interrupts
|
||||
#define sei() __enable_irq() // Enable interrupts
|
||||
|
||||
void HAL_clear_reset_source(); // clear reset reason
|
||||
uint8_t HAL_get_reset_source(); // get reset reason
|
||||
|
||||
void HAL_reboot();
|
||||
#define cli() __disable_irq() // Disable interrupts
|
||||
#define sei() __enable_irq() // Enable interrupts
|
||||
|
||||
//
|
||||
// ADC
|
||||
//
|
||||
extern uint16_t HAL_adc_result; // Most recent ADC conversion
|
||||
|
||||
#define HAL_ANALOG_SELECT(pin)
|
||||
|
||||
void HAL_adc_init();
|
||||
|
||||
//#define HAL_ADC_FILTERED // Disable Marlin's oversampling. The HAL filters ADC values.
|
||||
#define HAL_ADC_VREF 3.3
|
||||
#define HAL_ADC_RESOLUTION 10 // ... 12
|
||||
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
|
||||
#define HAL_READ_ADC() HAL_adc_result
|
||||
#define HAL_ADC_READY() true
|
||||
|
||||
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
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
@@ -142,35 +120,97 @@ inline void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255,
|
||||
//
|
||||
// Tone
|
||||
//
|
||||
void toneInit();
|
||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
|
||||
void noTone(const pin_t _pin);
|
||||
|
||||
// Enable hooks into idle and setup for HAL
|
||||
void HAL_init();
|
||||
/*
|
||||
#define HAL_IDLETASK 1
|
||||
void HAL_idletask();
|
||||
*/
|
||||
|
||||
//
|
||||
// Utility functions
|
||||
//
|
||||
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
|
||||
// ------------------------
|
||||
// Class Utilities
|
||||
// ------------------------
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s);
|
||||
|
||||
extern "C" int freeMemory();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return !__get_PRIMASK(); }
|
||||
static void isr_on() { sei(); }
|
||||
static void isr_off() { cli(); }
|
||||
|
||||
static void delay_ms(const int ms) { delay(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask() {}
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source() {}
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
static uint16_t adc_result;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init();
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const uint8_t ch) {}
|
||||
|
||||
// Begin ADC sampling on the given pin. Called from Temperature::isr!
|
||||
static void adc_start(const pin_t pin);
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return adc_result; }
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* No option to invert the duty cycle [default = false]
|
||||
* No option to change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
|
||||
analogWrite(pin, v);
|
||||
}
|
||||
|
||||
private:
|
||||
static void dma_init();
|
||||
};
|
||||
|
@@ -60,6 +60,12 @@
|
||||
#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_U_MAX_EILINE(P) TERN0(HAS_U_MAX, DEFER4(MATCH_EILINE)(P, U_MAX_PIN))
|
||||
#define MATCH_U_MIN_EILINE(P) TERN0(HAS_U_MIN, DEFER4(MATCH_EILINE)(P, U_MIN_PIN))
|
||||
#define MATCH_V_MAX_EILINE(P) TERN0(HAS_V_MAX, DEFER4(MATCH_EILINE)(P, V_MAX_PIN))
|
||||
#define MATCH_V_MIN_EILINE(P) TERN0(HAS_V_MIN, DEFER4(MATCH_EILINE)(P, V_MIN_PIN))
|
||||
#define MATCH_W_MAX_EILINE(P) TERN0(HAS_W_MAX, DEFER4(MATCH_EILINE)(P, W_MAX_PIN))
|
||||
#define MATCH_W_MIN_EILINE(P) TERN0(HAS_W_MIN, DEFER4(MATCH_EILINE)(P, W_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))
|
||||
@@ -75,6 +81,9 @@
|
||||
&& !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_U_MAX_EILINE(P) && !MATCH_U_MIN_EILINE(P) \
|
||||
&& !MATCH_V_MAX_EILINE(P) && !MATCH_V_MIN_EILINE(P) \
|
||||
&& !MATCH_W_MAX_EILINE(P) && !MATCH_W_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) \
|
||||
@@ -199,4 +208,40 @@ void setup_endstop_interrupts() {
|
||||
#endif
|
||||
attachInterrupt(K_MIN_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
#if !AVAILABLE_EILINE(U_MAX_PIN)
|
||||
#error "U_MAX_PIN has no EXTINT line available."
|
||||
#endif
|
||||
attachInterrupt(U_MAX_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
#if HAS_U_MIN
|
||||
#if !AVAILABLE_EILINE(U_MIN_PIN)
|
||||
#error "U_MIN_PIN has no EXTINT line available."
|
||||
#endif
|
||||
attachInterrupt(U_MIN_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
#if !AVAILABLE_EILINE(V_MAX_PIN)
|
||||
#error "V_MAX_PIN has no EXTINT line available."
|
||||
#endif
|
||||
attachInterrupt(V_MAX_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
#if HAS_V_MIN
|
||||
#if !AVAILABLE_EILINE(V_MIN_PIN)
|
||||
#error "V_MIN_PIN has no EXTINT line available."
|
||||
#endif
|
||||
attachInterrupt(V_MIN_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
#if !AVAILABLE_EILINE(W_MAX_PIN)
|
||||
#error "W_MAX_PIN has no EXTINT line available."
|
||||
#endif
|
||||
attachInterrupt(W_MAX_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
#if HAS_W_MIN
|
||||
#if !AVAILABLE_EILINE(W_MIN_PIN)
|
||||
#error "W_MIN_PIN has no EXTINT line available."
|
||||
#endif
|
||||
attachInterrupt(W_MIN_PIN, endstop_ISR, CHANGE);
|
||||
#endif
|
||||
}
|
||||
|
@@ -79,7 +79,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
||||
rtc->MODE0.INTENCLR.reg = RTC_MODE0_INTENCLR_CMP0;
|
||||
|
||||
// RTC clock setup
|
||||
OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K; // External 32.768KHz oscillator
|
||||
OSC32KCTRL->RTCCTRL.reg = OSC32KCTRL_RTCCTRL_RTCSEL_XOSC32K; // External 32.768kHz oscillator
|
||||
|
||||
// Stop timer, just in case, to be able to reconfigure it
|
||||
rtc->MODE0.CTRLA.bit.ENABLE = false;
|
||||
|
@@ -1,54 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef __SAMD51__
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#include "watchdog.h"
|
||||
|
||||
#define WDT_TIMEOUT_REG TERN(WATCHDOG_DURATION_8S, WDT_CONFIG_PER_CYC8192, WDT_CONFIG_PER_CYC4096) // 4 or 8 second timeout
|
||||
|
||||
void watchdog_init() {
|
||||
// The low-power oscillator used by the WDT runs at 32,768 Hz with
|
||||
// a 1:32 prescale, thus 1024 Hz, though probably not super precise.
|
||||
|
||||
// Setup WDT clocks
|
||||
MCLK->APBAMASK.bit.OSC32KCTRL_ = true;
|
||||
MCLK->APBAMASK.bit.WDT_ = true;
|
||||
OSC32KCTRL->OSCULP32K.bit.EN1K = true; // Enable out 1K (this is what WDT uses)
|
||||
|
||||
WDT->CTRLA.bit.ENABLE = false; // Disable watchdog for config
|
||||
SYNC(WDT->SYNCBUSY.bit.ENABLE);
|
||||
|
||||
WDT->INTENCLR.reg = WDT_INTENCLR_EW; // Disable early warning interrupt
|
||||
WDT->CONFIG.reg = WDT_TIMEOUT_REG; // Set a 4s or 8s period for chip reset
|
||||
|
||||
HAL_watchdog_refresh();
|
||||
|
||||
WDT->CTRLA.reg = WDT_CTRLA_ENABLE; // Start watchdog now in normal mode
|
||||
SYNC(WDT->SYNCBUSY.bit.ENABLE);
|
||||
}
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
#endif // __SAMD51__
|
@@ -1,31 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// Initialize watchdog with a 4 second interrupt time
|
||||
void watchdog_init();
|
||||
|
||||
// Reset watchdog. MUST be called at least every 4 seconds after the
|
||||
// first watchdog_init or SAMD will go into emergency procedures.
|
||||
inline void HAL_watchdog_refresh() {
|
||||
SYNC(WDT->SYNCBUSY.bit.CLEAR); // Test first if previous is 'ongoing' to save time waiting for command execution
|
||||
WDT->CLEAR.reg = WDT_CLEAR_CLEAR_KEY;
|
||||
}
|
@@ -24,14 +24,13 @@
|
||||
|
||||
#ifdef HAL_STM32
|
||||
|
||||
#include "HAL.h"
|
||||
#include "usb_serial.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../shared/Delay.h"
|
||||
|
||||
#include "usb_serial.h"
|
||||
|
||||
#ifdef USBCON
|
||||
DefaultSerial1 MSerial0(false, SerialUSB);
|
||||
DefaultSerial1 MSerialUSB(false, SerialUSB);
|
||||
#endif
|
||||
|
||||
#if ENABLED(SRAM_EEPROM_EMULATION)
|
||||
@@ -53,16 +52,18 @@
|
||||
// Public Variables
|
||||
// ------------------------
|
||||
|
||||
uint16_t HAL_adc_result;
|
||||
uint16_t MarlinHAL::adc_result;
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
extern void install_min_serial();
|
||||
#endif
|
||||
|
||||
// HAL initialization task
|
||||
void HAL_init() {
|
||||
void MarlinHAL::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.
|
||||
@@ -87,7 +88,7 @@ void HAL_init() {
|
||||
|
||||
SetTimerInterruptPriorities();
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER) && USBD_USE_CDC
|
||||
#if ENABLED(EMERGENCY_PARSER) && (USBD_USE_CDC || USBD_USE_CDC_MSC)
|
||||
USB_Hook_init();
|
||||
#endif
|
||||
|
||||
@@ -103,7 +104,7 @@ void HAL_init() {
|
||||
}
|
||||
|
||||
// HAL idle task
|
||||
void HAL_idletask() {
|
||||
void MarlinHAL::idletask() {
|
||||
#if HAS_SHARED_MEDIA
|
||||
// Stm32duino currently doesn't have a "loop/idle" method
|
||||
CDC_resume_receive();
|
||||
@@ -111,9 +112,9 @@ void HAL_idletask() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
|
||||
void MarlinHAL::reboot() { NVIC_SystemReset(); }
|
||||
|
||||
uint8_t HAL_get_reset_source() {
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
return
|
||||
#ifdef RCC_FLAG_IWDGRST // Some sources may not exist...
|
||||
RESET != __HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST) ? RST_WATCHDOG :
|
||||
@@ -137,24 +138,37 @@ uint8_t HAL_get_reset_source() {
|
||||
;
|
||||
}
|
||||
|
||||
void HAL_reboot() { NVIC_SystemReset(); }
|
||||
void MarlinHAL::clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
|
||||
|
||||
void _delay_ms(const int delay_ms) { delay(delay_ms); }
|
||||
// ------------------------
|
||||
// Watchdog Timer
|
||||
// ------------------------
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#define WDT_TIMEOUT_US TERN(WATCHDOG_DURATION_8S, 8000000, 4000000) // 4 or 8 second timeout
|
||||
|
||||
#include <IWatchdog.h>
|
||||
|
||||
void MarlinHAL::watchdog_init() {
|
||||
IF_DISABLED(DISABLE_WATCHDOG_INIT, IWatchdog.begin(WDT_TIMEOUT_US));
|
||||
}
|
||||
|
||||
void MarlinHAL::watchdog_refresh() {
|
||||
IWatchdog.reload();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
extern unsigned int _ebss; // end of bss section
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
// ADC
|
||||
// ------------------------
|
||||
|
||||
// TODO: Make sure this doesn't cause any delay
|
||||
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
|
||||
WEAK void flashFirmware(const int16_t) { HAL_reboot(); }
|
||||
WEAK void flashFirmware(const int16_t) { hal.reboot(); }
|
||||
|
||||
// Maple Compatibility
|
||||
volatile uint32_t systick_uptime_millis = 0;
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "Servo.h"
|
||||
#include "watchdog.h"
|
||||
#include "MarlinSerial.h"
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
@@ -44,64 +43,74 @@
|
||||
#define CPU_ST7920_DELAY_2 40
|
||||
#define CPU_ST7920_DELAY_3 340
|
||||
|
||||
//
|
||||
// Serial Ports
|
||||
//
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
#ifdef USBCON
|
||||
#include <USBSerial.h>
|
||||
#include "../../core/serial_hook.h"
|
||||
typedef ForwardSerial1Class< decltype(SerialUSB) > DefaultSerial1;
|
||||
extern DefaultSerial1 MSerial0;
|
||||
extern DefaultSerial1 MSerialUSB;
|
||||
#endif
|
||||
|
||||
#define _MSERIAL(X) MSerial##X
|
||||
#define MSERIAL(X) _MSERIAL(X)
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
#define MYSERIAL1 MSerial0
|
||||
#elif WITHIN(SERIAL_PORT, 1, 6)
|
||||
#if WITHIN(SERIAL_PORT, 1, 6)
|
||||
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
|
||||
#elif !defined(USBCON)
|
||||
#error "SERIAL_PORT must be from 1 to 6."
|
||||
#elif SERIAL_PORT == -1
|
||||
#define MYSERIAL1 MSerialUSB
|
||||
#else
|
||||
#error "SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
|
||||
#error "SERIAL_PORT must be from 1 to 6, or -1 for Native USB."
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
#if SERIAL_PORT_2 == -1
|
||||
#define MYSERIAL2 MSerial0
|
||||
#elif WITHIN(SERIAL_PORT_2, 1, 6)
|
||||
#if WITHIN(SERIAL_PORT_2, 1, 6)
|
||||
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
|
||||
#elif !defined(USBCON)
|
||||
#error "SERIAL_PORT must be from 1 to 6."
|
||||
#elif SERIAL_PORT_2 == -1
|
||||
#define MYSERIAL2 MSerialUSB
|
||||
#else
|
||||
#error "SERIAL_PORT_2 must be from 1 to 6. You can also use -1 if the board supports Native USB."
|
||||
#error "SERIAL_PORT_2 must be from 1 to 6, or -1 for Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_3
|
||||
#if SERIAL_PORT_3 == -1
|
||||
#define MYSERIAL3 MSerial0
|
||||
#elif WITHIN(SERIAL_PORT_3, 1, 6)
|
||||
#if WITHIN(SERIAL_PORT_3, 1, 6)
|
||||
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
|
||||
#elif !defined(USBCON)
|
||||
#error "SERIAL_PORT must be from 1 to 6."
|
||||
#elif SERIAL_PORT_3 == -1
|
||||
#define MYSERIAL3 MSerialUSB
|
||||
#else
|
||||
#error "SERIAL_PORT_3 must be from 1 to 6. You can also use -1 if the board supports Native USB."
|
||||
#error "SERIAL_PORT_3 must be from 1 to 6, or -1 for Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MMU2_SERIAL_PORT
|
||||
#if MMU2_SERIAL_PORT == -1
|
||||
#define MMU2_SERIAL MSerial0
|
||||
#elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
|
||||
#if WITHIN(MMU2_SERIAL_PORT, 1, 6)
|
||||
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
|
||||
#elif !defined(USBCON)
|
||||
#error "SERIAL_PORT must be from 1 to 6."
|
||||
#elif MMU2_SERIAL_PORT == -1
|
||||
#define MMU2_SERIAL MSerialUSB
|
||||
#else
|
||||
#error "MMU2_SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
|
||||
#error "MMU2_SERIAL_PORT must be from 1 to 6, or -1 for Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LCD_SERIAL_PORT
|
||||
#if LCD_SERIAL_PORT == -1
|
||||
#define LCD_SERIAL MSerial0
|
||||
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
|
||||
#if WITHIN(LCD_SERIAL_PORT, 1, 6)
|
||||
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
|
||||
#elif !defined(USBCON)
|
||||
#error "SERIAL_PORT must be from 1 to 6."
|
||||
#elif LCD_SERIAL_PORT == -1
|
||||
#define LCD_SERIAL MSerialUSB
|
||||
#else
|
||||
#error "LCD_SERIAL_PORT must be from 1 to 6. You can also use -1 if the board supports Native USB."
|
||||
#error "LCD_SERIAL_PORT must be from 1 to 6, or -1 for Native USB."
|
||||
#endif
|
||||
#if HAS_DGUS_LCD
|
||||
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
|
||||
@@ -115,77 +124,34 @@
|
||||
#define analogInputToDigitalPin(p) (p)
|
||||
#endif
|
||||
|
||||
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
|
||||
#define ISRS_ENABLED() (!__get_PRIMASK())
|
||||
#define ENABLE_ISRS() __enable_irq()
|
||||
#define DISABLE_ISRS() __disable_irq()
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
#define CRITICAL_SECTION_START() const bool irqon = !__get_PRIMASK(); __disable_irq()
|
||||
#define CRITICAL_SECTION_END() if (irqon) __enable_irq()
|
||||
#define cli() __disable_irq()
|
||||
#define sei() __enable_irq()
|
||||
|
||||
// On AVR this is in math.h?
|
||||
#define square(x) ((x)*(x))
|
||||
|
||||
// ------------------------
|
||||
// Types
|
||||
// ------------------------
|
||||
|
||||
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
|
||||
|
||||
#ifdef STM32G0B1xx
|
||||
typedef int32_t pin_t;
|
||||
#else
|
||||
typedef int16_t pin_t;
|
||||
#endif
|
||||
|
||||
#define HAL_SERVO_LIB libServo
|
||||
class libServo;
|
||||
typedef libServo hal_servo_t;
|
||||
#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
|
||||
#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
|
||||
|
||||
// ------------------------
|
||||
// Public Variables
|
||||
// ------------------------
|
||||
|
||||
// result of last ADC conversion
|
||||
extern uint16_t HAL_adc_result;
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
|
||||
// Memory related
|
||||
#define __bss_end __bss_end__
|
||||
|
||||
// Enable hooks into setup for HAL
|
||||
void HAL_init();
|
||||
#define HAL_IDLETASK 1
|
||||
void HAL_idletask();
|
||||
|
||||
// Clear reset reason
|
||||
void HAL_clear_reset_source();
|
||||
|
||||
// Reset reason
|
||||
uint8_t HAL_get_reset_source();
|
||||
|
||||
void HAL_reboot();
|
||||
|
||||
void _delay_ms(const int delay);
|
||||
|
||||
extern "C" char* _sbrk(int incr);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
|
||||
static inline int freeMemory() {
|
||||
volatile char top;
|
||||
return &top - reinterpret_cast<char*>(_sbrk(0));
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
//
|
||||
// ADC
|
||||
//
|
||||
|
||||
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
|
||||
// ------------------------
|
||||
|
||||
#ifdef ADC_RESOLUTION
|
||||
#define HAL_ADC_RESOLUTION ADC_RESOLUTION
|
||||
@@ -194,16 +160,10 @@ static inline int freeMemory() {
|
||||
#endif
|
||||
|
||||
#define HAL_ADC_VREF 3.3
|
||||
#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();
|
||||
|
||||
//
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
#define GET_PIN_MAP_PIN(index) index
|
||||
#define GET_PIN_MAP_INDEX(pin) pin
|
||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||
@@ -226,17 +186,96 @@ extern volatile uint32_t systick_uptime_millis;
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
|
||||
/**
|
||||
* set_pwm_frequency
|
||||
* Set the frequency of the timer corresponding to the provided pin
|
||||
* All Timer PWM pins run at the same frequency
|
||||
*/
|
||||
void set_pwm_frequency(const pin_t pin, int f_desired);
|
||||
// ------------------------
|
||||
// Class Utilities
|
||||
// ------------------------
|
||||
|
||||
/**
|
||||
* set_pwm_duty
|
||||
* Set the PWM duty cycle of the provided pin to the provided value
|
||||
* Optionally allows inverting the duty cycle [default = false]
|
||||
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
// Memory related
|
||||
#define __bss_end __bss_end__
|
||||
|
||||
extern "C" char* _sbrk(int incr);
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
static inline int freeMemory() {
|
||||
volatile char top;
|
||||
return &top - reinterpret_cast<char*>(_sbrk(0));
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return !__get_PRIMASK(); }
|
||||
static void isr_on() { sei(); }
|
||||
static void isr_off() { cli(); }
|
||||
|
||||
static void delay_ms(const int ms) { delay(ms); }
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source();
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
static uint16_t adc_result;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {
|
||||
analogReadResolution(HAL_ADC_RESOLUTION);
|
||||
}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const pin_t pin) { pinMode(pin, INPUT); }
|
||||
|
||||
// Begin ADC sampling on the given pin. Called from Temperature::isr!
|
||||
static void adc_start(const pin_t pin) { adc_result = analogRead(pin); }
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return adc_result; }
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* Optionally invert the duty cycle [default = false]
|
||||
* Optionally change the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
/**
|
||||
* Set the frequency of the timer for the given pin.
|
||||
* All Timer PWM pins run at the same frequency.
|
||||
*/
|
||||
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
|
||||
|
||||
};
|
||||
|
@@ -102,9 +102,9 @@ static SPISettings spiConfig;
|
||||
|
||||
// Soft SPI receive byte
|
||||
uint8_t spiRec() {
|
||||
DISABLE_ISRS(); // No interrupts during byte receive
|
||||
hal.isr_off(); // No interrupts during byte receive
|
||||
const uint8_t data = HAL_SPI_STM32_SpiTransfer_Mode_3(0xFF);
|
||||
ENABLE_ISRS(); // Enable interrupts
|
||||
hal.isr_on(); // Enable interrupts
|
||||
return data;
|
||||
}
|
||||
|
||||
@@ -116,9 +116,9 @@ static SPISettings spiConfig;
|
||||
|
||||
// Soft SPI send byte
|
||||
void spiSend(uint8_t data) {
|
||||
DISABLE_ISRS(); // No interrupts during byte send
|
||||
hal.isr_off(); // No interrupts during byte send
|
||||
HAL_SPI_STM32_SpiTransfer_Mode_3(data); // Don't care what is received
|
||||
ENABLE_ISRS(); // Enable interrupts
|
||||
hal.isr_on(); // Enable interrupts
|
||||
}
|
||||
|
||||
// Soft SPI send block
|
||||
|
@@ -28,8 +28,7 @@
|
||||
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
|
||||
#include "../shared/HAL_MinSerial.h"
|
||||
#include "watchdog.h"
|
||||
#include "../shared/MinSerial.h"
|
||||
|
||||
/* Instruction Synchronization Barrier */
|
||||
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
|
||||
@@ -120,7 +119,7 @@ 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());
|
||||
hal.watchdog_refresh();
|
||||
sw_barrier();
|
||||
}
|
||||
regs->DR = c;
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user