Compare commits
393 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8e027304c8 | |||
| 79dcfe5455 | |||
| 834025e486 | |||
| 05d51f9c7f | |||
| 44589a964d | |||
| b3e3a58e8b | |||
| 16106e3961 | |||
| 6dad386de9 | |||
| 8df0cca036 | |||
| 62c280a60f | |||
| 2087a1330d | |||
| cab94bb030 | |||
| 26d01c5f2c | |||
| 6b22f8152b | |||
| e7cf3c7970 | |||
| 77227f66c2 | |||
| efde96131d | |||
| 051b95c845 | |||
| f595e40ceb | |||
| 0d8a695ea9 | |||
| fcf9f22390 | |||
| 43fa749d27 | |||
| 6cc11b76fd | |||
| c2f7a568f3 | |||
| a8f650079b | |||
| 91fafec424 | |||
| 11f8244573 | |||
| e1df912dc7 | |||
| 35594a23de | |||
| 83922dd4e6 | |||
| a5c5bb9660 | |||
| 18b6d6c8ca | |||
| 2c6ed101c1 | |||
| 644c91ce8b | |||
| 1b3941c0d2 | |||
| e14faf0413 | |||
| f84d51ec06 | |||
| 8aa3273242 | |||
| 6f68942e83 | |||
| 9881f758d7 | |||
| 945d5dbe13 | |||
| 7d08ab4fb7 | |||
| 4a2b08f883 | |||
| 1d2aecaca8 | |||
| a4297ff492 | |||
| 4f299bf867 | |||
| 038042b09e | |||
| 8f4fb42bfb | |||
| 6fdf9bf2ea | |||
| 6c813fcd16 | |||
| 1e525c5976 | |||
| b1239a42a8 | |||
| 06d7d2ada4 | |||
| 9467b68608 | |||
| e338420df8 | |||
| d0e7c2c208 | |||
| 1ab6e5cdc9 | |||
| 551f5ada94 | |||
| e927e58d32 | |||
| 8a3ad7abcc | |||
| 5b0096c350 | |||
| c3b58f1938 | |||
| e003552804 | |||
| 50f79823d2 | |||
| 3c449b220f | |||
| c5af435449 | |||
| 45cf997341 | |||
| 0820f94a5a | |||
| d5cf0b3348 | |||
| 0ae64f1140 | |||
| c80d1ea97d | |||
| 1013323f18 | |||
| 25736abc0f | |||
| dc0b490bf0 | |||
| b95d073f02 | |||
| 9e5c143b87 | |||
| 458e1aea41 | |||
| 0765dfd43f | |||
| 4f9ba7e991 | |||
| 9ab0b18256 | |||
| 57ee26e909 | |||
| d23ab529d8 | |||
| c9ef1277f3 | |||
| 2b23bdce70 | |||
| 61a543a471 | |||
| 83aac65664 | |||
| c46ed8f57d | |||
| 9fc3642f2a | |||
| 328f6d9aff | |||
| 35d4791518 | |||
| 094701cc71 | |||
| f6d109287f | |||
| fdf6445a51 | |||
| 68d4869616 | |||
| 5f61a896d9 | |||
| bcb6f6e85e | |||
| 8e71f7add4 | |||
| 243f7f2834 | |||
| 89f86bc550 | |||
| 1b03fc3f63 | |||
| aa0904600b | |||
| 6542f61aaf | |||
| b229fba98b | |||
| 8a3cd2f47b | |||
| 9b7b1a3635 | |||
| 15a100dafa | |||
| c918e90b8d | |||
| 2635182dcb | |||
| ace358327d | |||
| eabab4322d | |||
| 66e61f4de3 | |||
| 42f8cc4606 | |||
| 82d1851743 | |||
| 6053fae1ac | |||
| 2f91154cbd | |||
| 6704c0bc4c | |||
| b19d44ba0b | |||
| 2a2c161d87 | |||
| f4a5db52e8 | |||
| a76b92bce0 | |||
| e201f4e656 | |||
| 2a1c2e26ed | |||
| 20c72845a0 | |||
| d77027276c | |||
| 6e39bd6c85 | |||
| 34f3e5bd88 | |||
| da3b7ab259 | |||
| 6909f5fa4f | |||
| 03d9254079 | |||
| 4ae9bf3b9d | |||
| 306e03b03b | |||
| e701e0bb25 | |||
| dab60a1cb7 | |||
| 1be5a7b5d7 | |||
| af1c7e1a81 | |||
| 1766ee15a3 | |||
| ce26fccc3e | |||
| 0100b7be4d | |||
| fab4fb7fbb | |||
| b8bd331efd | |||
| e42cbe7500 | |||
| c84f839fc7 | |||
| c2874ca809 | |||
| 4bd4c1f3bc | |||
| 637bff9982 | |||
| 8025117ac0 | |||
| 1a1db10634 | |||
| 5b68a3f79b | |||
| d33111b215 | |||
| 53b202cf9d | |||
| 9c86ca3a19 | |||
| e33dafeb80 | |||
| 5b4af52d04 | |||
| 83320f1052 | |||
| 1dc17aa64c | |||
| 68f13ca9cf | |||
| 5a2cc41f9c | |||
| 7f10f8932e | |||
| 1866e25eef | |||
| ec4db07a51 | |||
| becef39c19 | |||
| 24a7ed44b3 | |||
| a167e2e948 | |||
| 59c2fe4561 | |||
| b7fd046d59 | |||
| 4c9146cffd | |||
| 1bed10c380 | |||
| 1c4fc4603a | |||
| 35d9920ef8 | |||
| 1ad036c52f | |||
| 7f72e78520 | |||
| 6fe317e385 | |||
| e5f2daa001 | |||
| 4ba35d3284 | |||
| 91f9e1671f | |||
| 232a104a92 | |||
| aba35ec1af | |||
| d8df9ffd61 | |||
| f4b6870ad1 | |||
| 8938e4d23c | |||
| 0f0edd2e37 | |||
| 7b0eb2d9f8 | |||
| 44c1f2ef6b | |||
| 9cdfaf693c | |||
| 6f7d14def3 | |||
| a25f321abb | |||
| 7e5d5330d6 | |||
| b4dcdcc885 | |||
| 2dff08c86b | |||
| ca8182344f | |||
| 21c48d9f92 | |||
| 90b5645223 | |||
| d816c1b38d | |||
| 8ccbac5317 | |||
| 223bbc9bca | |||
| 4ffa2e80e4 | |||
| bc0e4c6d50 | |||
| a29fb8088f | |||
| 57ca996c31 | |||
| 8cf4c0515d | |||
| 2634d0cc52 | |||
| deca553e18 | |||
| 007af47768 | |||
| 8455408382 | |||
| 3b4c759872 | |||
| edeea5a6fb | |||
| 6577fba768 | |||
| 7726e26ac0 | |||
| c2972899ca | |||
| 58329b066d | |||
| 2419a167ee | |||
| 0138cb0552 | |||
| aacc2d3dc5 | |||
| 39c5793575 | |||
| 258904e86c | |||
| 57700b4edd | |||
| c5b3bacfc9 | |||
| 999f33b1e7 | |||
| 4b8a1ec86f | |||
| bb3c5aa186 | |||
| 5f2908a117 | |||
| ed2071aabd | |||
| 48e4863cb6 | |||
| 3b4a5a1ae8 | |||
| 6d83f7a579 | |||
| 23926bb4c2 | |||
| 8fd6693d53 | |||
| 9706cd0d7d | |||
| 504fec9823 | |||
| 05a7be7b25 | |||
| fa0ad4b594 | |||
| e84de791ab | |||
| 9be1de54ae | |||
| 147fbd9d39 | |||
| 8a1643587b | |||
| 2f219d6824 | |||
| 33d261141a | |||
| fc0615fbd1 | |||
| 48f0d55097 | |||
| 6eef807520 | |||
| 0f5703a837 | |||
| de0706e52c | |||
| 7361c03aa4 | |||
| e92854b0ed | |||
| 0941e8e869 | |||
| a61fab7302 | |||
| 0dc46a8d27 | |||
| 30ec700a1d | |||
| 8fb54d4621 | |||
| c47575f244 | |||
| 3f4e4a4d89 | |||
| 2dc543c4f5 | |||
| 1d31b6215a | |||
| cee517bc24 | |||
| 3c3c9f1a8e | |||
| 068624a726 | |||
| ec2864be74 | |||
| 1bab0243fd | |||
| 57e27339b6 | |||
| d60a280bc5 | |||
| 0a7be1ac58 | |||
| f101aeb3ec | |||
| 62c0ab072c | |||
| 55b8d1b9d3 | |||
| d924d17209 | |||
| 920799e38d | |||
| f65f7a685b | |||
| 623631286f | |||
| abe139192f | |||
| 5979aab1c7 | |||
| f73fad1b2f | |||
| 1497c40379 | |||
| 64aff274b4 | |||
| 509dfe92d0 | |||
| 58048e7748 | |||
| 9805d2bc38 | |||
| a88e847295 | |||
| 55417b28fe | |||
| 6a67ad4e4a | |||
| 132c37a651 | |||
| e08b293b54 | |||
| f39e2bc1e4 | |||
| e94fa7d5dc | |||
| 954b4493d2 | |||
| fc287b44da | |||
| 54e7b933cd | |||
| 9baeeedd69 | |||
| 3826b13ab1 | |||
| b8741a59df | |||
| 2b6ce3006e | |||
| d956a6ba00 | |||
| 9c376f120c | |||
| b1bb307dab | |||
| cb4a79173b | |||
| 35dbc286bd | |||
| c7923c0397 | |||
| a811005ab2 | |||
| 71368b5fa5 | |||
| f76025b79c | |||
| f5488f96cc | |||
| 4fb1c42500 | |||
| d9ec3795fb | |||
| cc51bc29e1 | |||
| 914501f67e | |||
| 31d286750c | |||
| d6fc3d2b69 | |||
| 93ffd57383 | |||
| 307dfb15ca | |||
| 884f7c7db9 | |||
| 95b70233f2 | |||
| 76d784f75f | |||
| d8545551fe | |||
| b46191715d | |||
| dc5c5bdf82 | |||
| d976f291fd | |||
| 1e66cc39c2 | |||
| 2266f1ad67 | |||
| a0125c85d4 | |||
| 546b3066c3 | |||
| 0aebcc4ded | |||
| 12a869e2ad | |||
| 645c7dc370 | |||
| 1a79537645 | |||
| 6355798bfd | |||
| 58d1b1be28 | |||
| 3c13be165b | |||
| 8c3ba69c98 | |||
| 757156de72 | |||
| 757d66e2c5 | |||
| b06e378703 | |||
| 90d9f1acc9 | |||
| 22f0496c9b | |||
| d0e9ff0e29 | |||
| 975c8f4b77 | |||
| 4520a51bbe | |||
| 432c879328 | |||
| 6cbd7a48d1 | |||
| 751c88aa5b | |||
| 76f1f9d3b3 | |||
| a526c3d77a | |||
| 1a6a604310 | |||
| 0a3c42a87c | |||
| 70eac0fe4f | |||
| 873f6c0b63 | |||
| e1b22a5c75 | |||
| 640282b8dc | |||
| 0ff3018fd2 | |||
| 9c6e0428af | |||
| 43e9fe7f88 | |||
| 20dea22091 | |||
| ee90ae2c87 | |||
| fb76ce841b | |||
| 0ca33429b6 | |||
| e4e6abe5af | |||
| 76a0cab782 | |||
| 3e9fb34892 | |||
| 9e73fd7149 | |||
| 371ac49fc1 | |||
| f6e123430f | |||
| 3b142e531c | |||
| d355ad04a0 | |||
| a7a730f811 | |||
| c9a9b25d41 | |||
| 41a9dea149 | |||
| ec7cc59818 | |||
| ca06c6eab9 | |||
| d08223429b | |||
| 8aca38351c | |||
| 9c872b214c | |||
| 3522d5376c | |||
| 2c0b8b52d8 | |||
| 384ff264d7 | |||
| 2b3ba02f09 | |||
| bcd9bb9628 | |||
| 41f73cb457 | |||
| 845e2f6fb7 | |||
| c9b97b8d64 | |||
| 833ea4ec29 | |||
| 12aded95dc | |||
| 0e8e735e4c | |||
| 49db4ef5e4 | |||
| 08c51a405a | |||
| eda61a2cbd | |||
| f6b425613e | |||
| e260d90d21 | |||
| 30a7c4ca52 | |||
| 85c0875db2 | |||
| 6f3d7d864f | |||
| 3d70aca6e8 | |||
| 58ce5182c2 | |||
| 7dd34848b6 | |||
| 1a555b3812 | |||
| ea7bebb568 |
+5
-1
@@ -14,6 +14,10 @@ end_of_line = lf
|
|||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[{*.py,*.conf,*.sublime-project}]
|
[{*.py}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 4
|
||||||
|
|
||||||
|
[{*.conf,*.sublime-project}]
|
||||||
indent_style = tab
|
indent_style = tab
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|||||||
@@ -14,13 +14,13 @@ body:
|
|||||||
|
|
||||||
## Before Reporting a Bug
|
## Before Reporting a Bug
|
||||||
|
|
||||||
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
|
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/.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.
|
- Test with the [`bugfix-2.1.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.1.x.zip) to see whether the issue still exists.
|
||||||
|
|
||||||
## Instructions
|
## 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/bugfix-2.0.x/.github/contributing.md) for additional guidelines.
|
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/bugfix-2.1.x/.github/contributing.md) for additional guidelines.
|
||||||
|
|
||||||
1. Provide a good title starting with [BUG].
|
1. Provide a good title starting with [BUG].
|
||||||
2. Fill out all sections of this bug report form.
|
2. Fill out all sections of this bug report form.
|
||||||
@@ -28,10 +28,10 @@ body:
|
|||||||
|
|
||||||
- type: dropdown
|
- type: dropdown
|
||||||
attributes:
|
attributes:
|
||||||
label: Did you test the latest `bugfix-2.0.x` code?
|
label: Did you test the latest `bugfix-2.1.x` code?
|
||||||
description: >-
|
description: >-
|
||||||
Always try the latest code to make sure the issue you are reporting is not already fixed. To download
|
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).
|
the latest code just [click this link](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.1.x.zip).
|
||||||
options:
|
options:
|
||||||
- Yes, and the problem still exists.
|
- Yes, and the problem still exists.
|
||||||
- No, but I will test it now!
|
- No, but I will test it now!
|
||||||
@@ -50,6 +50,8 @@ body:
|
|||||||
Describe the bug in this section. Tell us what you were trying to do and what
|
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
|
happened that you did not expect. Provide a clear and concise description of the
|
||||||
problem and include as many details as possible.
|
problem and include as many details as possible.
|
||||||
|
|
||||||
|
When pasting formatted text don't forget to put ` ``` ` (on its own line) before and after to make it readable.
|
||||||
placeholder: |
|
placeholder: |
|
||||||
Marlin doesn't work.
|
Marlin doesn't work.
|
||||||
validations:
|
validations:
|
||||||
@@ -149,21 +151,28 @@ body:
|
|||||||
|
|
||||||
- type: markdown
|
- type: markdown
|
||||||
attributes:
|
attributes:
|
||||||
value: >-
|
value: |
|
||||||
## Other things to include
|
# Attachments
|
||||||
|
|
||||||
Please also be sure to include these items to help with troubleshooting:
|
- type: checkboxes
|
||||||
|
attributes:
|
||||||
|
label: Don't forget to include
|
||||||
|
options:
|
||||||
|
- label: A ZIP file containing your `Configuration.h` and `Configuration_adv.h`.
|
||||||
|
required: true
|
||||||
|
|
||||||
* **A ZIP file** containing your `Configuration.h` and `Configuration_adv.h`.
|
- type: markdown
|
||||||
(Please don't paste lengthy configuration text here.)
|
attributes:
|
||||||
* **Log output** from the host. (`M111 S247` for maximum logging.)
|
value: |
|
||||||
* **Images or videos** demonstrating the problem, if it helps to make it clear.
|
### Optional items to include:
|
||||||
* **A G-Code file** that exposes the problem, if not affecting _all_ G-code.
|
- 'Log output from the host. (`M111 S247` for maximum logging.)'
|
||||||
|
- Images or videos demonstrating the problem, if it helps to make it clear.
|
||||||
If you've made any other modifications to the firmware, please describe them in detail in the space provided.
|
- A G-Code file that exposes the problem, if not affecting _all_ G-code.
|
||||||
|
|
||||||
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
|
- type: textarea
|
||||||
attributes:
|
attributes:
|
||||||
label: Additional information & file uploads
|
label: Additional information & file uploads
|
||||||
|
description: >-
|
||||||
|
If you've made any other modifications to the firmware, please describe them in detail.
|
||||||
|
|
||||||
|
When pasting formatted text don't forget to put ` ``` ` (on its own line) before and after to make it readable.
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ body:
|
|||||||
|
|
||||||
- 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.
|
- 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.
|
- Check the latest [`bugfix-2.1.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.1.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.
|
- 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.
|
||||||
|
|
||||||
|
|||||||
@@ -34,8 +34,11 @@ This project and everyone participating in it is governed by the [Marlin Code of
|
|||||||
|
|
||||||
We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions.
|
We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions.
|
||||||
|
|
||||||
* [Marlin RepRap forum](https://reprap.org/forum/list.php?415)
|
- [Marlin Documentation](https://marlinfw.org) - Official Marlin documentation
|
||||||
* [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/)
|
- Facebook Group ["Marlin Firmware"](https://www.facebook.com/groups/1049718498464482/)
|
||||||
|
- RepRap.org [Marlin Forum](https://forums.reprap.org/list.php?415)
|
||||||
|
- Facebook Group ["Marlin Firmware for 3D Printers"](https://www.facebook.com/groups/3Dtechtalk/)
|
||||||
|
- [Marlin Configuration](https://www.youtube.com/results?search_query=marlin+configuration) on YouTube
|
||||||
|
|
||||||
If chat is more your speed, you can join the MarlinFirmware Discord server:
|
If chat is more your speed, you can join the MarlinFirmware Discord server:
|
||||||
|
|
||||||
@@ -116,7 +119,7 @@ Unsure where to begin contributing to Marlin? You can start by looking through t
|
|||||||
|
|
||||||
### Pull Requests
|
### Pull Requests
|
||||||
|
|
||||||
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.
|
Pull Requests should always be targeted to working branches (e.g., `bugfix-2.1.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).
|
* Fill in [the required template](pull_request_template.md).
|
||||||
* Don't include issue numbers in the PR title.
|
* Don't include issue numbers in the PR title.
|
||||||
|
|||||||
@@ -18,12 +18,32 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Check out bugfix-2.0.x
|
- name: Check out bugfix-2.1.x
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
ref: bugfix-2.0.x
|
ref: bugfix-2.1.x
|
||||||
|
|
||||||
- name: Bump Distribution Date
|
- name: Bump Date (bugfix-2.0.x)
|
||||||
|
run: |
|
||||||
|
# Inline Bump Script
|
||||||
|
if [[ ! "$( git log -1 --pretty=%B )" =~ ^\[cron\] ]]; then
|
||||||
|
DIST=$( date +"%Y-%m-%d" )
|
||||||
|
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/src/inc/Version.h" && \
|
||||||
|
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/Version.h" && \
|
||||||
|
git config user.name "${GITHUB_ACTOR}" && \
|
||||||
|
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
|
||||||
|
git add . && \
|
||||||
|
git commit -m "[cron] Bump distribution date ($DIST)" && \
|
||||||
|
git push
|
||||||
|
fi
|
||||||
|
exit 0
|
||||||
|
|
||||||
|
- name: Check out bugfix-2.1.x
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
ref: bugfix-2.1.x
|
||||||
|
|
||||||
|
- name: Bump Date (bugfix-2.1.x)
|
||||||
run: |
|
run: |
|
||||||
# Inline Bump Script
|
# Inline Bump Script
|
||||||
if [[ ! "$( git log -1 --pretty=%B )" =~ ^\[cron\] ]]; then
|
if [[ ! "$( git log -1 --pretty=%B )" =~ ^\[cron\] ]]; then
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ on:
|
|||||||
- 1.0.x
|
- 1.0.x
|
||||||
- 1.1.x
|
- 1.1.x
|
||||||
- 2.0.x
|
- 2.0.x
|
||||||
|
- 2.1.x
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
bad_target:
|
bad_target:
|
||||||
@@ -26,8 +27,8 @@ jobs:
|
|||||||
comment: >
|
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.
|
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.
|
Please redo this PR starting with the `bugfix-2.1.x` branch and be careful to target `bugfix-2.1.x` when resubmitting the PR. Patches may also target `bugfix-2.0.x` if they are specifically for 2.0.9.x.
|
||||||
|
|
||||||
It may help to set your fork's default branch to `bugfix-2.0.x`.
|
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.
|
See [this page](https://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions.
|
||||||
|
|||||||
@@ -25,4 +25,4 @@ jobs:
|
|||||||
days-before-close: 10
|
days-before-close: 10
|
||||||
stale-issue-label: 'stale-closing-soon'
|
stale-issue-label: 'stale-closing-soon'
|
||||||
exempt-all-assignees: true
|
exempt-all-assignees: true
|
||||||
exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: Discussion,Needs: Documentation,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking'
|
exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: More Data,Needs: Discussion,Needs: Documentation,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking'
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ name: CI
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- bugfix-2.0.x
|
- bugfix-2.1.x
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- config/**
|
- config/**
|
||||||
- data/**
|
- data/**
|
||||||
@@ -16,7 +16,7 @@ on:
|
|||||||
- '**/*.md'
|
- '**/*.md'
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- bugfix-2.0.x
|
- bugfix-2.1.x
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- config/**
|
- config/**
|
||||||
- data/**
|
- data/**
|
||||||
@@ -45,6 +45,7 @@ jobs:
|
|||||||
- teensy35
|
- teensy35
|
||||||
- teensy41
|
- teensy41
|
||||||
- SAMD51_grandcentral_m4
|
- SAMD51_grandcentral_m4
|
||||||
|
- PANDA_PI_V29
|
||||||
|
|
||||||
# Extended AVR Environments
|
# Extended AVR Environments
|
||||||
|
|
||||||
@@ -65,7 +66,7 @@ jobs:
|
|||||||
#- mks_robin_maple
|
#- mks_robin_maple
|
||||||
- mks_robin_lite_maple
|
- mks_robin_lite_maple
|
||||||
- mks_robin_pro_maple
|
- mks_robin_pro_maple
|
||||||
#- mks_robin_nano35_maple
|
#- mks_robin_nano_v1v2_maple
|
||||||
#- STM32F103RE_creality_maple
|
#- STM32F103RE_creality_maple
|
||||||
- STM32F103VE_ZM3E4V2_USB_maple
|
- STM32F103VE_ZM3E4V2_USB_maple
|
||||||
|
|
||||||
@@ -79,7 +80,6 @@ jobs:
|
|||||||
- STM32F401RC_creality
|
- STM32F401RC_creality
|
||||||
- STM32F103VE_longer
|
- STM32F103VE_longer
|
||||||
- STM32F407VE_black
|
- STM32F407VE_black
|
||||||
- STM32F401VE_STEVAL
|
|
||||||
- BIGTREE_BTT002
|
- BIGTREE_BTT002
|
||||||
- BIGTREE_SKR_PRO
|
- BIGTREE_SKR_PRO
|
||||||
- BIGTREE_GTR_V1_0
|
- BIGTREE_GTR_V1_0
|
||||||
@@ -93,12 +93,17 @@ jobs:
|
|||||||
- rumba32
|
- rumba32
|
||||||
- LERDGEX
|
- LERDGEX
|
||||||
- LERDGEK
|
- LERDGEK
|
||||||
- mks_robin_nano35
|
- mks_robin_nano_v1v2
|
||||||
|
#- mks_robin_nano_v1v2_usbmod
|
||||||
|
#- mks_robin_nano_v1_3_f4_usbmod
|
||||||
- NUCLEO_F767ZI
|
- NUCLEO_F767ZI
|
||||||
- REMRAM_V1
|
- REMRAM_V1
|
||||||
- BTT_SKR_SE_BX
|
- BTT_SKR_SE_BX
|
||||||
- chitu_f103
|
- chitu_f103
|
||||||
- Index_Mobo_Rev03
|
- Opulo_Lumen_REV3
|
||||||
|
|
||||||
|
# ESP32 environments
|
||||||
|
- mks_tinybee
|
||||||
|
|
||||||
# Put lengthy tests last
|
# Put lengthy tests last
|
||||||
|
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ vc-fileutils.settings
|
|||||||
imgui.ini
|
imgui.ini
|
||||||
eeprom.dat
|
eeprom.dat
|
||||||
spi_flash.bin
|
spi_flash.bin
|
||||||
|
fs.img
|
||||||
|
|
||||||
#cmake
|
#cmake
|
||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
|||||||
+333
-74
@@ -35,7 +35,7 @@
|
|||||||
*
|
*
|
||||||
* Advanced settings can be found in Configuration_adv.h
|
* Advanced settings can be found in Configuration_adv.h
|
||||||
*/
|
*/
|
||||||
#define CONFIGURATION_H_VERSION 02010000
|
#define CONFIGURATION_H_VERSION 02010200
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//============================= Getting Started =============================
|
//============================= Getting Started =============================
|
||||||
@@ -57,15 +57,6 @@
|
|||||||
* https://www.thingiverse.com/thing:1278865
|
* https://www.thingiverse.com/thing:1278865
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//===========================================================================
|
|
||||||
//========================== DELTA / SCARA / TPARA ==========================
|
|
||||||
//===========================================================================
|
|
||||||
//
|
|
||||||
// Download configurations from the link above and customize for your machine.
|
|
||||||
// Examples are located in config/examples/delta, .../SCARA, and .../TPARA.
|
|
||||||
//
|
|
||||||
//===========================================================================
|
|
||||||
|
|
||||||
// @section info
|
// @section info
|
||||||
|
|
||||||
// Author info of this build printed to the host during boot and M115
|
// Author info of this build printed to the host during boot and M115
|
||||||
@@ -121,6 +112,7 @@
|
|||||||
* :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
|
* :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
|
||||||
*/
|
*/
|
||||||
#define BAUDRATE 250000
|
#define BAUDRATE 250000
|
||||||
|
|
||||||
//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate
|
//#define BAUD_RATE_GCODE // Enable G-code M575 to set the baud rate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -129,7 +121,7 @@
|
|||||||
* :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
|
* :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
*/
|
*/
|
||||||
//#define SERIAL_PORT_2 -1
|
//#define SERIAL_PORT_2 -1
|
||||||
//#define BAUDRATE_2 250000 // Enable to override BAUDRATE
|
//#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Select a third serial port on the board to use for communication with the host.
|
* Select a third serial port on the board to use for communication with the host.
|
||||||
@@ -137,7 +129,7 @@
|
|||||||
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
|
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||||
*/
|
*/
|
||||||
//#define SERIAL_PORT_3 1
|
//#define SERIAL_PORT_3 1
|
||||||
//#define BAUDRATE_3 250000 // Enable to override BAUDRATE
|
//#define BAUDRATE_3 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE
|
||||||
|
|
||||||
// Enable the Bluetooth serial interface on AT90USB devices
|
// Enable the Bluetooth serial interface on AT90USB devices
|
||||||
//#define BLUETOOTH
|
//#define BLUETOOTH
|
||||||
@@ -149,6 +141,8 @@
|
|||||||
// Choose your own or use a service like https://www.uuidgenerator.net/version4
|
// Choose your own or use a service like https://www.uuidgenerator.net/version4
|
||||||
//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
|
//#define MACHINE_UUID "00000000-0000-0000-0000-000000000000"
|
||||||
|
|
||||||
|
// @section stepper drivers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stepper Drivers
|
* Stepper Drivers
|
||||||
*
|
*
|
||||||
@@ -157,13 +151,12 @@
|
|||||||
*
|
*
|
||||||
* Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
|
* Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
|
||||||
*
|
*
|
||||||
* Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01,
|
* Options: A4988, A5984, DRV8825, LV8729, TB6560, TB6600, TMC2100,
|
||||||
* TB6560, TB6600, TMC2100,
|
|
||||||
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
|
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
|
||||||
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
|
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
|
||||||
* TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE,
|
* TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE,
|
||||||
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_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']
|
* :['A4988', 'A5984', 'DRV8825', 'LV8729', '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 X_DRIVER_TYPE A4988
|
||||||
#define Y_DRIVER_TYPE A4988
|
#define Y_DRIVER_TYPE A4988
|
||||||
@@ -249,6 +242,8 @@
|
|||||||
//#define SINGLENOZZLE_STANDBY_FAN
|
//#define SINGLENOZZLE_STANDBY_FAN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @section multi-material
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Multi-Material Unit
|
* Multi-Material Unit
|
||||||
* Set to one of these predefined models:
|
* Set to one of these predefined models:
|
||||||
@@ -261,6 +256,7 @@
|
|||||||
*
|
*
|
||||||
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
|
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
|
||||||
* See additional options in Configuration_adv.h.
|
* See additional options in Configuration_adv.h.
|
||||||
|
* :["PRUSA_MMU1", "PRUSA_MMU2", "PRUSA_MMU2S", "EXTENDABLE_EMU_MMU2", "EXTENDABLE_EMU_MMU2S"]
|
||||||
*/
|
*/
|
||||||
//#define MMU_MODEL PRUSA_MMU2
|
//#define MMU_MODEL PRUSA_MMU2
|
||||||
|
|
||||||
@@ -280,6 +276,7 @@
|
|||||||
#define SWITCHING_NOZZLE_SERVO_NR 0
|
#define SWITCHING_NOZZLE_SERVO_NR 0
|
||||||
//#define SWITCHING_NOZZLE_E1_SERVO_NR 1 // If two servos are used, the index of the second
|
//#define SWITCHING_NOZZLE_E1_SERVO_NR 1 // If two servos are used, the index of the second
|
||||||
#define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 (single servo) or lowered/raised (dual servo)
|
#define SWITCHING_NOZZLE_SERVO_ANGLES { 0, 90 } // Angles for E0, E1 (single servo) or lowered/raised (dual servo)
|
||||||
|
#define SWITCHING_NOZZLE_SERVO_DWELL 2500 // Dwell time to wait for servo to make physical move
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,7 +393,7 @@
|
|||||||
//#define HOTEND_OFFSET_Y { 0.0, 5.00 } // (mm) relative Y-offset for each nozzle
|
//#define HOTEND_OFFSET_Y { 0.0, 5.00 } // (mm) relative Y-offset for each nozzle
|
||||||
//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle
|
//#define HOTEND_OFFSET_Z { 0.0, 0.00 } // (mm) relative Z-offset for each nozzle
|
||||||
|
|
||||||
// @section machine
|
// @section psu control
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Power Supply Control
|
* Power Supply Control
|
||||||
@@ -499,7 +496,7 @@
|
|||||||
* 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950
|
* 30 : 100kΩ Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K - beta 3950
|
||||||
* 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950
|
* 60 : 100kΩ Maker's Tool Works Kapton Bed Thermistor - beta 3950
|
||||||
* 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
|
* 61 : 100kΩ Formbot/Vivedino 350°C Thermistor - beta 3950
|
||||||
* 66 : 4.7MΩ Dyze Design High Temperature Thermistor
|
* 66 : 4.7MΩ Dyze Design / Trianglelab T-D500 500°C High Temperature Thermistor
|
||||||
* 67 : 500kΩ SliceEngineering 450°C Thermistor
|
* 67 : 500kΩ SliceEngineering 450°C Thermistor
|
||||||
* 68 : PT100 amplifier board from Dyze Design
|
* 68 : PT100 amplifier board from Dyze Design
|
||||||
* 70 : 100kΩ bq Hephestos 2
|
* 70 : 100kΩ bq Hephestos 2
|
||||||
@@ -521,6 +518,7 @@
|
|||||||
* 110 : Pt100 with 1kΩ pullup (atypical)
|
* 110 : Pt100 with 1kΩ pullup (atypical)
|
||||||
* 147 : Pt100 with 4.7kΩ pullup
|
* 147 : Pt100 with 4.7kΩ pullup
|
||||||
* 1010 : Pt1000 with 1kΩ pullup (atypical)
|
* 1010 : Pt1000 with 1kΩ pullup (atypical)
|
||||||
|
* 1022 : Pt1000 with 2.2kΩ pullup
|
||||||
* 1047 : Pt1000 with 4.7kΩ pullup (E3D)
|
* 1047 : Pt1000 with 4.7kΩ pullup (E3D)
|
||||||
* 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
|
* 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
|
||||||
* NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
|
* NOTE: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
|
||||||
@@ -558,22 +556,32 @@
|
|||||||
#define DUMMY_THERMISTOR_999_VALUE 100
|
#define DUMMY_THERMISTOR_999_VALUE 100
|
||||||
|
|
||||||
// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1
|
// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1
|
||||||
//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
|
#if TEMP_SENSOR_IS_MAX_TC(0)
|
||||||
//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000
|
#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
|
||||||
//#define MAX31865_SENSOR_OHMS_1 100
|
#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for Adafruit PT100; 4300 for Adafruit PT1000
|
||||||
//#define MAX31865_CALIBRATION_OHMS_1 430
|
#endif
|
||||||
|
#if TEMP_SENSOR_IS_MAX_TC(1)
|
||||||
|
#define MAX31865_SENSOR_OHMS_1 100
|
||||||
|
#define MAX31865_CALIBRATION_OHMS_1 430
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
|
#if HAS_E_TEMP_SENSOR
|
||||||
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
|
||||||
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||||
|
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
|
#if TEMP_SENSOR_BED
|
||||||
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
|
||||||
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||||
|
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||||
|
#endif
|
||||||
|
|
||||||
#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
|
#if TEMP_SENSOR_CHAMBER
|
||||||
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
|
||||||
#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
|
||||||
|
#define TEMP_CHAMBER_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT)
|
* Redundant Temperature Sensor (TEMP_SENSOR_REDUNDANT)
|
||||||
@@ -632,6 +640,8 @@
|
|||||||
//============================= PID Settings ================================
|
//============================= PID Settings ================================
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
|
// @section hotend temp
|
||||||
|
|
||||||
// Enable PIDTEMP for PID control or MPCTEMP for Predictive Model.
|
// Enable PIDTEMP for PID control or MPCTEMP for Predictive Model.
|
||||||
// temperature control. Disable both for bang-bang heating.
|
// temperature control. Disable both for bang-bang heating.
|
||||||
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
|
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
|
||||||
@@ -642,8 +652,9 @@
|
|||||||
#define PID_K1 0.95 // Smoothing factor within any PID loop
|
#define PID_K1 0.95 // Smoothing factor within any PID loop
|
||||||
|
|
||||||
#if ENABLED(PIDTEMP)
|
#if ENABLED(PIDTEMP)
|
||||||
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
|
//#define PID_DEBUG // Print PID debug data to the serial port. Use 'M303 D' to toggle activation.
|
||||||
// Set/get with gcode: M301 E[extruder number, 0-2]
|
//#define PID_PARAMS_PER_HOTEND // Use separate PID parameters for each extruder (useful for mismatched extruders)
|
||||||
|
// Set/get with G-code: M301 E[extruder number, 0-2]
|
||||||
|
|
||||||
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
#if ENABLED(PID_PARAMS_PER_HOTEND)
|
||||||
// Specify up to one value per hotend here, according to your setup.
|
// Specify up to one value per hotend here, according to your setup.
|
||||||
@@ -663,7 +674,8 @@
|
|||||||
*
|
*
|
||||||
* Use a physical model of the hotend to control temperature. When configured correctly
|
* 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
|
* 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.
|
* for PID_EXTRUSION_SCALING and PID_FAN_SCALING. Use M306 T to autotune the model.
|
||||||
|
* @section mpctemp
|
||||||
*/
|
*/
|
||||||
#if ENABLED(MPCTEMP)
|
#if ENABLED(MPCTEMP)
|
||||||
//#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash)
|
//#define MPC_EDIT_MENU // Add MPC editing to the "Advanced Settings" menu. (~1300 bytes of flash)
|
||||||
@@ -716,6 +728,7 @@
|
|||||||
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W
|
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 250W
|
||||||
* heater. If your configuration is significantly different than this and you don't understand
|
* heater. If your configuration is significantly different than this and you don't understand
|
||||||
* the issues involved, don't use bed PID until someone else verifies that your hardware works.
|
* the issues involved, don't use bed PID until someone else verifies that your hardware works.
|
||||||
|
* @section bed temp
|
||||||
*/
|
*/
|
||||||
//#define PIDTEMPBED
|
//#define PIDTEMPBED
|
||||||
|
|
||||||
@@ -731,7 +744,7 @@
|
|||||||
|
|
||||||
#if ENABLED(PIDTEMPBED)
|
#if ENABLED(PIDTEMPBED)
|
||||||
//#define MIN_BED_POWER 0
|
//#define MIN_BED_POWER 0
|
||||||
//#define PID_BED_DEBUG // Sends debug data to the serial port.
|
//#define PID_BED_DEBUG // Print Bed PID debug data to the serial port.
|
||||||
|
|
||||||
// 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
|
// 120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
|
||||||
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
|
// from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
|
||||||
@@ -759,6 +772,7 @@
|
|||||||
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W
|
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W
|
||||||
* heater. If your configuration is significantly different than this and you don't understand
|
* heater. If your configuration is significantly different than this and you don't understand
|
||||||
* the issues involved, don't use chamber PID until someone else verifies that your hardware works.
|
* the issues involved, don't use chamber PID until someone else verifies that your hardware works.
|
||||||
|
* @section chamber temp
|
||||||
*/
|
*/
|
||||||
//#define PIDTEMPCHAMBER
|
//#define PIDTEMPCHAMBER
|
||||||
//#define CHAMBER_LIMIT_SWITCHING
|
//#define CHAMBER_LIMIT_SWITCHING
|
||||||
@@ -773,7 +787,7 @@
|
|||||||
|
|
||||||
#if ENABLED(PIDTEMPCHAMBER)
|
#if ENABLED(PIDTEMPCHAMBER)
|
||||||
#define MIN_CHAMBER_POWER 0
|
#define MIN_CHAMBER_POWER 0
|
||||||
//#define PID_CHAMBER_DEBUG // Sends debug data to the serial port.
|
//#define PID_CHAMBER_DEBUG // Print Chamber PID debug data to the serial port.
|
||||||
|
|
||||||
// Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
|
// Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
|
||||||
// and placed inside the small Creality printer enclosure tent.
|
// and placed inside the small Creality printer enclosure tent.
|
||||||
@@ -787,7 +801,6 @@
|
|||||||
#endif // PIDTEMPCHAMBER
|
#endif // PIDTEMPCHAMBER
|
||||||
|
|
||||||
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
|
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
|
||||||
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
|
|
||||||
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
|
||||||
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
|
//#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
|
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
||||||
@@ -797,7 +810,7 @@
|
|||||||
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
|
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// @section extruder
|
// @section safety
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prevent extrusion if the temperature is below EXTRUDE_MINTEMP.
|
* Prevent extrusion if the temperature is below EXTRUDE_MINTEMP.
|
||||||
@@ -865,11 +878,154 @@
|
|||||||
#define POLAR_SEGMENTS_PER_SECOND 5
|
#define POLAR_SEGMENTS_PER_SECOND 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @section delta
|
||||||
|
|
||||||
|
// Enable for DELTA kinematics and configure below
|
||||||
|
//#define DELTA
|
||||||
|
#if ENABLED(DELTA)
|
||||||
|
|
||||||
|
// Make delta curves from many straight lines (linear interpolation).
|
||||||
|
// This is a trade-off between visible corners (not enough segments)
|
||||||
|
// and processor overload (too many expensive sqrt calls).
|
||||||
|
#define DELTA_SEGMENTS_PER_SECOND 200
|
||||||
|
|
||||||
|
// After homing move down to a height where XY movement is unconstrained
|
||||||
|
//#define DELTA_HOME_TO_SAFE_ZONE
|
||||||
|
|
||||||
|
// Delta calibration menu
|
||||||
|
// uncomment to add three points calibration menu option.
|
||||||
|
// See http://minow.blogspot.com/index.html#4918805519571907051
|
||||||
|
//#define DELTA_CALIBRATION_MENU
|
||||||
|
|
||||||
|
// uncomment to add G33 Delta Auto-Calibration (Enable EEPROM_SETTINGS to store results)
|
||||||
|
//#define DELTA_AUTO_CALIBRATION
|
||||||
|
|
||||||
|
// NOTE NB all values for DELTA_* values MUST be floating point, so always have a decimal point in them
|
||||||
|
|
||||||
|
#if ENABLED(DELTA_AUTO_CALIBRATION)
|
||||||
|
// set the default number of probe points : n*n (1 -> 7)
|
||||||
|
#define DELTA_CALIBRATION_DEFAULT_POINTS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if EITHER(DELTA_AUTO_CALIBRATION, DELTA_CALIBRATION_MENU)
|
||||||
|
// Set the steprate for papertest probing
|
||||||
|
#define PROBE_MANUALLY_STEP 0.05 // (mm)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Print surface diameter/2 minus unreachable space (avoid collisions with vertical towers).
|
||||||
|
#define DELTA_PRINTABLE_RADIUS 140.0 // (mm)
|
||||||
|
|
||||||
|
// Maximum reachable area
|
||||||
|
#define DELTA_MAX_RADIUS 140.0 // (mm)
|
||||||
|
|
||||||
|
// Center-to-center distance of the holes in the diagonal push rods.
|
||||||
|
#define DELTA_DIAGONAL_ROD 250.0 // (mm)
|
||||||
|
|
||||||
|
// Distance between bed and nozzle Z home position
|
||||||
|
#define DELTA_HEIGHT 250.00 // (mm) Get this value from G33 auto calibrate
|
||||||
|
|
||||||
|
#define DELTA_ENDSTOP_ADJ { 0.0, 0.0, 0.0 } // Get these values from G33 auto calibrate
|
||||||
|
|
||||||
|
// Horizontal distance bridged by diagonal push rods when effector is centered.
|
||||||
|
#define DELTA_RADIUS 124.0 // (mm) Get this value from G33 auto calibrate
|
||||||
|
|
||||||
|
// Trim adjustments for individual towers
|
||||||
|
// tower angle corrections for X and Y tower / rotate XYZ so Z tower angle = 0
|
||||||
|
// measured in degrees anticlockwise looking from above the printer
|
||||||
|
#define DELTA_TOWER_ANGLE_TRIM { 0.0, 0.0, 0.0 } // Get these values from G33 auto calibrate
|
||||||
|
|
||||||
|
// Delta radius and diagonal rod adjustments (mm)
|
||||||
|
//#define DELTA_RADIUS_TRIM_TOWER { 0.0, 0.0, 0.0 }
|
||||||
|
//#define DELTA_DIAGONAL_ROD_TRIM_TOWER { 0.0, 0.0, 0.0 }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// @section scara
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MORGAN_SCARA was developed by QHARLEY in South Africa in 2012-2013.
|
||||||
|
* Implemented and slightly reworked by JCERNY in June, 2014.
|
||||||
|
*
|
||||||
|
* Mostly Printed SCARA is an open source design by Tyler Williams. See:
|
||||||
|
* https://www.thingiverse.com/thing:2487048
|
||||||
|
* https://www.thingiverse.com/thing:1241491
|
||||||
|
*/
|
||||||
|
//#define MORGAN_SCARA
|
||||||
|
//#define MP_SCARA
|
||||||
|
#if EITHER(MORGAN_SCARA, MP_SCARA)
|
||||||
|
// If movement is choppy try lowering this value
|
||||||
|
#define SCARA_SEGMENTS_PER_SECOND 200
|
||||||
|
|
||||||
|
// Length of inner and outer support arms. Measure arm lengths precisely.
|
||||||
|
#define SCARA_LINKAGE_1 150 // (mm)
|
||||||
|
#define SCARA_LINKAGE_2 150 // (mm)
|
||||||
|
|
||||||
|
// SCARA tower offset (position of Tower relative to bed zero position)
|
||||||
|
// This needs to be reasonably accurate as it defines the printbed position in the SCARA space.
|
||||||
|
#define SCARA_OFFSET_X 100 // (mm)
|
||||||
|
#define SCARA_OFFSET_Y -56 // (mm)
|
||||||
|
|
||||||
|
#if ENABLED(MORGAN_SCARA)
|
||||||
|
|
||||||
|
//#define DEBUG_SCARA_KINEMATICS
|
||||||
|
#define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
|
||||||
|
|
||||||
|
// Radius around the center where the arm cannot reach
|
||||||
|
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
|
||||||
|
|
||||||
|
#define THETA_HOMING_OFFSET 0 // Calculated from Calibration Guide and M360 / M114. See http://reprap.harleystudio.co.za/?page_id=1073
|
||||||
|
#define PSI_HOMING_OFFSET 0 // Calculated from Calibration Guide and M364 / M114. See http://reprap.harleystudio.co.za/?page_id=1073
|
||||||
|
|
||||||
|
#elif ENABLED(MP_SCARA)
|
||||||
|
|
||||||
|
#define SCARA_OFFSET_THETA1 12 // degrees
|
||||||
|
#define SCARA_OFFSET_THETA2 131 // degrees
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// @section tpara
|
||||||
|
|
||||||
|
// Enable for TPARA kinematics and configure below
|
||||||
|
//#define AXEL_TPARA
|
||||||
|
#if ENABLED(AXEL_TPARA)
|
||||||
|
#define DEBUG_ROBOT_KINEMATICS
|
||||||
|
#define ROBOT_SEGMENTS_PER_SECOND 200
|
||||||
|
|
||||||
|
// Length of inner and outer support arms. Measure arm lengths precisely.
|
||||||
|
#define ROBOT_LINKAGE_1 120 // (mm)
|
||||||
|
#define ROBOT_LINKAGE_2 120 // (mm)
|
||||||
|
|
||||||
|
// SCARA tower offset (position of Tower relative to bed zero position)
|
||||||
|
// This needs to be reasonably accurate as it defines the printbed position in the SCARA space.
|
||||||
|
#define ROBOT_OFFSET_X 0 // (mm)
|
||||||
|
#define ROBOT_OFFSET_Y 0 // (mm)
|
||||||
|
#define ROBOT_OFFSET_Z 0 // (mm)
|
||||||
|
|
||||||
|
#define SCARA_FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
|
||||||
|
|
||||||
|
// Radius around the center where the arm cannot reach
|
||||||
|
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
|
||||||
|
|
||||||
|
// Calculated from Calibration Guide and M360 / M114. See http://reprap.harleystudio.co.za/?page_id=1073
|
||||||
|
#define THETA_HOMING_OFFSET 0
|
||||||
|
#define PSI_HOMING_OFFSET 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// @section machine
|
||||||
|
|
||||||
|
// Articulated robot (arm). Joints are directly mapped to axes with no kinematics.
|
||||||
|
//#define ARTICULATED_ROBOT_ARM
|
||||||
|
|
||||||
|
// For a hot wire cutter with parallel horizontal axes (X, I) where the heights of the two wire
|
||||||
|
// ends are controlled by parallel axes (Y, J). Joints are directly mapped to axes (no kinematics).
|
||||||
|
//#define FOAMCUTTER_XYUV
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
//============================== Endstop Settings ===========================
|
//============================== Endstop Settings ===========================
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
// @section homing
|
// @section endstops
|
||||||
|
|
||||||
// Specify here all the endstop connectors that are connected to any endstop or probe.
|
// Specify here all the endstop connectors that are connected to any endstop or probe.
|
||||||
// Almost all printers will be using one per axis. Probes will use one or more of the
|
// Almost all printers will be using one per axis. Probes will use one or more of the
|
||||||
@@ -1217,6 +1373,27 @@
|
|||||||
#define Z_PROBE_RETRACT_X X_MAX_POS
|
#define Z_PROBE_RETRACT_X X_MAX_POS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Magnetically Mounted Probe
|
||||||
|
* For probes such as Euclid, Klicky, Klackender, etc.
|
||||||
|
*/
|
||||||
|
//#define MAG_MOUNTED_PROBE
|
||||||
|
#if ENABLED(MAG_MOUNTED_PROBE)
|
||||||
|
#define PROBE_DEPLOY_FEEDRATE (133*60) // (mm/min) Probe deploy speed
|
||||||
|
#define PROBE_STOW_FEEDRATE (133*60) // (mm/min) Probe stow speed
|
||||||
|
|
||||||
|
#define MAG_MOUNTED_DEPLOY_1 { PROBE_DEPLOY_FEEDRATE, { 245, 114, 30 } } // Move to side Dock & Attach probe
|
||||||
|
#define MAG_MOUNTED_DEPLOY_2 { PROBE_DEPLOY_FEEDRATE, { 210, 114, 30 } } // Move probe off dock
|
||||||
|
#define MAG_MOUNTED_DEPLOY_3 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
|
||||||
|
#define MAG_MOUNTED_DEPLOY_4 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
|
||||||
|
#define MAG_MOUNTED_DEPLOY_5 { PROBE_DEPLOY_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
|
||||||
|
#define MAG_MOUNTED_STOW_1 { PROBE_STOW_FEEDRATE, { 245, 114, 20 } } // Move to dock
|
||||||
|
#define MAG_MOUNTED_STOW_2 { PROBE_STOW_FEEDRATE, { 245, 114, 0 } } // Place probe beside remover
|
||||||
|
#define MAG_MOUNTED_STOW_3 { PROBE_STOW_FEEDRATE, { 230, 114, 0 } } // Side move to remove probe
|
||||||
|
#define MAG_MOUNTED_STOW_4 { PROBE_STOW_FEEDRATE, { 210, 114, 20 } } // Side move to remove probe
|
||||||
|
#define MAG_MOUNTED_STOW_5 { PROBE_STOW_FEEDRATE, { 0, 0, 0 } } // Extra move if needed
|
||||||
|
#endif
|
||||||
|
|
||||||
// Duet Smart Effector (for delta printers) - https://bit.ly/2ul5U7J
|
// Duet Smart Effector (for delta printers) - https://bit.ly/2ul5U7J
|
||||||
// When the pin is defined you can use M672 to set/reset the probe sensitivity.
|
// When the pin is defined you can use M672 to set/reset the probe sensitivity.
|
||||||
//#define DUET_SMART_EFFECTOR
|
//#define DUET_SMART_EFFECTOR
|
||||||
@@ -1232,9 +1409,37 @@
|
|||||||
*/
|
*/
|
||||||
//#define SENSORLESS_PROBING
|
//#define SENSORLESS_PROBING
|
||||||
|
|
||||||
//
|
/**
|
||||||
// For Z_PROBE_ALLEN_KEY see the Delta example configurations.
|
* Allen key retractable z-probe as seen on many Kossel delta printers - https://reprap.org/wiki/Kossel#Automatic_bed_leveling_probe
|
||||||
//
|
* Deploys by touching z-axis belt. Retracts by pushing the probe down.
|
||||||
|
*/
|
||||||
|
//#define Z_PROBE_ALLEN_KEY
|
||||||
|
#if ENABLED(Z_PROBE_ALLEN_KEY)
|
||||||
|
// 2 or 3 sets of coordinates for deploying and retracting the spring loaded touch probe on G29,
|
||||||
|
// if servo actuated touch probe is not defined. Uncomment as appropriate for your printer/probe.
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_DEPLOY_1 { 30.0, DELTA_PRINTABLE_RADIUS, 100.0 }
|
||||||
|
#define Z_PROBE_ALLEN_KEY_DEPLOY_1_FEEDRATE XY_PROBE_FEEDRATE
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_DEPLOY_2 { 0.0, DELTA_PRINTABLE_RADIUS, 100.0 }
|
||||||
|
#define Z_PROBE_ALLEN_KEY_DEPLOY_2_FEEDRATE (XY_PROBE_FEEDRATE)/10
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_DEPLOY_3 { 0.0, (DELTA_PRINTABLE_RADIUS) * 0.75, 100.0 }
|
||||||
|
#define Z_PROBE_ALLEN_KEY_DEPLOY_3_FEEDRATE XY_PROBE_FEEDRATE
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_1 { -64.0, 56.0, 23.0 } // Move the probe into position
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_1_FEEDRATE XY_PROBE_FEEDRATE
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_2 { -64.0, 56.0, 3.0 } // Push it down
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_2_FEEDRATE (XY_PROBE_FEEDRATE)/10
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_3 { -64.0, 56.0, 50.0 } // Move it up to clear
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_3_FEEDRATE XY_PROBE_FEEDRATE
|
||||||
|
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_4 { 0.0, 0.0, 50.0 }
|
||||||
|
#define Z_PROBE_ALLEN_KEY_STOW_4_FEEDRATE XY_PROBE_FEEDRATE
|
||||||
|
|
||||||
|
#endif // Z_PROBE_ALLEN_KEY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nozzle-to-Probe offsets { X, Y, Z }
|
* Nozzle-to-Probe offsets { X, Y, Z }
|
||||||
@@ -1430,7 +1635,7 @@
|
|||||||
#define DISABLE_E false // Disable the extruder when not stepping
|
#define DISABLE_E false // Disable the extruder when not stepping
|
||||||
#define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled
|
#define DISABLE_INACTIVE_EXTRUDER // Keep only the active extruder enabled
|
||||||
|
|
||||||
// @section machine
|
// @section motion
|
||||||
|
|
||||||
// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
|
// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
|
||||||
#define INVERT_X_DIR false
|
#define INVERT_X_DIR false
|
||||||
@@ -1484,7 +1689,7 @@
|
|||||||
//#define V_HOME_DIR -1
|
//#define V_HOME_DIR -1
|
||||||
//#define W_HOME_DIR -1
|
//#define W_HOME_DIR -1
|
||||||
|
|
||||||
// @section machine
|
// @section geometry
|
||||||
|
|
||||||
// The size of the printable area
|
// The size of the printable area
|
||||||
#define X_BED_SIZE 200
|
#define X_BED_SIZE 200
|
||||||
@@ -1687,6 +1892,15 @@
|
|||||||
#define LEVELING_BED_TEMP 50
|
#define LEVELING_BED_TEMP 50
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bed Distance Sensor
|
||||||
|
*
|
||||||
|
* Measures the distance from bed to nozzle with accuracy of 0.01mm.
|
||||||
|
* For information about this sensor https://github.com/markniu/Bed_Distance_sensor
|
||||||
|
* Uses I2C port, so it requires I2C library markyue/Panda_SoftMasterI2C.
|
||||||
|
*/
|
||||||
|
//#define BD_SENSOR
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable detailed logging of G28, G29, M48, etc.
|
* Enable detailed logging of G28, G29, M48, etc.
|
||||||
* Turn on with the command 'M111 S32'.
|
* Turn on with the command 'M111 S32'.
|
||||||
@@ -1806,18 +2020,18 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Add a menu item to move between bed corners for manual bed adjustment
|
// 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)
|
#if ENABLED(LCD_BED_TRAMMING)
|
||||||
#define LEVEL_CORNERS_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
|
#define BED_TRAMMING_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 BED_TRAMMING_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 BED_TRAMMING_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 BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
|
||||||
//#define LEVEL_CORNERS_USE_PROBE
|
//#define BED_TRAMMING_USE_PROBE
|
||||||
#if ENABLED(LEVEL_CORNERS_USE_PROBE)
|
#if ENABLED(BED_TRAMMING_USE_PROBE)
|
||||||
#define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
|
#define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm)
|
||||||
#define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
|
#define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
|
||||||
//#define LEVEL_CORNERS_AUDIO_FEEDBACK
|
//#define BED_TRAMMING_AUDIO_FEEDBACK
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1837,7 +2051,7 @@
|
|||||||
* | 1 2 | | 1 4 | | 1 2 | | 2 |
|
* | 1 2 | | 1 4 | | 1 2 | | 2 |
|
||||||
* LF --------- RF LF --------- RF LF --------- RF LF --------- RF
|
* 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
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1921,9 +2135,8 @@
|
|||||||
#define XY_DIAG_BD 282.8427124746
|
#define XY_DIAG_BD 282.8427124746
|
||||||
#define XY_SIDE_AD 200
|
#define XY_SIDE_AD 200
|
||||||
|
|
||||||
// Or, set the default skew factors directly here
|
// Or, set the XY skew factor directly:
|
||||||
// to override the above measurements:
|
//#define XY_SKEW_FACTOR 0.0
|
||||||
#define XY_SKEW_FACTOR 0.0
|
|
||||||
|
|
||||||
//#define SKEW_CORRECTION_FOR_Z
|
//#define SKEW_CORRECTION_FOR_Z
|
||||||
#if ENABLED(SKEW_CORRECTION_FOR_Z)
|
#if ENABLED(SKEW_CORRECTION_FOR_Z)
|
||||||
@@ -1932,8 +2145,10 @@
|
|||||||
#define YZ_DIAG_AC 282.8427124746
|
#define YZ_DIAG_AC 282.8427124746
|
||||||
#define YZ_DIAG_BD 282.8427124746
|
#define YZ_DIAG_BD 282.8427124746
|
||||||
#define YZ_SIDE_AD 200
|
#define YZ_SIDE_AD 200
|
||||||
#define XZ_SKEW_FACTOR 0.0
|
|
||||||
#define YZ_SKEW_FACTOR 0.0
|
// Or, set the Z skew factors directly:
|
||||||
|
//#define XZ_SKEW_FACTOR 0.0
|
||||||
|
//#define YZ_SKEW_FACTOR 0.0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Enable this option for M852 to set skew at runtime
|
// Enable this option for M852 to set skew at runtime
|
||||||
@@ -1944,7 +2159,7 @@
|
|||||||
//============================= Additional Features ===========================
|
//============================= Additional Features ===========================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// @section extras
|
// @section eeprom
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EEPROM
|
* EEPROM
|
||||||
@@ -1964,6 +2179,8 @@
|
|||||||
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
|
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @section host
|
||||||
|
|
||||||
//
|
//
|
||||||
// Host Keepalive
|
// Host Keepalive
|
||||||
//
|
//
|
||||||
@@ -1974,6 +2191,8 @@
|
|||||||
#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113.
|
#define DEFAULT_KEEPALIVE_INTERVAL 2 // Number of seconds between "busy" messages. Set with M113.
|
||||||
#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating
|
#define BUSY_WHILE_HEATING // Some hosts require "busy" messages even during heating
|
||||||
|
|
||||||
|
// @section units
|
||||||
|
|
||||||
//
|
//
|
||||||
// G20/G21 Inch mode support
|
// G20/G21 Inch mode support
|
||||||
//
|
//
|
||||||
@@ -1987,7 +2206,7 @@
|
|||||||
// @section temperature
|
// @section temperature
|
||||||
|
|
||||||
//
|
//
|
||||||
// Preheat Constants - Up to 6 are supported without changes
|
// Preheat Constants - Up to 10 are supported without changes
|
||||||
//
|
//
|
||||||
#define PREHEAT_1_LABEL "PLA"
|
#define PREHEAT_1_LABEL "PLA"
|
||||||
#define PREHEAT_1_TEMP_HOTEND 180
|
#define PREHEAT_1_TEMP_HOTEND 180
|
||||||
@@ -2001,6 +2220,8 @@
|
|||||||
#define PREHEAT_2_TEMP_CHAMBER 35
|
#define PREHEAT_2_TEMP_CHAMBER 35
|
||||||
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
|
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
|
||||||
|
|
||||||
|
// @section motion
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nozzle Park
|
* Nozzle Park
|
||||||
*
|
*
|
||||||
@@ -2099,6 +2320,8 @@
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @section host
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print Job Timer
|
* Print Job Timer
|
||||||
*
|
*
|
||||||
@@ -2125,6 +2348,8 @@
|
|||||||
*/
|
*/
|
||||||
#define PRINTJOB_TIMER_AUTOSTART
|
#define PRINTJOB_TIMER_AUTOSTART
|
||||||
|
|
||||||
|
// @section stats
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Print Counter
|
* Print Counter
|
||||||
*
|
*
|
||||||
@@ -2139,9 +2364,11 @@
|
|||||||
*/
|
*/
|
||||||
//#define PRINTCOUNTER
|
//#define PRINTCOUNTER
|
||||||
#if ENABLED(PRINTCOUNTER)
|
#if ENABLED(PRINTCOUNTER)
|
||||||
#define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print
|
#define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print. A value of 0 will save stats at end of print.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @section security
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Password
|
* Password
|
||||||
*
|
*
|
||||||
@@ -2177,7 +2404,7 @@
|
|||||||
//============================= LCD and SD support ============================
|
//============================= LCD and SD support ============================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// @section lcd
|
// @section interface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* LCD LANGUAGE
|
* LCD LANGUAGE
|
||||||
@@ -2293,6 +2520,16 @@
|
|||||||
//
|
//
|
||||||
//#define REVERSE_SELECT_DIRECTION
|
//#define REVERSE_SELECT_DIRECTION
|
||||||
|
|
||||||
|
//
|
||||||
|
// Encoder EMI Noise Filter
|
||||||
|
//
|
||||||
|
// This option increases encoder samples to filter out phantom encoder clicks caused by EMI noise.
|
||||||
|
//
|
||||||
|
//#define ENCODER_NOISE_FILTER
|
||||||
|
#if ENABLED(ENCODER_NOISE_FILTER)
|
||||||
|
#define ENCODER_SAMPLES 10
|
||||||
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
// Individual Axis Homing
|
// Individual Axis Homing
|
||||||
//
|
//
|
||||||
@@ -2323,6 +2560,7 @@
|
|||||||
//======================== LCD / Controller Selection =========================
|
//======================== LCD / Controller Selection =========================
|
||||||
//======================== (Character-based LCDs) =========================
|
//======================== (Character-based LCDs) =========================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
// @section lcd
|
||||||
|
|
||||||
//
|
//
|
||||||
// RepRapDiscount Smart Controller.
|
// RepRapDiscount Smart Controller.
|
||||||
@@ -2624,6 +2862,12 @@
|
|||||||
//
|
//
|
||||||
//#define SILVER_GATE_GLCD_CONTROLLER
|
//#define SILVER_GATE_GLCD_CONTROLLER
|
||||||
|
|
||||||
|
//
|
||||||
|
// eMotion Tech LCD with SD
|
||||||
|
// https://www.reprap-france.com/produit/1234568748-ecran-graphique-128-x-64-points-2-1
|
||||||
|
//
|
||||||
|
//#define EMOTION_TECH_LCD
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
//============================== OLED Displays ==============================
|
//============================== OLED Displays ==============================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
@@ -2746,6 +2990,7 @@
|
|||||||
//#define ANYCUBIC_LCD_CHIRON
|
//#define ANYCUBIC_LCD_CHIRON
|
||||||
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
|
#if EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
|
||||||
//#define ANYCUBIC_LCD_DEBUG
|
//#define ANYCUBIC_LCD_DEBUG
|
||||||
|
//#define ANYCUBIC_LCD_GCODE_EXT // Add ".gcode" to menu entries for DGUS clone compatibility
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -2913,10 +3158,11 @@
|
|||||||
//
|
//
|
||||||
//#define TOUCH_SCREEN
|
//#define TOUCH_SCREEN
|
||||||
#if ENABLED(TOUCH_SCREEN)
|
#if ENABLED(TOUCH_SCREEN)
|
||||||
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
|
#define BUTTON_DELAY_EDIT 50 // (ms) Button repeat delay for edit screens
|
||||||
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
|
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
|
||||||
|
|
||||||
//#define TOUCH_IDLE_SLEEP 300 // (s) Turn off the TFT backlight if set (5mn)
|
//#define DISABLE_ENCODER // Disable the click encoder, if any
|
||||||
|
//#define TOUCH_IDLE_SLEEP_MINS 5 // (minutes) Display Sleep after a period of inactivity. Set with M255 S.
|
||||||
|
|
||||||
#define TOUCH_SCREEN_CALIBRATION
|
#define TOUCH_SCREEN_CALIBRATION
|
||||||
|
|
||||||
@@ -2951,7 +3197,7 @@
|
|||||||
//=============================== Extra Features ==============================
|
//=============================== Extra Features ==============================
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
||||||
// @section extras
|
// @section fans
|
||||||
|
|
||||||
// Set number of user-controlled fans. Disable to use all board-defined fans.
|
// Set number of user-controlled fans. Disable to use all board-defined fans.
|
||||||
// :[1,2,3,4,5,6,7,8]
|
// :[1,2,3,4,5,6,7,8]
|
||||||
@@ -2975,14 +3221,18 @@
|
|||||||
// duty cycle is attained.
|
// duty cycle is attained.
|
||||||
//#define SOFT_PWM_DITHER
|
//#define SOFT_PWM_DITHER
|
||||||
|
|
||||||
|
// @section extras
|
||||||
|
|
||||||
|
// Support for the BariCUDA Paste Extruder
|
||||||
|
//#define BARICUDA
|
||||||
|
|
||||||
|
// @section lights
|
||||||
|
|
||||||
// Temperature status LEDs that display the hotend and bed temperature.
|
// Temperature status LEDs that display the hotend and bed temperature.
|
||||||
// If all hotends, bed temperature, and target temperature are under 54C
|
// If all hotends, bed temperature, and target temperature are under 54C
|
||||||
// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis)
|
// then the BLUE led is on. Otherwise the RED led is on. (1C hysteresis)
|
||||||
//#define TEMP_STAT_LEDS
|
//#define TEMP_STAT_LEDS
|
||||||
|
|
||||||
// Support for the BariCUDA Paste Extruder
|
|
||||||
//#define BARICUDA
|
|
||||||
|
|
||||||
// Support for BlinkM/CyzRgb
|
// Support for BlinkM/CyzRgb
|
||||||
//#define BLINKM
|
//#define BLINKM
|
||||||
|
|
||||||
@@ -3003,16 +3253,19 @@
|
|||||||
* luminance values can be set from 0 to 255.
|
* luminance values can be set from 0 to 255.
|
||||||
* For NeoPixel LED an overall brightness parameter is also available.
|
* For NeoPixel LED an overall brightness parameter is also available.
|
||||||
*
|
*
|
||||||
* *** CAUTION ***
|
* === CAUTION ===
|
||||||
* LED Strips require a MOSFET Chip between PWM lines and LEDs,
|
* LED Strips require a MOSFET Chip between PWM lines and LEDs,
|
||||||
* as the Arduino cannot handle the current the LEDs will require.
|
* as the Arduino cannot handle the current the LEDs will require.
|
||||||
* Failure to follow this precaution can destroy your Arduino!
|
* Failure to follow this precaution can destroy your Arduino!
|
||||||
|
*
|
||||||
* NOTE: A separate 5V power supply is required! The NeoPixel LED needs
|
* NOTE: A separate 5V power supply is required! The NeoPixel LED needs
|
||||||
* more current than the Arduino 5V linear regulator can produce.
|
* more current than the Arduino 5V linear regulator can produce.
|
||||||
* *** CAUTION ***
|
|
||||||
*
|
*
|
||||||
* LED Type. Enable only one of the following two options.
|
* Requires PWM frequency between 50 <> 100Hz (Check HAL or variant)
|
||||||
|
* Use FAST_PWM_FAN, if possible, to reduce fan noise.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// LED Type. Enable only one of the following two options:
|
||||||
//#define RGB_LED
|
//#define RGB_LED
|
||||||
//#define RGBW_LED
|
//#define RGBW_LED
|
||||||
|
|
||||||
@@ -3021,6 +3274,10 @@
|
|||||||
//#define RGB_LED_G_PIN 43
|
//#define RGB_LED_G_PIN 43
|
||||||
//#define RGB_LED_B_PIN 35
|
//#define RGB_LED_B_PIN 35
|
||||||
//#define RGB_LED_W_PIN -1
|
//#define RGB_LED_W_PIN -1
|
||||||
|
//#define RGB_STARTUP_TEST // For PWM pins, fade between all colors
|
||||||
|
#if ENABLED(RGB_STARTUP_TEST)
|
||||||
|
#define RGB_STARTUP_TEST_INNER_MS 10 // (ms) Reduce or increase fading speed
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Support for Adafruit NeoPixel LED driver
|
// Support for Adafruit NeoPixel LED driver
|
||||||
@@ -3068,6 +3325,8 @@
|
|||||||
#define PRINTER_EVENT_LEDS
|
#define PRINTER_EVENT_LEDS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// @section servos
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of servos
|
* Number of servos
|
||||||
*
|
*
|
||||||
|
|||||||
+280
-434
File diff suppressed because it is too large
Load Diff
+6
-119
@@ -109,7 +109,7 @@ LIQUID_TWI2 ?= 0
|
|||||||
# This defines if Wire is needed
|
# This defines if Wire is needed
|
||||||
WIRE ?= 0
|
WIRE ?= 0
|
||||||
|
|
||||||
# This defines if Tone is needed (i.e SPEAKER is defined in Configuration.h)
|
# This defines if Tone is needed (i.e., SPEAKER is defined in Configuration.h)
|
||||||
# Disabling this (and SPEAKER) saves approximately 350 bytes of memory.
|
# Disabling this (and SPEAKER) saves approximately 350 bytes of memory.
|
||||||
TONE ?= 1
|
TONE ?= 1
|
||||||
|
|
||||||
@@ -317,123 +317,10 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1159)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1160)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1160)
|
||||||
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
|
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1161)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1161)
|
||||||
|
# Zonestar zrib V5.3 (Chinese RAMPS replica)
|
||||||
|
else ifeq ($(HARDWARE_MOTHERBOARD),1162)
|
||||||
# 3Drag Controller
|
# Pxmalion Core I3
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1100)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1163)
|
||||||
# Velleman K8200 Controller (derived from 3Drag Controller)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1101)
|
|
||||||
# Velleman K8400 Controller (derived from 3Drag Controller)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1102)
|
|
||||||
# Velleman K8600 Controller (Vertex Nano)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1103)
|
|
||||||
# Velleman K8800 Controller (Vertex Delta)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1104)
|
|
||||||
# 2PrintBeta BAM&DICE with STK drivers
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1105)
|
|
||||||
# 2PrintBeta BAM&DICE Due with STK drivers
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
|
|
||||||
# MKS BASE v1.0
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
|
|
||||||
# MKS v1.4 with A4982 stepper drivers
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
|
|
||||||
# MKS v1.5 with Allegro A4982 stepper drivers
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
|
|
||||||
# MKS v1.6 with Allegro A4982 stepper drivers
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
|
|
||||||
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
|
|
||||||
# MKS GEN v1.3 or 1.4
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
|
|
||||||
# MKS GEN L
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
|
|
||||||
# zrib V2.0 control board (Chinese RAMPS replica)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
|
|
||||||
# BigTreeTech or BIQU KFB2.0
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
|
|
||||||
# Felix 2.0+ Electronics Board (RAMPS like)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
|
|
||||||
# Invent-A-Part RigidBoard
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
|
|
||||||
# Invent-A-Part RigidBoard V2
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
|
|
||||||
# Sainsmart 2-in-1 board
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
|
|
||||||
# Ultimaker
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
|
|
||||||
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
|
|
||||||
MCU ?= atmega1280
|
|
||||||
PROG_MCU ?= m1280
|
|
||||||
|
|
||||||
# Azteeg X3
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
|
|
||||||
# Azteeg X3 Pro
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
|
|
||||||
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
|
|
||||||
# Rumba
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
|
|
||||||
# Raise3D Rumba
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
|
|
||||||
# Rapide Lite RL200 Rumba
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
|
|
||||||
# Formbot T-Rex 2 Plus
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
|
|
||||||
# Formbot T-Rex 3
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
|
|
||||||
# Formbot Raptor
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
|
|
||||||
# Formbot Raptor 2
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
|
|
||||||
# bq ZUM Mega 3D
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
|
|
||||||
# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
|
|
||||||
# TriGorilla Anycubic version 1.3 based on RAMPS EFB
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
|
|
||||||
# TriGorilla Anycubic version 1.4 based on RAMPS EFB
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
|
|
||||||
# TriGorilla Anycubic version 1.4 Rev 1.1
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
|
|
||||||
# Creality: Ender-4, CR-8
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
|
|
||||||
# Creality: CR10S, CR20, CR-X
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
|
|
||||||
# Dagoma F5
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
|
|
||||||
# FYSETC F6 1.3
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
|
|
||||||
# FYSETC F6 1.5
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
|
|
||||||
# Duplicator i3 Plus
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
|
|
||||||
# VORON
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
|
|
||||||
# TRONXY V3 1.0
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
|
|
||||||
# Z-Bolt X Series
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
|
|
||||||
# TT OSCAR
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
|
|
||||||
# Overlord/Overlord Pro
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
|
|
||||||
# ADIMLab Gantry v1
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
|
|
||||||
# ADIMLab Gantry v2
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
|
|
||||||
# BIQU Tango V1
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
|
|
||||||
# MKS GEN L V2
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
|
|
||||||
# MKS GEN L V2.1
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
|
|
||||||
# Copymaster 3D
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
|
|
||||||
# Ortur 4
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
|
|
||||||
# Tenlog D3 Hero
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# RAMBo and derivatives
|
# RAMBo and derivatives
|
||||||
@@ -512,7 +399,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1324)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
|
||||||
# Intamsys 4.0 (Funmat HT)
|
# Intamsys 4.0 (Funmat HT)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
|
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)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
|
||||||
# Geeetech GT2560 Rev B for A20(M/T/D)
|
# Geeetech GT2560 Rev B for A20(M/T/D)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@
|
|||||||
/**
|
/**
|
||||||
* Marlin release version identifier
|
* Marlin release version identifier
|
||||||
*/
|
*/
|
||||||
//#define SHORT_BUILD_VERSION "bugfix-2.0.x"
|
//#define SHORT_BUILD_VERSION "bugfix-2.1.x"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verbose version identifier which should contain a reference to the location
|
* 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
|
* here we define this default string as the date where the latest release
|
||||||
* version was tagged.
|
* version was tagged.
|
||||||
*/
|
*/
|
||||||
//#define STRING_DISTRIBUTION_DATE "2022-05-29"
|
//#define STRING_DISTRIBUTION_DATE "2022-10-12"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||||
|
|||||||
@@ -0,0 +1,211 @@
|
|||||||
|
#
|
||||||
|
# Marlin Firmware
|
||||||
|
# config.ini - Options to apply before the build
|
||||||
|
#
|
||||||
|
[config:base]
|
||||||
|
ini_use_config = none
|
||||||
|
|
||||||
|
# Load all config: sections in this file
|
||||||
|
;ini_use_config = all
|
||||||
|
# Load config file relative to Marlin/
|
||||||
|
;ini_use_config = another.ini
|
||||||
|
# Download configurations from GitHub
|
||||||
|
;ini_use_config = example/Creality/Ender-5 Plus @ bugfix-2.1.x
|
||||||
|
# Download configurations from your server
|
||||||
|
;ini_use_config = https://me.myserver.com/path/to/configs
|
||||||
|
# Evaluate config:base and do a config dump
|
||||||
|
;ini_use_config = base
|
||||||
|
;config_export = 2
|
||||||
|
|
||||||
|
[config:minimal]
|
||||||
|
motherboard = BOARD_RAMPS_14_EFB
|
||||||
|
serial_port = 0
|
||||||
|
baudrate = 250000
|
||||||
|
|
||||||
|
use_watchdog = on
|
||||||
|
thermal_protection_hotends = on
|
||||||
|
thermal_protection_hysteresis = 4
|
||||||
|
thermal_protection_period = 40
|
||||||
|
|
||||||
|
bufsize = 4
|
||||||
|
block_buffer_size = 16
|
||||||
|
max_cmd_size = 96
|
||||||
|
|
||||||
|
extruders = 1
|
||||||
|
temp_sensor_0 = 1
|
||||||
|
|
||||||
|
temp_hysteresis = 3
|
||||||
|
heater_0_mintemp = 5
|
||||||
|
heater_0_maxtemp = 275
|
||||||
|
preheat_1_temp_hotend = 180
|
||||||
|
|
||||||
|
bang_max = 255
|
||||||
|
pidtemp = on
|
||||||
|
pid_k1 = 0.95
|
||||||
|
pid_max = BANG_MAX
|
||||||
|
pid_functional_range = 10
|
||||||
|
|
||||||
|
default_kp = 22.20
|
||||||
|
default_ki = 1.08
|
||||||
|
default_kd = 114.00
|
||||||
|
|
||||||
|
x_driver_type = A4988
|
||||||
|
y_driver_type = A4988
|
||||||
|
z_driver_type = A4988
|
||||||
|
e0_driver_type = A4988
|
||||||
|
|
||||||
|
x_bed_size = 200
|
||||||
|
x_min_pos = 0
|
||||||
|
x_max_pos = X_BED_SIZE
|
||||||
|
|
||||||
|
y_bed_size = 200
|
||||||
|
y_min_pos = 0
|
||||||
|
y_max_pos = Y_BED_SIZE
|
||||||
|
|
||||||
|
z_min_pos = 0
|
||||||
|
z_max_pos = 200
|
||||||
|
|
||||||
|
x_home_dir = -1
|
||||||
|
y_home_dir = -1
|
||||||
|
z_home_dir = -1
|
||||||
|
|
||||||
|
use_xmin_plug = on
|
||||||
|
use_ymin_plug = on
|
||||||
|
use_zmin_plug = on
|
||||||
|
|
||||||
|
x_min_endstop_inverting = false
|
||||||
|
y_min_endstop_inverting = false
|
||||||
|
z_min_endstop_inverting = false
|
||||||
|
|
||||||
|
default_axis_steps_per_unit = { 80, 80, 400, 500 }
|
||||||
|
axis_relative_modes = { false, false, false, false }
|
||||||
|
default_max_feedrate = { 300, 300, 5, 25 }
|
||||||
|
default_max_acceleration = { 3000, 3000, 100, 10000 }
|
||||||
|
|
||||||
|
homing_feedrate_mm_m = { (50*60), (50*60), (4*60) }
|
||||||
|
homing_bump_divisor = { 2, 2, 4 }
|
||||||
|
|
||||||
|
x_enable_on = 0
|
||||||
|
y_enable_on = 0
|
||||||
|
z_enable_on = 0
|
||||||
|
e_enable_on = 0
|
||||||
|
|
||||||
|
invert_x_dir = false
|
||||||
|
invert_y_dir = true
|
||||||
|
invert_z_dir = false
|
||||||
|
invert_e0_dir = false
|
||||||
|
|
||||||
|
invert_e_step_pin = false
|
||||||
|
invert_x_step_pin = false
|
||||||
|
invert_y_step_pin = false
|
||||||
|
invert_z_step_pin = false
|
||||||
|
|
||||||
|
disable_x = false
|
||||||
|
disable_y = false
|
||||||
|
disable_z = false
|
||||||
|
disable_e = false
|
||||||
|
|
||||||
|
proportional_font_ratio = 1.0
|
||||||
|
default_nominal_filament_dia = 1.75
|
||||||
|
|
||||||
|
junction_deviation_mm = 0.013
|
||||||
|
|
||||||
|
default_acceleration = 3000
|
||||||
|
default_travel_acceleration = 3000
|
||||||
|
default_retract_acceleration = 3000
|
||||||
|
|
||||||
|
default_minimumfeedrate = 0.0
|
||||||
|
default_mintravelfeedrate = 0.0
|
||||||
|
|
||||||
|
minimum_planner_speed = 0.05
|
||||||
|
min_steps_per_segment = 6
|
||||||
|
default_minsegmenttime = 20000
|
||||||
|
|
||||||
|
[config:basic]
|
||||||
|
bed_overshoot = 10
|
||||||
|
busy_while_heating = on
|
||||||
|
default_ejerk = 5.0
|
||||||
|
default_keepalive_interval = 2
|
||||||
|
default_leveling_fade_height = 0.0
|
||||||
|
disable_inactive_extruder = on
|
||||||
|
display_charset_hd44780 = JAPANESE
|
||||||
|
eeprom_boot_silent = on
|
||||||
|
eeprom_chitchat = on
|
||||||
|
endstoppullups = on
|
||||||
|
extrude_maxlength = 200
|
||||||
|
extrude_mintemp = 170
|
||||||
|
host_keepalive_feature = on
|
||||||
|
hotend_overshoot = 15
|
||||||
|
jd_handle_small_segments = on
|
||||||
|
lcd_info_screen_style = 0
|
||||||
|
lcd_language = en
|
||||||
|
max_bed_power = 255
|
||||||
|
mesh_inset = 0
|
||||||
|
min_software_endstops = on
|
||||||
|
max_software_endstops = on
|
||||||
|
min_software_endstop_x = on
|
||||||
|
min_software_endstop_y = on
|
||||||
|
min_software_endstop_z = on
|
||||||
|
max_software_endstop_x = on
|
||||||
|
max_software_endstop_y = on
|
||||||
|
max_software_endstop_z = on
|
||||||
|
preheat_1_fan_speed = 0
|
||||||
|
preheat_1_label = "PLA"
|
||||||
|
preheat_1_temp_bed = 70
|
||||||
|
prevent_cold_extrusion = on
|
||||||
|
prevent_lengthy_extrude = on
|
||||||
|
printjob_timer_autostart = on
|
||||||
|
probing_margin = 10
|
||||||
|
show_bootscreen = on
|
||||||
|
soft_pwm_scale = 0
|
||||||
|
string_config_h_author = "(none, default config)"
|
||||||
|
temp_bed_hysteresis = 3
|
||||||
|
temp_bed_residency_time = 10
|
||||||
|
temp_bed_window = 1
|
||||||
|
temp_residency_time = 10
|
||||||
|
temp_window = 1
|
||||||
|
validate_homing_endstops = on
|
||||||
|
xy_probe_feedrate = (133*60)
|
||||||
|
z_clearance_between_probes = 5
|
||||||
|
z_clearance_deploy_probe = 10
|
||||||
|
z_clearance_multi_probe = 5
|
||||||
|
|
||||||
|
[config:advanced]
|
||||||
|
arc_support = on
|
||||||
|
auto_report_temperatures = on
|
||||||
|
autotemp = on
|
||||||
|
autotemp_oldweight = 0.98
|
||||||
|
bed_check_interval = 5000
|
||||||
|
default_stepper_deactive_time = 120
|
||||||
|
default_volumetric_extruder_limit = 0.00
|
||||||
|
disable_inactive_e = true
|
||||||
|
disable_inactive_x = true
|
||||||
|
disable_inactive_y = true
|
||||||
|
disable_inactive_z = true
|
||||||
|
e0_auto_fan_pin = -1
|
||||||
|
encoder_100x_steps_per_sec = 80
|
||||||
|
encoder_10x_steps_per_sec = 30
|
||||||
|
encoder_rate_multiplier = on
|
||||||
|
extended_capabilities_report = on
|
||||||
|
extruder_auto_fan_speed = 255
|
||||||
|
extruder_auto_fan_temperature = 50
|
||||||
|
fanmux0_pin = -1
|
||||||
|
fanmux1_pin = -1
|
||||||
|
fanmux2_pin = -1
|
||||||
|
faster_gcode_parser = on
|
||||||
|
homing_bump_mm = { 5, 5, 2 }
|
||||||
|
max_arc_segment_mm = 1.0
|
||||||
|
min_arc_segment_mm = 0.1
|
||||||
|
min_circle_segments = 72
|
||||||
|
n_arc_correction = 25
|
||||||
|
serial_overrun_protection = on
|
||||||
|
slowdown = on
|
||||||
|
slowdown_divisor = 2
|
||||||
|
temp_sensor_bed = 0
|
||||||
|
thermal_protection_bed_hysteresis = 2
|
||||||
|
thermocouple_max_errors = 15
|
||||||
|
tx_buffer_size = 0
|
||||||
|
watch_bed_temp_increase = 2
|
||||||
|
watch_bed_temp_period = 60
|
||||||
|
watch_temp_increase = 2
|
||||||
|
watch_temp_period = 20
|
||||||
+102
-92
@@ -66,27 +66,26 @@ static volatile int8_t Channel[_Nbr_16timers]; // counter for the s
|
|||||||
|
|
||||||
/************ static functions common to all instances ***********************/
|
/************ static functions common to all instances ***********************/
|
||||||
|
|
||||||
static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) {
|
static inline void handle_interrupts(const timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) {
|
||||||
if (Channel[timer] < 0)
|
int8_t cho = Channel[timer]; // Handle the prior Channel[timer] first
|
||||||
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
|
if (cho < 0) // Channel -1 indicates the refresh interval completed...
|
||||||
else {
|
*TCNTn = 0; // ...so reset the timer
|
||||||
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
|
else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled?
|
||||||
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
|
extDigitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW
|
||||||
}
|
|
||||||
|
|
||||||
Channel[timer]++; // increment to the next channel
|
Channel[timer] = ++cho; // Handle the next channel (or 0)
|
||||||
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
|
if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) {
|
||||||
*OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
|
*OCRnA = *TCNTn + SERVO(timer, cho).ticks; // set compare to current ticks plus duration
|
||||||
if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated
|
if (SERVO(timer, cho).Pin.isActive) // activated?
|
||||||
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
|
extDigitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// finished all channels so wait for the refresh period to expire before starting over
|
// finished all channels so wait for the refresh period to expire before starting over
|
||||||
if (((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
|
const unsigned int cval = ((unsigned)*TCNTn) + 32 / (SERVO_TIMER_PRESCALER), // allow 32 cycles to ensure the next OCR1A not missed
|
||||||
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
|
ival = (unsigned int)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed
|
||||||
else
|
*OCRnA = max(cval, ival);
|
||||||
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
|
|
||||||
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
|
Channel[timer] = -1; // reset the timer counter to 0 on the next call
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,91 +122,102 @@ static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t
|
|||||||
|
|
||||||
/****************** end of static functions ******************************/
|
/****************** end of static functions ******************************/
|
||||||
|
|
||||||
void initISR(timer16_Sequence_t timer) {
|
void initISR(const timer16_Sequence_t timer_index) {
|
||||||
#ifdef _useTimer1
|
switch (timer_index) {
|
||||||
if (timer == _timer1) {
|
default: break;
|
||||||
TCCR1A = 0; // normal counting mode
|
|
||||||
TCCR1B = _BV(CS11); // set prescaler of 8
|
|
||||||
TCNT1 = 0; // clear the timer count
|
|
||||||
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
|
|
||||||
SBI(TIFR, OCF1A); // clear any pending interrupts;
|
|
||||||
SBI(TIMSK, OCIE1A); // enable the output compare interrupt
|
|
||||||
#else
|
|
||||||
// here if not ATmega8 or ATmega128
|
|
||||||
SBI(TIFR1, OCF1A); // clear any pending interrupts;
|
|
||||||
SBI(TIMSK1, OCIE1A); // enable the output compare interrupt
|
|
||||||
#endif
|
|
||||||
#ifdef WIRING
|
|
||||||
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _useTimer3
|
#ifdef _useTimer1
|
||||||
if (timer == _timer3) {
|
case _timer1:
|
||||||
TCCR3A = 0; // normal counting mode
|
TCCR1A = 0; // normal counting mode
|
||||||
TCCR3B = _BV(CS31); // set prescaler of 8
|
TCCR1B = _BV(CS11); // set prescaler of 8
|
||||||
TCNT3 = 0; // clear the timer count
|
TCNT1 = 0; // clear the timer count
|
||||||
#ifdef __AVR_ATmega128__
|
#if defined(__AVR_ATmega8__) || defined(__AVR_ATmega128__)
|
||||||
SBI(TIFR, OCF3A); // clear any pending interrupts;
|
SBI(TIFR, OCF1A); // clear any pending interrupts;
|
||||||
SBI(ETIMSK, OCIE3A); // enable the output compare interrupt
|
SBI(TIMSK, OCIE1A); // enable the output compare interrupt
|
||||||
#else
|
#else
|
||||||
SBI(TIFR3, OCF3A); // clear any pending interrupts;
|
// here if not ATmega8 or ATmega128
|
||||||
SBI(TIMSK3, OCIE3A); // enable the output compare interrupt
|
SBI(TIFR1, OCF1A); // clear any pending interrupts;
|
||||||
#endif
|
SBI(TIMSK1, OCIE1A); // enable the output compare interrupt
|
||||||
#ifdef WIRING
|
#endif
|
||||||
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
|
#ifdef WIRING
|
||||||
#endif
|
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
|
||||||
}
|
#endif
|
||||||
#endif
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _useTimer4
|
#ifdef _useTimer3
|
||||||
if (timer == _timer4) {
|
case _timer3:
|
||||||
TCCR4A = 0; // normal counting mode
|
TCCR3A = 0; // normal counting mode
|
||||||
TCCR4B = _BV(CS41); // set prescaler of 8
|
TCCR3B = _BV(CS31); // set prescaler of 8
|
||||||
TCNT4 = 0; // clear the timer count
|
TCNT3 = 0; // clear the timer count
|
||||||
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
|
#ifdef __AVR_ATmega128__
|
||||||
TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt
|
SBI(TIFR, OCF3A); // clear any pending interrupts;
|
||||||
}
|
SBI(ETIMSK, OCIE3A); // enable the output compare interrupt
|
||||||
#endif
|
#else
|
||||||
|
SBI(TIFR3, OCF3A); // clear any pending interrupts;
|
||||||
|
SBI(TIMSK3, OCIE3A); // enable the output compare interrupt
|
||||||
|
#endif
|
||||||
|
#ifdef WIRING
|
||||||
|
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef _useTimer5
|
#ifdef _useTimer4
|
||||||
if (timer == _timer5) {
|
case _timer4:
|
||||||
TCCR5A = 0; // normal counting mode
|
TCCR4A = 0; // normal counting mode
|
||||||
TCCR5B = _BV(CS51); // set prescaler of 8
|
TCCR4B = _BV(CS41); // set prescaler of 8
|
||||||
TCNT5 = 0; // clear the timer count
|
TCNT4 = 0; // clear the timer count
|
||||||
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
|
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
|
||||||
TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt
|
TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt
|
||||||
}
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef _useTimer5
|
||||||
|
case _timer5:
|
||||||
|
TCCR5A = 0; // normal counting mode
|
||||||
|
TCCR5B = _BV(CS51); // set prescaler of 8
|
||||||
|
TCNT5 = 0; // clear the timer count
|
||||||
|
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
|
||||||
|
TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void finISR(timer16_Sequence_t timer) {
|
void finISR(const timer16_Sequence_t timer_index) {
|
||||||
// Disable use of the given timer
|
// Disable use of the given timer
|
||||||
#ifdef WIRING
|
#ifdef WIRING
|
||||||
if (timer == _timer1) {
|
switch (timer_index) {
|
||||||
CBI(
|
default: break;
|
||||||
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
|
||||||
TIMSK1
|
case _timer1:
|
||||||
#else
|
CBI(
|
||||||
TIMSK
|
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
||||||
#endif
|
TIMSK1
|
||||||
, OCIE1A); // disable timer 1 output compare interrupt
|
#else
|
||||||
timerDetach(TIMER1OUTCOMPAREA_INT);
|
TIMSK
|
||||||
}
|
#endif
|
||||||
else if (timer == _timer3) {
|
, OCIE1A // disable timer 1 output compare interrupt
|
||||||
CBI(
|
);
|
||||||
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
timerDetach(TIMER1OUTCOMPAREA_INT);
|
||||||
TIMSK3
|
break;
|
||||||
#else
|
|
||||||
ETIMSK
|
case _timer3:
|
||||||
#endif
|
CBI(
|
||||||
, OCIE3A); // disable the timer3 output compare A interrupt
|
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
||||||
timerDetach(TIMER3OUTCOMPAREA_INT);
|
TIMSK3
|
||||||
|
#else
|
||||||
|
ETIMSK
|
||||||
|
#endif
|
||||||
|
, OCIE3A // disable the timer3 output compare A interrupt
|
||||||
|
);
|
||||||
|
timerDetach(TIMER3OUTCOMPAREA_INT);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#else // !WIRING
|
#else // !WIRING
|
||||||
// For arduino - in future: call here to a currently undefined function to reset the timer
|
// For arduino - in future: call here to a currently undefined function to reset the timer
|
||||||
UNUSED(timer);
|
UNUSED(timer_index);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,11 +35,19 @@
|
|||||||
|| X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_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_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \
|
||||||
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
|
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
|
||||||
|
|| BTN_EN1 == N || BTN_EN2 == N \
|
||||||
)
|
)
|
||||||
#if CONF_SERIAL_IS(0) // D0-D1. No known conflicts.
|
#if CONF_SERIAL_IS(0)
|
||||||
|
// D0-D1. No known conflicts.
|
||||||
#endif
|
#endif
|
||||||
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19))
|
#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
|
||||||
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
|
#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
|
||||||
|
#else
|
||||||
|
#if CONF_SERIAL_IS(1) && (CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11))
|
||||||
|
#error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board."
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if CONF_SERIAL_IS(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
|
#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."
|
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
#define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin
|
#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) {
|
void PRINT_ARRAY_NAME(uint8_t x) {
|
||||||
const char * const name_mem_pointer = (PGM_P)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) {
|
LOOP_L_N(y, MAX_NAME_LENGTH) {
|
||||||
char temp_char = pgm_read_byte(name_mem_pointer + y);
|
char temp_char = pgm_read_byte(name_mem_pointer + y);
|
||||||
if (temp_char != 0)
|
if (temp_char != 0)
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ public:
|
|||||||
static void adc_init() {}
|
static void adc_init() {}
|
||||||
|
|
||||||
// Called by Temperature::init for each sensor at startup
|
// Called by Temperature::init for each sensor at startup
|
||||||
static void adc_enable(const uint8_t ch) {}
|
static void adc_enable(const uint8_t /*ch*/) {}
|
||||||
|
|
||||||
// Begin ADC sampling on the given channel. Called from Temperature::isr!
|
// Begin ADC sampling on the given channel. Called from Temperature::isr!
|
||||||
static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }
|
static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }
|
||||||
|
|||||||
@@ -247,12 +247,12 @@
|
|||||||
b <<= 1; // little setup time
|
b <<= 1; // little setup time
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, HIGH);
|
WRITE(SD_SCK_PIN, HIGH);
|
||||||
DELAY_NS(spiDelayNS);
|
DELAY_NS_VAR(spiDelayNS);
|
||||||
|
|
||||||
b |= (READ(SD_MISO_PIN) != 0);
|
b |= (READ(SD_MISO_PIN) != 0);
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SD_SCK_PIN, LOW);
|
||||||
DELAY_NS(spiDelayNS);
|
DELAY_NS_VAR(spiDelayNS);
|
||||||
} while (--bits);
|
} while (--bits);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@
|
|||||||
practice, we need alignment to 256 bytes to make this work in all
|
practice, we need alignment to 256 bytes to make this work in all
|
||||||
cases */
|
cases */
|
||||||
__attribute__ ((aligned(256)))
|
__attribute__ ((aligned(256)))
|
||||||
static DeviceVectors ram_tab = { nullptr };
|
static DeviceVectors ram_tab[61] = { nullptr };
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function checks if the exception/interrupt table is already in SRAM or not.
|
* This function checks if the exception/interrupt table is already in SRAM or not.
|
||||||
|
|||||||
@@ -47,12 +47,12 @@
|
|||||||
#include "../shared/servo.h"
|
#include "../shared/servo.h"
|
||||||
#include "../shared/servo_private.h"
|
#include "../shared/servo_private.h"
|
||||||
|
|
||||||
static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
|
static Flags<_Nbr_16timers> DisablePending; // ISR should disable the timer at the next timer reset
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
/// Interrupt handler for the TC0 channel 1.
|
/// Interrupt handler for the TC0 channel 1.
|
||||||
// ------------------------
|
// ------------------------
|
||||||
void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel);
|
void Servo_Handler(const timer16_Sequence_t, Tc*, const uint8_t);
|
||||||
|
|
||||||
#ifdef _useTimer1
|
#ifdef _useTimer1
|
||||||
void HANDLER_FOR_TIMER1() { Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); }
|
void HANDLER_FOR_TIMER1() { Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); }
|
||||||
@@ -70,88 +70,92 @@ void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel);
|
|||||||
void HANDLER_FOR_TIMER5() { Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); }
|
void HANDLER_FOR_TIMER5() { Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) {
|
void Servo_Handler(const timer16_Sequence_t timer, Tc *tc, const uint8_t channel) {
|
||||||
// clear interrupt
|
static int8_t Channel[_Nbr_16timers]; // Servo counters to pulse (or -1 for refresh interval)
|
||||||
tc->TC_CHANNEL[channel].TC_SR;
|
int8_t cho = Channel[timer]; // Handle the prior Channel[timer] first
|
||||||
if (Channel[timer] < 0)
|
if (cho < 0) { // Channel -1 indicates the refresh interval completed...
|
||||||
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
|
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // ...so reset the timer
|
||||||
else if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
|
if (DisablePending[timer]) {
|
||||||
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
|
// Disabling only after the full servo period expires prevents
|
||||||
|
// pulses being too close together if immediately re-enabled.
|
||||||
|
DisablePending.clear(timer);
|
||||||
|
TC_Stop(tc, channel);
|
||||||
|
tc->TC_CHANNEL[channel].TC_SR; // clear interrupt
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled?
|
||||||
|
extDigitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW
|
||||||
|
|
||||||
Channel[timer]++; // increment to the next channel
|
Channel[timer] = ++cho; // go to the next channel (or 0)
|
||||||
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
|
if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) {
|
||||||
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
|
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer, cho).ticks;
|
||||||
if (SERVO(timer,Channel[timer]).Pin.isActive) // check if activated
|
if (SERVO(timer, cho).Pin.isActive) // activated?
|
||||||
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
|
extDigitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// finished all channels so wait for the refresh period to expire before starting over
|
// finished all channels so wait for the refresh period to expire before starting over
|
||||||
tc->TC_CHANNEL[channel].TC_RA =
|
const unsigned int cval = tc->TC_CHANNEL[channel].TC_CV + 128 / (SERVO_TIMER_PRESCALER), // allow 128 cycles to ensure the next CV not missed
|
||||||
tc->TC_CHANNEL[channel].TC_CV < usToTicks(REFRESH_INTERVAL) - 4
|
ival = (unsigned int)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed
|
||||||
? (unsigned int)usToTicks(REFRESH_INTERVAL) // allow a few ticks to ensure the next OCR1A not missed
|
tc->TC_CHANNEL[channel].TC_RA = max(cval, ival);
|
||||||
: tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed
|
|
||||||
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
|
Channel[timer] = -1; // reset the timer CCR on the next call
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tc->TC_CHANNEL[channel].TC_SR; // clear interrupt
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) {
|
static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) {
|
||||||
pmc_enable_periph_clk(id);
|
pmc_enable_periph_clk(id);
|
||||||
TC_Configure(tc, channel,
|
TC_Configure(tc, channel,
|
||||||
TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32
|
TC_CMR_WAVE // Waveform mode
|
||||||
TC_CMR_WAVE | // Waveform mode
|
| TC_CMR_WAVSEL_UP_RC // Counter running up and reset when equal to RC
|
||||||
TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
|
| (SERVO_TIMER_PRESCALER == 2 ? TC_CMR_TCCLKS_TIMER_CLOCK1 : 0) // MCK/2
|
||||||
|
| (SERVO_TIMER_PRESCALER == 8 ? TC_CMR_TCCLKS_TIMER_CLOCK2 : 0) // MCK/8
|
||||||
|
| (SERVO_TIMER_PRESCALER == 32 ? TC_CMR_TCCLKS_TIMER_CLOCK3 : 0) // MCK/32
|
||||||
|
| (SERVO_TIMER_PRESCALER == 128 ? TC_CMR_TCCLKS_TIMER_CLOCK4 : 0) // MCK/128
|
||||||
|
);
|
||||||
|
|
||||||
/* 84MHz, MCK/32, for 1.5ms: 3937 */
|
// Wait 1ms before the first ISR
|
||||||
TC_SetRA(tc, channel, 2625); // 1ms
|
TC_SetRA(tc, channel, (F_CPU) / (SERVO_TIMER_PRESCALER) / 1000UL); // 1ms
|
||||||
|
|
||||||
/* Configure and enable interrupt */
|
// Configure and enable interrupt
|
||||||
NVIC_EnableIRQ(irqn);
|
NVIC_EnableIRQ(irqn);
|
||||||
// TC_IER_CPAS: RA Compare
|
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS; // TC_IER_CPAS: RA Compare
|
||||||
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS;
|
|
||||||
|
|
||||||
// Enables the timer clock and performs a software reset to start the counting
|
// Enables the timer clock and performs a software reset to start the counting
|
||||||
TC_Start(tc, channel);
|
TC_Start(tc, channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initISR(timer16_Sequence_t timer) {
|
void initISR(const timer16_Sequence_t timer_index) {
|
||||||
#ifdef _useTimer1
|
CRITICAL_SECTION_START();
|
||||||
if (timer == _timer1)
|
const bool disable_soon = DisablePending[timer_index];
|
||||||
_initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
|
DisablePending.clear(timer_index);
|
||||||
#endif
|
CRITICAL_SECTION_END();
|
||||||
#ifdef _useTimer2
|
|
||||||
if (timer == _timer2)
|
if (!disable_soon) switch (timer_index) {
|
||||||
_initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
|
default: break;
|
||||||
#endif
|
#ifdef _useTimer1
|
||||||
#ifdef _useTimer3
|
case _timer1: return _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
|
||||||
if (timer == _timer3)
|
#endif
|
||||||
_initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
|
#ifdef _useTimer2
|
||||||
#endif
|
case _timer2: return _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
|
||||||
#ifdef _useTimer4
|
#endif
|
||||||
if (timer == _timer4)
|
#ifdef _useTimer3
|
||||||
_initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
|
case _timer3: return _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
|
||||||
#endif
|
#endif
|
||||||
#ifdef _useTimer5
|
#ifdef _useTimer4
|
||||||
if (timer == _timer5)
|
case _timer4: return _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
|
||||||
_initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
|
#endif
|
||||||
#endif
|
#ifdef _useTimer5
|
||||||
|
case _timer5: return _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void finISR(timer16_Sequence_t) {
|
void finISR(const timer16_Sequence_t timer_index) {
|
||||||
#ifdef _useTimer1
|
// Timer is disabled from the ISR, to ensure proper final pulse length.
|
||||||
TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1);
|
DisablePending.set(timer_index);
|
||||||
#endif
|
|
||||||
#ifdef _useTimer2
|
|
||||||
TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2);
|
|
||||||
#endif
|
|
||||||
#ifdef _useTimer3
|
|
||||||
TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3);
|
|
||||||
#endif
|
|
||||||
#ifdef _useTimer4
|
|
||||||
TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4);
|
|
||||||
#endif
|
|
||||||
#ifdef _useTimer5
|
|
||||||
TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_SERVOS
|
#endif // HAS_SERVOS
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
#define _useTimer5
|
#define _useTimer5
|
||||||
|
|
||||||
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays
|
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays
|
||||||
#define SERVO_TIMER_PRESCALER 32 // timer prescaler
|
#define SERVO_TIMER_PRESCALER 2 // timer prescaler
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TC0, chan 0 => TC0_Handler
|
TC0, chan 0 => TC0_Handler
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
||||||
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
||||||
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
|
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
|
||||||
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0)
|
#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
|
||||||
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
|
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
|
||||||
#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
|
#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
|
||||||
#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \
|
#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \
|
||||||
|
|||||||
@@ -89,10 +89,17 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
|||||||
NVIC_SetPriority(irq, timer_config[timer_num].priority);
|
NVIC_SetPriority(irq, timer_config[timer_num].priority);
|
||||||
|
|
||||||
// wave mode, reset counter on match with RC,
|
// wave mode, reset counter on match with RC,
|
||||||
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
|
TC_Configure(tc, channel,
|
||||||
|
TC_CMR_WAVE
|
||||||
|
| TC_CMR_WAVSEL_UP_RC
|
||||||
|
| (HAL_TIMER_PRESCALER == 2 ? TC_CMR_TCCLKS_TIMER_CLOCK1 : 0)
|
||||||
|
| (HAL_TIMER_PRESCALER == 8 ? TC_CMR_TCCLKS_TIMER_CLOCK2 : 0)
|
||||||
|
| (HAL_TIMER_PRESCALER == 32 ? TC_CMR_TCCLKS_TIMER_CLOCK3 : 0)
|
||||||
|
| (HAL_TIMER_PRESCALER == 128 ? TC_CMR_TCCLKS_TIMER_CLOCK4 : 0)
|
||||||
|
);
|
||||||
|
|
||||||
// Set compare value
|
// Set compare value
|
||||||
TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency);
|
TC_SetRC(tc, channel, VARIANT_MCK / (HAL_TIMER_PRESCALER) / frequency);
|
||||||
|
|
||||||
// And start timer
|
// And start timer
|
||||||
TC_Start(tc, channel);
|
TC_Start(tc, channel);
|
||||||
|
|||||||
@@ -35,7 +35,8 @@
|
|||||||
typedef uint32_t hal_timer_t;
|
typedef uint32_t hal_timer_t;
|
||||||
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
|
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
|
||||||
|
|
||||||
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
|
#define HAL_TIMER_PRESCALER 2
|
||||||
|
#define HAL_TIMER_RATE ((F_CPU) / (HAL_TIMER_PRESCALER)) // frequency of timers peripherals
|
||||||
|
|
||||||
#ifndef MF_TIMER_STEP
|
#ifndef MF_TIMER_STEP
|
||||||
#define MF_TIMER_STEP 2 // Timer Index for Stepper
|
#define MF_TIMER_STEP 2 // Timer Index for Stepper
|
||||||
|
|||||||
@@ -1059,7 +1059,7 @@ static inline void convert_64_bit_to_byte_array(uint64_t value, uint8_t *data)
|
|||||||
while (val_index < 8)
|
while (val_index < 8)
|
||||||
{
|
{
|
||||||
data[val_index++] = value & 0xFF;
|
data[val_index++] = value & 0xFF;
|
||||||
value = value >> 8;
|
value >>= 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ void usb_task_idle(void) {
|
|||||||
// Attend SD card access from the USB MSD -- Prioritize access to improve speed
|
// Attend SD card access from the USB MSD -- Prioritize access to improve speed
|
||||||
int delay = 2;
|
int delay = 2;
|
||||||
while (main_b_msc_enable && --delay > 0) {
|
while (main_b_msc_enable && --delay > 0) {
|
||||||
if (udi_msc_process_trans()) delay = 10000;
|
if (udi_msc_process_trans()) delay = 20;
|
||||||
|
|
||||||
// Reset the watchdog, just to be sure
|
// Reset the watchdog, just to be sure
|
||||||
REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5);
|
REG_WDT_CR = WDT_CR_WDRSTT | WDT_CR_KEY(0xA5);
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ portMUX_TYPE MarlinHAL::spinlock = portMUX_INITIALIZER_UNLOCKED;
|
|||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
||||||
uint16_t MarlinHAL::adc_result;
|
uint16_t MarlinHAL::adc_result;
|
||||||
|
pwm_pin_t MarlinHAL::pwm_pin_data[MAX_EXPANDER_BITS];
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Private Variables
|
// Private Variables
|
||||||
@@ -330,21 +331,46 @@ int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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*/) {
|
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 ENABLED(I2S_STEPPER_STREAM)
|
||||||
if (cid >= 0) {
|
if (pin > 127) {
|
||||||
uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1);
|
const uint8_t pinlo = pin & 0x7F;
|
||||||
ledcWrite(cid, duty);
|
pwm_pin_t &pindata = pwm_pin_data[pinlo];
|
||||||
}
|
const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, pindata.pwm_cycle_ticks);
|
||||||
|
if (duty == 0 || duty == pindata.pwm_cycle_ticks) { // max or min (i.e., on/off)
|
||||||
|
pindata.pwm_duty_ticks = 0; // turn off PWM for this pin
|
||||||
|
duty ? SBI32(i2s_port_data, pinlo) : CBI32(i2s_port_data, pinlo); // set pin level
|
||||||
|
}
|
||||||
|
else
|
||||||
|
pindata.pwm_duty_ticks = duty; // PWM duty count = # of 4µs ticks per full PWM cycle
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION);
|
||||||
|
if (cid >= 0) {
|
||||||
|
const 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) {
|
int8_t MarlinHAL::set_pwm_frequency(const pin_t pin, const uint32_t f_desired) {
|
||||||
const int8_t cid = channel_for_pin(pin);
|
#if ENABLED(I2S_STEPPER_STREAM)
|
||||||
if (cid >= 0) {
|
if (pin > 127) {
|
||||||
if (f_desired == ledcReadFreq(cid)) return cid; // no freq change
|
pwm_pin_data[pin & 0x7F].pwm_cycle_ticks = 1000000UL / f_desired / 4; // # of 4µs ticks per full PWM cycle
|
||||||
ledcDetachPin(chan_pin[cid]);
|
return 0;
|
||||||
chan_pin[cid] = 0; // remove old freq channel
|
}
|
||||||
}
|
else
|
||||||
return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one
|
#endif
|
||||||
|
{
|
||||||
|
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
|
// use hardware PWM if avail, if not then ISR
|
||||||
|
|||||||
@@ -60,14 +60,17 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define CRITICAL_SECTION_START() portENTER_CRITICAL(&spinlock)
|
#define CRITICAL_SECTION_START() portENTER_CRITICAL(&hal.spinlock)
|
||||||
#define CRITICAL_SECTION_END() portEXIT_CRITICAL(&spinlock)
|
#define CRITICAL_SECTION_END() portEXIT_CRITICAL(&hal.spinlock)
|
||||||
|
|
||||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
#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_FREQUENCY 1000u // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency()
|
||||||
#define PWM_RESOLUTION 10u // Default PWM bit resolution
|
#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 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
|
#define MAX_PWM_IOPIN 33u // hardware pwm pins < 34
|
||||||
|
#ifndef MAX_EXPANDER_BITS
|
||||||
|
#define MAX_EXPANDER_BITS 32 // I2S expander bit width (max 32)
|
||||||
|
#endif
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Types
|
// Types
|
||||||
@@ -76,6 +79,12 @@
|
|||||||
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
|
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
|
||||||
typedef int16_t pin_t;
|
typedef int16_t pin_t;
|
||||||
|
|
||||||
|
typedef struct pwm_pin {
|
||||||
|
uint32_t pwm_cycle_ticks = 1000000UL / (PWM_FREQUENCY) / 4; // # ticks per pwm cycle
|
||||||
|
uint32_t pwm_tick_count = 0; // current tick count
|
||||||
|
uint32_t pwm_duty_ticks = 0; // # of ticks for current duty cycle
|
||||||
|
} pwm_pin_t;
|
||||||
|
|
||||||
class Servo;
|
class Servo;
|
||||||
typedef Servo hal_servo_t;
|
typedef Servo hal_servo_t;
|
||||||
|
|
||||||
@@ -197,6 +206,8 @@ public:
|
|||||||
// Free SRAM
|
// Free SRAM
|
||||||
static int freeMemory();
|
static int freeMemory();
|
||||||
|
|
||||||
|
static pwm_pin_t pwm_pin_data[MAX_EXPANDER_BITS];
|
||||||
|
|
||||||
//
|
//
|
||||||
// ADC Methods
|
// ADC Methods
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -139,22 +139,40 @@ static void IRAM_ATTR i2s_intr_handler_default(void *arg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void stepperTask(void *parameter) {
|
void stepperTask(void *parameter) {
|
||||||
uint32_t remaining = 0;
|
uint32_t nextMainISR = 0;
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
|
uint32_t nextAdvanceISR = Stepper::LA_ADV_NEVER;
|
||||||
|
#endif
|
||||||
|
|
||||||
while (1) {
|
for (;;) {
|
||||||
xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
|
xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
|
||||||
dma.rw_pos = 0;
|
dma.rw_pos = 0;
|
||||||
|
|
||||||
while (dma.rw_pos < DMA_SAMPLE_COUNT) {
|
while (dma.rw_pos < DMA_SAMPLE_COUNT) {
|
||||||
// Fill with the port data post pulse_phase until the next step
|
// Fill with the port data post pulse_phase until the next step
|
||||||
if (remaining) {
|
if (nextMainISR && TERN1(LIN_ADVANCE, nextAdvanceISR))
|
||||||
i2s_push_sample();
|
i2s_push_sample();
|
||||||
remaining--;
|
|
||||||
}
|
// i2s_push_sample() is also called from Stepper::pulse_phase_isr() and Stepper::advance_isr()
|
||||||
else {
|
// in a rare case where both are called, we need to double decrement the counters
|
||||||
|
const uint8_t push_count = 1 + (!nextMainISR && TERN0(LIN_ADVANCE, !nextAdvanceISR));
|
||||||
|
|
||||||
|
#if ENABLED(LIN_ADVANCE)
|
||||||
|
if (!nextAdvanceISR) {
|
||||||
|
Stepper::advance_isr();
|
||||||
|
nextAdvanceISR = Stepper::la_interval;
|
||||||
|
}
|
||||||
|
else if (nextAdvanceISR == Stepper::LA_ADV_NEVER)
|
||||||
|
nextAdvanceISR = Stepper::la_interval;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!nextMainISR) {
|
||||||
Stepper::pulse_phase_isr();
|
Stepper::pulse_phase_isr();
|
||||||
remaining = Stepper::block_phase_isr();
|
nextMainISR = Stepper::block_phase_isr();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nextMainISR -= push_count;
|
||||||
|
TERN_(LIN_ADVANCE, nextAdvanceISR -= push_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -337,6 +355,26 @@ uint8_t i2s_state(uint8_t pin) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void i2s_push_sample() {
|
void i2s_push_sample() {
|
||||||
|
// Every 4µs (when space in DMA buffer) toggle each expander PWM output using
|
||||||
|
// the current duty cycle/frequency so they sync with any steps (once
|
||||||
|
// through the DMA/FIFO buffers). PWM signal inversion handled by other functions
|
||||||
|
LOOP_L_N(p, MAX_EXPANDER_BITS) {
|
||||||
|
if (hal.pwm_pin_data[p].pwm_duty_ticks > 0) { // pin has active pwm?
|
||||||
|
if (hal.pwm_pin_data[p].pwm_tick_count == 0) {
|
||||||
|
if (TEST32(i2s_port_data, p)) { // hi->lo
|
||||||
|
CBI32(i2s_port_data, p);
|
||||||
|
hal.pwm_pin_data[p].pwm_tick_count = hal.pwm_pin_data[p].pwm_cycle_ticks - hal.pwm_pin_data[p].pwm_duty_ticks;
|
||||||
|
}
|
||||||
|
else { // lo->hi
|
||||||
|
SBI32(i2s_port_data, p);
|
||||||
|
hal.pwm_pin_data[p].pwm_tick_count = hal.pwm_pin_data[p].pwm_duty_ticks;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
hal.pwm_pin_data[p].pwm_tick_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
dma.current[dma.rw_pos++] = i2s_port_data;
|
dma.current[dma.rw_pos++] = i2s_port_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,3 +20,10 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
//
|
||||||
|
// Board-specific options need to be defined before HAL.h
|
||||||
|
//
|
||||||
|
#if MB(MKS_TINYBEE)
|
||||||
|
#define MAX_EXPANDER_BITS 24 // TinyBee has 3 x HC595
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -45,6 +45,14 @@
|
|||||||
#error "FAST_PWM_FAN is not available on TinyBee."
|
#error "FAST_PWM_FAN is not available on TinyBee."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BOTH(I2S_STEPPER_STREAM, BABYSTEPPING) && DISABLED(INTEGRATED_BABYSTEPPING)
|
||||||
|
#error "BABYSTEPPING on I2S stream requires INTEGRATED_BABYSTEPPING."
|
||||||
|
#endif
|
||||||
|
|
||||||
#if USING_PULLDOWNS
|
#if USING_PULLDOWNS
|
||||||
#error "PULLDOWN pin mode is not available on ESP32 boards."
|
#error "PULLDOWN pin mode is not available on ESP32 boards."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE) && DISABLED(EXPERIMENTAL_I2S_LA)
|
||||||
|
#error "I2S stream is currently incompatible with LIN_ADVANCE."
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -32,6 +32,13 @@
|
|||||||
#include "HAL.h"
|
#include "HAL.h"
|
||||||
#include "SPI.h"
|
#include "SPI.h"
|
||||||
|
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
#include "../../sd/cardreader.h"
|
||||||
|
#if ENABLED(ESP3D_WIFISUPPORT)
|
||||||
|
#include "sd_ESP32.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static SPISettings spiConfig;
|
static SPISettings spiConfig;
|
||||||
|
|
||||||
|
|
||||||
@@ -45,6 +52,11 @@ static SPISettings spiConfig;
|
|||||||
|
|
||||||
uint8_t u8g_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
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
|
static uint8_t msgInitCount = 2; // Ignore all messages until 2nd U8G_COM_MSG_INIT
|
||||||
|
|
||||||
|
#if ENABLED(PAUSE_LCD_FOR_BUSY_SD)
|
||||||
|
if (card.flag.saving || card.flag.logging || TERN0(ESP3D_WIFISUPPORT, sd_busy_lock == true)) return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (msgInitCount) {
|
if (msgInitCount) {
|
||||||
if (msg == U8G_COM_MSG_INIT) msgInitCount--;
|
if (msg == U8G_COM_MSG_INIT) msgInitCount--;
|
||||||
if (msgInitCount) return -1;
|
if (msgInitCount) return -1;
|
||||||
|
|||||||
@@ -69,12 +69,12 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
|
|||||||
std::size_t bytes_written = 0;
|
std::size_t bytes_written = 0;
|
||||||
|
|
||||||
for (std::size_t i = 0; i < size; i++) {
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
buffer[pos+i] = value[i];
|
buffer[pos + i] = value[i];
|
||||||
bytes_written ++;
|
bytes_written++;
|
||||||
}
|
}
|
||||||
|
|
||||||
crc16(crc, value, size);
|
crc16(crc, value, size);
|
||||||
pos = pos + size;
|
pos += size;
|
||||||
return (bytes_written != size); // return true for any error
|
return (bytes_written != size); // return true for any error
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,21 +82,21 @@ bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uin
|
|||||||
std::size_t bytes_read = 0;
|
std::size_t bytes_read = 0;
|
||||||
if (writing) {
|
if (writing) {
|
||||||
for (std::size_t i = 0; i < size; i++) {
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
value[i] = buffer[pos+i];
|
value[i] = buffer[pos + i];
|
||||||
bytes_read ++;
|
bytes_read++;
|
||||||
}
|
}
|
||||||
crc16(crc, value, size);
|
crc16(crc, value, size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uint8_t temp[size];
|
uint8_t temp[size];
|
||||||
for (std::size_t i = 0; i < size; i++) {
|
for (std::size_t i = 0; i < size; i++) {
|
||||||
temp[i] = buffer[pos+i];
|
temp[i] = buffer[pos + i];
|
||||||
bytes_read ++;
|
bytes_read++;
|
||||||
}
|
}
|
||||||
crc16(crc, temp, size);
|
crc16(crc, temp, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pos = pos + size;
|
pos += size;
|
||||||
return bytes_read != size; // return true for any error
|
return bytes_read != size; // return true for any error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,8 @@
|
|||||||
struct LowpassFilter {
|
struct LowpassFilter {
|
||||||
uint64_t data_delay = 0;
|
uint64_t data_delay = 0;
|
||||||
uint16_t update(uint16_t value) {
|
uint16_t update(uint16_t value) {
|
||||||
data_delay = data_delay - (data_delay >> 6) + value;
|
data_delay += value - (data_delay >> 6);
|
||||||
return (uint16_t)(data_delay >> 6);
|
return uint16_t(data_delay >> 6);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,6 @@
|
|||||||
|
|
||||||
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
|
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
|
||||||
// TODO: Which other boards are incompatible?
|
// TODO: Which other boards are incompatible?
|
||||||
#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0
|
#if defined(MCU_LPC1768) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0
|
||||||
#define PRINTCOUNTER_SYNC 1
|
#define PRINTCOUNTER_SYNC 1
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,119 +9,127 @@ from __future__ import print_function
|
|||||||
import pioutil
|
import pioutil
|
||||||
if pioutil.is_pio_build():
|
if pioutil.is_pio_build():
|
||||||
|
|
||||||
target_filename = "FIRMWARE.CUR"
|
target_filename = "FIRMWARE.CUR"
|
||||||
target_drive = "REARM"
|
target_drive = "REARM"
|
||||||
|
|
||||||
import os,getpass,platform
|
import platform
|
||||||
|
|
||||||
current_OS = platform.system()
|
current_OS = platform.system()
|
||||||
Import("env")
|
Import("env")
|
||||||
|
|
||||||
def print_error(e):
|
def print_error(e):
|
||||||
print('\nUnable to find destination disk (%s)\n' \
|
print('\nUnable to find destination disk (%s)\n' \
|
||||||
'Please select it in platformio.ini using the upload_port keyword ' \
|
'Please select it in platformio.ini using the upload_port keyword ' \
|
||||||
'(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
|
'(https://docs.platformio.org/en/latest/projectconf/section_env_upload.html) ' \
|
||||||
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
|
'or copy the firmware (.pio/build/%s/firmware.bin) manually to the appropriate disk\n' \
|
||||||
%(e, env.get('PIOENV')))
|
%(e, env.get('PIOENV')))
|
||||||
|
|
||||||
def before_upload(source, target, env):
|
def before_upload(source, target, env):
|
||||||
try:
|
try:
|
||||||
#
|
from pathlib import Path
|
||||||
# Find a disk for upload
|
#
|
||||||
#
|
# Find a disk for upload
|
||||||
upload_disk = 'Disk not found'
|
#
|
||||||
target_file_found = False
|
upload_disk = 'Disk not found'
|
||||||
target_drive_found = False
|
target_file_found = False
|
||||||
if current_OS == 'Windows':
|
target_drive_found = False
|
||||||
#
|
if current_OS == 'Windows':
|
||||||
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
|
#
|
||||||
# Windows - doesn't care about the disk's name, only cares about the drive letter
|
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
|
||||||
import subprocess,string
|
# Windows - doesn't care about the disk's name, only cares about the drive letter
|
||||||
from ctypes import windll
|
import subprocess,string
|
||||||
|
from ctypes import windll
|
||||||
|
from pathlib import PureWindowsPath
|
||||||
|
|
||||||
# getting list of drives
|
# getting list of drives
|
||||||
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
|
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
|
||||||
drives = []
|
drives = []
|
||||||
bitmask = windll.kernel32.GetLogicalDrives()
|
bitmask = windll.kernel32.GetLogicalDrives()
|
||||||
for letter in string.ascii_uppercase:
|
for letter in string.ascii_uppercase:
|
||||||
if bitmask & 1:
|
if bitmask & 1:
|
||||||
drives.append(letter)
|
drives.append(letter)
|
||||||
bitmask >>= 1
|
bitmask >>= 1
|
||||||
|
|
||||||
for drive in drives:
|
for drive in drives:
|
||||||
final_drive_name = drive + ':\\'
|
final_drive_name = drive + ':'
|
||||||
# print ('disc check: {}'.format(final_drive_name))
|
# print ('disc check: {}'.format(final_drive_name))
|
||||||
try:
|
try:
|
||||||
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
|
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print ('error:{}'.format(e))
|
print ('error:{}'.format(e))
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
|
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
|
||||||
target_drive_found = True
|
target_drive_found = True
|
||||||
upload_disk = final_drive_name
|
upload_disk = PureWindowsPath(final_drive_name)
|
||||||
if target_filename in volume_info:
|
if target_filename in volume_info:
|
||||||
if not target_file_found:
|
if not target_file_found:
|
||||||
upload_disk = final_drive_name
|
upload_disk = PureWindowsPath(final_drive_name)
|
||||||
target_file_found = True
|
target_file_found = True
|
||||||
|
|
||||||
elif current_OS == 'Linux':
|
elif current_OS == 'Linux':
|
||||||
#
|
#
|
||||||
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
|
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
|
||||||
#
|
#
|
||||||
drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
|
import getpass
|
||||||
if target_drive in drives: # If target drive is found, use it.
|
user = getpass.getuser()
|
||||||
target_drive_found = True
|
mpath = Path('/media', user)
|
||||||
upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), target_drive) + os.sep
|
drives = [ x for x in mpath.iterdir() if x.is_dir() ]
|
||||||
else:
|
if target_drive in drives: # If target drive is found, use it.
|
||||||
for drive in drives:
|
target_drive_found = True
|
||||||
try:
|
upload_disk = mpath / target_drive
|
||||||
files = os.listdir(os.path.join(os.sep, 'media', getpass.getuser(), drive))
|
else:
|
||||||
except:
|
for drive in drives:
|
||||||
continue
|
try:
|
||||||
else:
|
fpath = mpath / drive
|
||||||
if target_filename in files:
|
filenames = [ x.name for x in fpath.iterdir() if x.is_file() ]
|
||||||
upload_disk = os.path.join(os.sep, 'media', getpass.getuser(), drive) + os.sep
|
except:
|
||||||
target_file_found = True
|
continue
|
||||||
break
|
else:
|
||||||
#
|
if target_filename in filenames:
|
||||||
# set upload_port to drive if found
|
upload_disk = mpath / drive
|
||||||
#
|
target_file_found = True
|
||||||
|
break
|
||||||
|
#
|
||||||
|
# set upload_port to drive if found
|
||||||
|
#
|
||||||
|
|
||||||
if target_file_found or target_drive_found:
|
if target_file_found or target_drive_found:
|
||||||
env.Replace(
|
env.Replace(
|
||||||
UPLOAD_FLAGS="-P$UPLOAD_PORT"
|
UPLOAD_FLAGS="-P$UPLOAD_PORT"
|
||||||
)
|
)
|
||||||
|
|
||||||
elif current_OS == 'Darwin': # MAC
|
elif current_OS == 'Darwin': # MAC
|
||||||
#
|
#
|
||||||
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
|
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
|
||||||
#
|
#
|
||||||
drives = os.listdir('/Volumes') # human readable names
|
dpath = Path('/Volumes') # human readable names
|
||||||
if target_drive in drives and not target_file_found: # set upload if not found target file yet
|
drives = [ x for x in dpath.iterdir() if x.is_dir() ]
|
||||||
target_drive_found = True
|
if target_drive in drives and not target_file_found: # set upload if not found target file yet
|
||||||
upload_disk = '/Volumes/' + target_drive + '/'
|
target_drive_found = True
|
||||||
for drive in drives:
|
upload_disk = dpath / target_drive
|
||||||
try:
|
for drive in drives:
|
||||||
filenames = os.listdir('/Volumes/' + drive + '/') # will get an error if the drive is protected
|
try:
|
||||||
except:
|
fpath = dpath / drive # will get an error if the drive is protected
|
||||||
continue
|
filenames = [ x.name for x in fpath.iterdir() if x.is_file() ]
|
||||||
else:
|
except:
|
||||||
if target_filename in filenames:
|
continue
|
||||||
if not target_file_found:
|
else:
|
||||||
upload_disk = '/Volumes/' + drive + '/'
|
if target_filename in filenames:
|
||||||
target_file_found = True
|
upload_disk = dpath / drive
|
||||||
|
target_file_found = True
|
||||||
|
break
|
||||||
|
|
||||||
#
|
#
|
||||||
# Set upload_port to drive if found
|
# Set upload_port to drive if found
|
||||||
#
|
#
|
||||||
if target_file_found or target_drive_found:
|
if target_file_found or target_drive_found:
|
||||||
env.Replace(UPLOAD_PORT=upload_disk)
|
env.Replace(UPLOAD_PORT=str(upload_disk))
|
||||||
print('\nUpload disk: ', upload_disk, '\n')
|
print('\nUpload disk: ', upload_disk, '\n')
|
||||||
else:
|
else:
|
||||||
print_error('Autodetect Error')
|
print_error('Autodetect Error')
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print_error(str(e))
|
print_error(str(e))
|
||||||
|
|
||||||
env.AddPreAction("upload", before_upload)
|
env.AddPreAction("upload", before_upload)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
*
|
*
|
||||||
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
|
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
|
||||||
*
|
*
|
||||||
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
* Why double up on these macros? see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/// Read a pin
|
/// Read a pin
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ enum XPTCoordinate : uint8_t {
|
|||||||
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
|
XPT2046_Z2 = 0x40 | XPT2046_CONTROL | XPT2046_DFR_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if !defined(XPT2046_Z1_THRESHOLD)
|
#ifndef XPT2046_Z1_THRESHOLD
|
||||||
#define XPT2046_Z1_THRESHOLD 10
|
#define XPT2046_Z1_THRESHOLD 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -598,7 +598,7 @@ void MarlinHAL::dma_init() {
|
|||||||
void MarlinHAL::init() {
|
void MarlinHAL::init() {
|
||||||
TERN_(DMA_IS_REQUIRED, dma_init());
|
TERN_(DMA_IS_REQUIRED, dma_init());
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
#if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT)
|
#if HAS_SD_DETECT && SD_CONNECTION_IS(ONBOARD)
|
||||||
SET_INPUT_PULLUP(SD_DETECT_PIN);
|
SET_INPUT_PULLUP(SD_DETECT_PIN);
|
||||||
#endif
|
#endif
|
||||||
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
|
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ HAL_SERVO_TIMER_ISR() {
|
|||||||
;
|
;
|
||||||
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
|
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
|
||||||
|
|
||||||
if (currentServoIndex[timer] < 0) {
|
int8_t cho = currentServoIndex[timer]; // Handle the prior servo first
|
||||||
|
if (cho < 0) { // Servo -1 indicates the refresh interval completed...
|
||||||
#if defined(_useTimer1) && defined(_useTimer2)
|
#if defined(_useTimer1) && defined(_useTimer2)
|
||||||
if (currentServoIndex[timer ^ 1] >= 0) {
|
if (currentServoIndex[timer ^ 1] >= 0) {
|
||||||
// Wait for both channels
|
// Wait for both channels
|
||||||
@@ -86,45 +87,37 @@ HAL_SERVO_TIMER_ISR() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL;
|
tc->COUNT16.COUNT.reg = TC_COUNTER_START_VAL; // ...so reset the timer
|
||||||
SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT);
|
SYNC(tc->COUNT16.SYNCBUSY.bit.COUNT);
|
||||||
}
|
}
|
||||||
else if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && SERVO(timer, currentServoIndex[timer]).Pin.isActive)
|
else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled?
|
||||||
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, LOW); // pulse this channel low if activated
|
digitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW
|
||||||
|
|
||||||
// Select the next servo controlled by this timer
|
currentServoIndex[timer] = ++cho; // go to the next channel (or 0)
|
||||||
currentServoIndex[timer]++;
|
if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) {
|
||||||
|
if (SERVO(timer, cho).Pin.isActive) // activated?
|
||||||
|
digitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH
|
||||||
|
|
||||||
if (SERVO_INDEX(timer, currentServoIndex[timer]) < ServoCount && currentServoIndex[timer] < SERVOS_PER_TIMER) {
|
tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)SERVO(timer, cho).ticks;
|
||||||
if (SERVO(timer, currentServoIndex[timer]).Pin.isActive) // check if activated
|
|
||||||
digitalWrite(SERVO(timer, currentServoIndex[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
|
|
||||||
|
|
||||||
tc->COUNT16.CC[tcChannel].reg = getTimerCount() - (uint16_t)SERVO(timer, currentServoIndex[timer]).ticks;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// finished all channels so wait for the refresh period to expire before starting over
|
// finished all channels so wait for the refresh period to expire before starting over
|
||||||
currentServoIndex[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
|
currentServoIndex[timer] = -1; // reset the timer COUNT.reg on the next call
|
||||||
|
const uint16_t cval = getTimerCount() - 256 / (SERVO_TIMER_PRESCALER), // allow 256 cycles to ensure the next CV not missed
|
||||||
const uint16_t tcCounterValue = getTimerCount();
|
ival = (TC_COUNTER_START_VAL) - (uint16_t)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed
|
||||||
|
tc->COUNT16.CC[tcChannel].reg = min(cval, ival);
|
||||||
if ((TC_COUNTER_START_VAL - tcCounterValue) + 4UL < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
|
|
||||||
tc->COUNT16.CC[tcChannel].reg = TC_COUNTER_START_VAL - (uint16_t)usToTicks(REFRESH_INTERVAL);
|
|
||||||
else
|
|
||||||
tc->COUNT16.CC[tcChannel].reg = (uint16_t)(tcCounterValue - 4UL); // at least REFRESH_INTERVAL has elapsed
|
|
||||||
}
|
}
|
||||||
if (tcChannel == 0) {
|
if (tcChannel == 0) {
|
||||||
SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);
|
SYNC(tc->COUNT16.SYNCBUSY.bit.CC0);
|
||||||
// Clear the interrupt
|
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0; // Clear the interrupt
|
||||||
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC0;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);
|
SYNC(tc->COUNT16.SYNCBUSY.bit.CC1);
|
||||||
// Clear the interrupt
|
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1; // Clear the interrupt
|
||||||
tc->COUNT16.INTFLAG.reg = TC_INTFLAG_MC1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void initISR(timer16_Sequence_t timer) {
|
void initISR(const timer16_Sequence_t timer) {
|
||||||
Tc * const tc = timer_config[SERVO_TC].pTc;
|
Tc * const tc = timer_config[SERVO_TC].pTc;
|
||||||
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
|
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
|
||||||
|
|
||||||
@@ -201,9 +194,9 @@ void initISR(timer16_Sequence_t timer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void finISR(timer16_Sequence_t timer) {
|
void finISR(const timer16_Sequence_t timer_index) {
|
||||||
Tc * const tc = timer_config[SERVO_TC].pTc;
|
Tc * const tc = timer_config[SERVO_TC].pTc;
|
||||||
const uint8_t tcChannel = TIMER_TCCHANNEL(timer);
|
const uint8_t tcChannel = TIMER_TCCHANNEL(timer_index);
|
||||||
|
|
||||||
// Disable the match channel interrupt request
|
// Disable the match channel interrupt request
|
||||||
tc->COUNT16.INTENCLR.reg = (tcChannel == 0) ? TC_INTENCLR_MC0 : TC_INTENCLR_MC1;
|
tc->COUNT16.INTENCLR.reg = (tcChannel == 0) ? TC_INTENCLR_MC0 : TC_INTENCLR_MC1;
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
||||||
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
||||||
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
|
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
|
||||||
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL)
|
#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
|
||||||
#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p)
|
#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p)
|
||||||
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1)
|
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1)
|
||||||
#define pwm_status(pin) digitalPinHasPWM(pin)
|
#define pwm_status(pin) digitalPinHasPWM(pin)
|
||||||
|
|||||||
@@ -27,3 +27,8 @@
|
|||||||
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
|
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
|
||||||
#define USE_SHARED_EEPROM 1
|
#define USE_SHARED_EEPROM 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Some STM32F4 boards may lose steps when saving to EEPROM during print (PR #17946)
|
||||||
|
#if defined(STM32F4xx) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0
|
||||||
|
#define PRINTCOUNTER_SYNC 1
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -37,11 +37,6 @@
|
|||||||
#error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation."
|
#error "SDCARD_EEPROM_EMULATION requires SDSUPPORT. Enable SDSUPPORT or choose another EEPROM emulation."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(STM32F4xx) && BOTH(PRINTCOUNTER, FLASH_EEPROM_EMULATION)
|
|
||||||
#warning "FLASH_EEPROM_EMULATION may cause long delays when writing and should not be used while printing."
|
|
||||||
#error "Disable PRINTCOUNTER or choose another EEPROM emulation."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(STM32F4xx) && ENABLED(FLASH_EEPROM_LEVELING)
|
#if !defined(STM32F4xx) && ENABLED(FLASH_EEPROM_LEVELING)
|
||||||
#error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware."
|
#error "FLASH_EEPROM_LEVELING is currently only supported on STM32F4 hardware."
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -102,17 +102,18 @@ const XrefInfo pin_xref[] PROGMEM = {
|
|||||||
#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
|
#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
|
||||||
#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
|
#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
|
||||||
#define PORT_NUM(P) ((P >> 4) & 0x0007)
|
#define PORT_NUM(P) ((P >> 4) & 0x0007)
|
||||||
#define PORT_ALPHA(P) ('A' + (P >> 4))
|
#define PORT_ALPHA(P) ('A' + (P >> 4))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translation of routines & variables used by pinsDebug.h
|
* Translation of routines & variables used by pinsDebug.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if PA0 >= NUM_DIGITAL_PINS
|
#if NUM_ANALOG_FIRST >= NUM_DIGITAL_PINS
|
||||||
#define HAS_HIGH_ANALOG_PINS 1
|
#define HAS_HIGH_ANALOG_PINS 1
|
||||||
#endif
|
#endif
|
||||||
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS)
|
#define NUM_ANALOG_LAST ((NUM_ANALOG_FIRST) + (NUM_ANALOG_INPUTS) - 1)
|
||||||
#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL)
|
#define NUMBER_PINS_TOTAL ((NUM_DIGITAL_PINS) + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS))
|
||||||
|
#define VALID_PIN(P) (WITHIN(P, 0, (NUM_DIGITAL_PINS) - 1) || TERN0(HAS_HIGH_ANALOG_PINS, WITHIN(P, NUM_ANALOG_FIRST, NUM_ANALOG_LAST)))
|
||||||
#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
|
#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
|
||||||
#define PRINT_PIN(Q)
|
#define PRINT_PIN(Q)
|
||||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
||||||
@@ -168,7 +169,7 @@ bool GET_PINMODE(const pin_t Ard_num) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int8_t digital_pin_to_analog_pin(const pin_t Ard_num) {
|
int8_t digital_pin_to_analog_pin(const pin_t Ard_num) {
|
||||||
if (WITHIN(Ard_num, NUM_ANALOG_FIRST, NUM_ANALOG_FIRST + NUM_ANALOG_INPUTS - 1))
|
if (WITHIN(Ard_num, NUM_ANALOG_FIRST, NUM_ANALOG_LAST))
|
||||||
return Ard_num - NUM_ANALOG_FIRST;
|
return Ard_num - NUM_ANALOG_FIRST;
|
||||||
|
|
||||||
const uint32_t ind = digitalPinToAnalogInput(Ard_num);
|
const uint32_t ind = digitalPinToAnalogInput(Ard_num);
|
||||||
@@ -206,8 +207,11 @@ void port_print(const pin_t Ard_num) {
|
|||||||
SERIAL_ECHO_SP(7);
|
SERIAL_ECHO_SP(7);
|
||||||
|
|
||||||
// Print number to be used with M42
|
// Print number to be used with M42
|
||||||
int calc_p = Ard_num % (NUM_DIGITAL_PINS + 1);
|
int calc_p = Ard_num;
|
||||||
if (Ard_num > NUM_DIGITAL_PINS && calc_p > 7) calc_p += 8;
|
if (Ard_num > NUM_DIGITAL_PINS) {
|
||||||
|
calc_p -= NUM_ANALOG_FIRST;
|
||||||
|
if (calc_p > 7) calc_p += 8;
|
||||||
|
}
|
||||||
SERIAL_ECHOPGM(" M42 P", calc_p);
|
SERIAL_ECHOPGM(" M42 P", calc_p);
|
||||||
SERIAL_CHAR(' ');
|
SERIAL_CHAR(' ');
|
||||||
if (calc_p < 100) {
|
if (calc_p < 100) {
|
||||||
|
|||||||
+348
-217
@@ -33,7 +33,6 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
// use local drivers
|
|
||||||
#if defined(STM32F103xE) || defined(STM32F103xG)
|
#if defined(STM32F103xE) || defined(STM32F103xG)
|
||||||
#include <stm32f1xx_hal_rcc_ex.h>
|
#include <stm32f1xx_hal_rcc_ex.h>
|
||||||
#include <stm32f1xx_hal_sd.h>
|
#include <stm32f1xx_hal_sd.h>
|
||||||
@@ -47,254 +46,397 @@
|
|||||||
#include <stm32f7xx_hal_dma.h>
|
#include <stm32f7xx_hal_dma.h>
|
||||||
#include <stm32f7xx_hal_gpio.h>
|
#include <stm32f7xx_hal_gpio.h>
|
||||||
#include <stm32f7xx_hal_sd.h>
|
#include <stm32f7xx_hal_sd.h>
|
||||||
|
#elif defined(STM32H7xx)
|
||||||
|
#define SDIO_FOR_STM32H7
|
||||||
|
#include <stm32h7xx_hal_rcc.h>
|
||||||
|
#include <stm32h7xx_hal_dma.h>
|
||||||
|
#include <stm32h7xx_hal_gpio.h>
|
||||||
|
#include <stm32h7xx_hal_sd.h>
|
||||||
#else
|
#else
|
||||||
#error "SDIO only supported with STM32F103xE, STM32F103xG, STM32F4xx, or STM32F7xx."
|
#error "SDIO is only supported with STM32F103xE, STM32F103xG, STM32F4xx, STM32F7xx, and STM32H7xx."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
SD_HandleTypeDef hsd; // create SDIO structure
|
// SDIO Max Clock (naming from STM Manual, don't change)
|
||||||
// F4 supports one DMA for RX and another for TX, but Marlin will never
|
#define SDIOCLK 48000000
|
||||||
// do read and write at same time, so we use the same DMA for both.
|
|
||||||
DMA_HandleTypeDef hdma_sdio;
|
|
||||||
|
|
||||||
/*
|
|
||||||
SDIO_INIT_CLK_DIV is 118
|
|
||||||
SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2)
|
|
||||||
SDIO init clock frequency should not exceed 400kHz = 48MHz / (118 + 2)
|
|
||||||
|
|
||||||
Default TRANSFER_CLOCK_DIV is 2 (118 / 40)
|
|
||||||
Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz
|
|
||||||
This might be too fast for stable SDIO operations
|
|
||||||
|
|
||||||
MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency
|
|
||||||
Additional testing is required as there are clearly some 4bit initialization problems
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef USBD_OK
|
|
||||||
#define USBD_OK 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Target Clock, configurable. Default is 18MHz, from STM32F1
|
// Target Clock, configurable. Default is 18MHz, from STM32F1
|
||||||
#ifndef SDIO_CLOCK
|
#ifndef SDIO_CLOCK
|
||||||
#define SDIO_CLOCK 18000000 // 18 MHz
|
#define SDIO_CLOCK 18000000 // 18 MHz
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// SDIO retries, configurable. Default is 3, from STM32F1
|
SD_HandleTypeDef hsd; // SDIO structure
|
||||||
#ifndef SDIO_READ_RETRIES
|
|
||||||
#define SDIO_READ_RETRIES 3
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// SDIO Max Clock (naming from STM Manual, don't change)
|
|
||||||
#define SDIOCLK 48000000
|
|
||||||
|
|
||||||
static uint32_t clock_to_divider(uint32_t clk) {
|
static uint32_t clock_to_divider(uint32_t clk) {
|
||||||
// limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals
|
#ifdef SDIO_FOR_STM32H7
|
||||||
// Also limited to no more than 48Mhz (SDIOCLK).
|
// SDMMC_CK frequency = sdmmc_ker_ck / [2 * CLKDIV].
|
||||||
const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
|
uint32_t sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
|
||||||
clk = min(clk, (uint32_t)(pclk2 * 8 / 3));
|
return sdmmc_clk / (2U * SDIO_CLOCK) + (sdmmc_clk % (2U * SDIO_CLOCK) != 0);
|
||||||
clk = min(clk, (uint32_t)SDIOCLK);
|
|
||||||
// Round up divider, so we don't run the card over the speed supported,
|
|
||||||
// and subtract by 2, because STM32 will add 2, as written in the manual:
|
|
||||||
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
|
|
||||||
return pclk2 / clk + (pclk2 % clk != 0) - 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void go_to_transfer_speed() {
|
|
||||||
/* Default SDIO peripheral configuration for SD card initialization */
|
|
||||||
hsd.Init.ClockEdge = hsd.Init.ClockEdge;
|
|
||||||
hsd.Init.ClockBypass = hsd.Init.ClockBypass;
|
|
||||||
hsd.Init.ClockPowerSave = hsd.Init.ClockPowerSave;
|
|
||||||
hsd.Init.BusWide = hsd.Init.BusWide;
|
|
||||||
hsd.Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
|
|
||||||
hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
|
|
||||||
|
|
||||||
/* Initialize SDIO peripheral interface with default configuration */
|
|
||||||
SDIO_Init(hsd.Instance, hsd.Init);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SD_LowLevel_Init(void) {
|
|
||||||
uint32_t tempreg;
|
|
||||||
|
|
||||||
__HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks
|
|
||||||
__HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks
|
|
||||||
|
|
||||||
GPIO_InitTypeDef GPIO_InitStruct;
|
|
||||||
|
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
||||||
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL;
|
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
|
||||||
|
|
||||||
#if DISABLED(STM32F1xx)
|
|
||||||
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK
|
|
||||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // define D1-D3 only if have a four bit wide SDIO bus
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3
|
|
||||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Configure PD.02 CMD line
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
|
||||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
// Setup DMA
|
|
||||||
#if defined(STM32F1xx)
|
|
||||||
hdma_sdio.Init.Mode = DMA_NORMAL;
|
|
||||||
hdma_sdio.Instance = DMA2_Channel4;
|
|
||||||
HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
|
|
||||||
#elif defined(STM32F4xx)
|
|
||||||
hdma_sdio.Init.Mode = DMA_PFCTRL;
|
|
||||||
hdma_sdio.Instance = DMA2_Stream3;
|
|
||||||
hdma_sdio.Init.Channel = DMA_CHANNEL_4;
|
|
||||||
hdma_sdio.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
|
||||||
hdma_sdio.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
|
||||||
hdma_sdio.Init.MemBurst = DMA_MBURST_INC4;
|
|
||||||
hdma_sdio.Init.PeriphBurst = DMA_PBURST_INC4;
|
|
||||||
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
|
||||||
#endif
|
|
||||||
HAL_NVIC_EnableIRQ(SDIO_IRQn);
|
|
||||||
hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
|
|
||||||
hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
|
|
||||||
hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
|
||||||
hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
|
||||||
hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
|
|
||||||
__HAL_LINKDMA(&hsd, hdmarx, hdma_sdio);
|
|
||||||
__HAL_LINKDMA(&hsd, hdmatx, hdma_sdio);
|
|
||||||
|
|
||||||
#if defined(STM32F1xx)
|
|
||||||
__HAL_RCC_SDIO_CLK_ENABLE();
|
|
||||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
|
||||||
#else
|
#else
|
||||||
__HAL_RCC_SDIO_FORCE_RESET();
|
// limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals
|
||||||
delay(2);
|
// Also limited to no more than 48Mhz (SDIOCLK).
|
||||||
__HAL_RCC_SDIO_RELEASE_RESET();
|
const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
|
||||||
delay(2);
|
clk = min(clk, (uint32_t)(pclk2 * 8 / 3));
|
||||||
__HAL_RCC_SDIO_CLK_ENABLE();
|
clk = min(clk, (uint32_t)SDIOCLK);
|
||||||
|
// Round up divider, so we don't run the card over the speed supported,
|
||||||
__HAL_RCC_DMA2_FORCE_RESET();
|
// and subtract by 2, because STM32 will add 2, as written in the manual:
|
||||||
delay(2);
|
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
|
||||||
__HAL_RCC_DMA2_RELEASE_RESET();
|
return pclk2 / clk + (pclk2 % clk != 0) - 2;
|
||||||
delay(2);
|
|
||||||
__HAL_RCC_DMA2_CLK_ENABLE();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Initialize the SDIO (with initial <400Khz Clock)
|
|
||||||
tempreg = 0; //Reset value
|
|
||||||
tempreg |= SDIO_CLKCR_CLKEN; // Clock enabled
|
|
||||||
tempreg |= SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
|
|
||||||
// Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable
|
|
||||||
SDIO->CLKCR = tempreg;
|
|
||||||
|
|
||||||
// Power up the SDIO
|
|
||||||
SDIO_PowerState_ON(SDIO);
|
|
||||||
hsd.Instance = SDIO;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
|
// Start the SDIO clock
|
||||||
UNUSED(hsd); // Prevent unused argument(s) compilation warning
|
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
|
||||||
__HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock
|
UNUSED(hsd);
|
||||||
|
#ifdef SDIO_FOR_STM32H7
|
||||||
|
pinmap_pinout(PC_12, PinMap_SD);
|
||||||
|
pinmap_pinout(PD_2, PinMap_SD);
|
||||||
|
pinmap_pinout(PC_8, PinMap_SD);
|
||||||
|
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // Define D1-D3 only for 4-bit wide SDIO bus
|
||||||
|
pinmap_pinout(PC_9, PinMap_SD);
|
||||||
|
pinmap_pinout(PC_10, PinMap_SD);
|
||||||
|
pinmap_pinout(PC_11, PinMap_SD);
|
||||||
|
#endif
|
||||||
|
__HAL_RCC_SDMMC1_CLK_ENABLE();
|
||||||
|
HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
|
||||||
|
#else
|
||||||
|
__HAL_RCC_SDIO_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDIO_Init() {
|
#ifdef SDIO_FOR_STM32H7
|
||||||
uint8_t retryCnt = SDIO_READ_RETRIES;
|
|
||||||
|
|
||||||
bool status;
|
#define SD_TIMEOUT 1000 // ms
|
||||||
hsd.Instance = SDIO;
|
|
||||||
hsd.State = HAL_SD_STATE_RESET;
|
|
||||||
|
|
||||||
SD_LowLevel_Init();
|
extern "C" void SDMMC1_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); }
|
||||||
|
|
||||||
uint8_t retry_Cnt = retryCnt;
|
uint8_t waitingRxCplt = 0, waitingTxCplt = 0;
|
||||||
for (;;) {
|
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsdio) { waitingTxCplt = 0; }
|
||||||
hal.watchdog_refresh();
|
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsdio) { waitingRxCplt = 0; }
|
||||||
status = (bool) HAL_SD_Init(&hsd);
|
|
||||||
if (!status) break;
|
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
|
||||||
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
|
__HAL_RCC_SDMMC1_FORCE_RESET(); delay(10);
|
||||||
|
__HAL_RCC_SDMMC1_RELEASE_RESET(); delay(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
go_to_transfer_speed();
|
bool SDIO_Init() {
|
||||||
|
HAL_StatusTypeDef sd_state = HAL_OK;
|
||||||
|
if (hsd.Instance == SDMMC1) HAL_SD_DeInit(&hsd);
|
||||||
|
|
||||||
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // go to 4 bit wide mode if pins are defined
|
// HAL SD initialization
|
||||||
retry_Cnt = retryCnt;
|
hsd.Instance = SDMMC1;
|
||||||
|
hsd.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
|
||||||
|
hsd.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
|
||||||
|
hsd.Init.BusWide = SDMMC_BUS_WIDE_1B;
|
||||||
|
hsd.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
|
||||||
|
hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
|
||||||
|
sd_state = HAL_SD_Init(&hsd);
|
||||||
|
|
||||||
|
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3)
|
||||||
|
if (sd_state == HAL_OK)
|
||||||
|
sd_state = HAL_SD_ConfigWideBusOperation(&hsd, SDMMC_BUS_WIDE_4B);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (sd_state == HAL_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // !SDIO_FOR_STM32H7
|
||||||
|
|
||||||
|
#define SD_TIMEOUT 500 // ms
|
||||||
|
|
||||||
|
// SDIO retries, configurable. Default is 3, from STM32F1
|
||||||
|
#ifndef SDIO_READ_RETRIES
|
||||||
|
#define SDIO_READ_RETRIES 3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// F4 supports one DMA for RX and another for TX, but Marlin will never
|
||||||
|
// do read and write at same time, so we use the same DMA for both.
|
||||||
|
DMA_HandleTypeDef hdma_sdio;
|
||||||
|
|
||||||
|
#ifdef STM32F1xx
|
||||||
|
#define DMA_IRQ_HANDLER DMA2_Channel4_5_IRQHandler
|
||||||
|
#elif defined(STM32F4xx)
|
||||||
|
#define DMA_IRQ_HANDLER DMA2_Stream3_IRQHandler
|
||||||
|
#else
|
||||||
|
#error "Unknown STM32 architecture."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern "C" void SDIO_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); }
|
||||||
|
extern "C" void DMA_IRQ_HANDLER(void) { HAL_DMA_IRQHandler(&hdma_sdio); }
|
||||||
|
|
||||||
|
/*
|
||||||
|
SDIO_INIT_CLK_DIV is 118
|
||||||
|
SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2)
|
||||||
|
SDIO init clock frequency should not exceed 400kHz = 48MHz / (118 + 2)
|
||||||
|
|
||||||
|
Default TRANSFER_CLOCK_DIV is 2 (118 / 40)
|
||||||
|
Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz
|
||||||
|
This might be too fast for stable SDIO operations
|
||||||
|
|
||||||
|
MKS Robin SDIO seems stable with BusWide 1bit and ClockDiv 8 (i.e., 4.8MHz SDIO clock frequency)
|
||||||
|
More testing is required as there are clearly some 4bit init problems.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void go_to_transfer_speed() {
|
||||||
|
/* Default SDIO peripheral configuration for SD card initialization */
|
||||||
|
hsd.Init.ClockEdge = hsd.Init.ClockEdge;
|
||||||
|
hsd.Init.ClockBypass = hsd.Init.ClockBypass;
|
||||||
|
hsd.Init.ClockPowerSave = hsd.Init.ClockPowerSave;
|
||||||
|
hsd.Init.BusWide = hsd.Init.BusWide;
|
||||||
|
hsd.Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
|
||||||
|
hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
|
||||||
|
|
||||||
|
/* Initialize SDIO peripheral interface with default configuration */
|
||||||
|
SDIO_Init(hsd.Instance, hsd.Init);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SD_LowLevel_Init() {
|
||||||
|
uint32_t tempreg;
|
||||||
|
|
||||||
|
// Enable GPIO clocks
|
||||||
|
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||||
|
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||||
|
|
||||||
|
GPIO_InitTypeDef GPIO_InitStruct;
|
||||||
|
|
||||||
|
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
||||||
|
GPIO_InitStruct.Pull = 1; // GPIO_NOPULL
|
||||||
|
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||||
|
|
||||||
|
#if DISABLED(STM32F1xx)
|
||||||
|
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK
|
||||||
|
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // define D1-D3 only if have a four bit wide SDIO bus
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3
|
||||||
|
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Configure PD.02 CMD line
|
||||||
|
GPIO_InitStruct.Pin = GPIO_PIN_2;
|
||||||
|
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
||||||
|
|
||||||
|
// Setup DMA
|
||||||
|
#ifdef STM32F1xx
|
||||||
|
hdma_sdio.Init.Mode = DMA_NORMAL;
|
||||||
|
hdma_sdio.Instance = DMA2_Channel4;
|
||||||
|
HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
|
||||||
|
#elif defined(STM32F4xx)
|
||||||
|
hdma_sdio.Init.Mode = DMA_PFCTRL;
|
||||||
|
hdma_sdio.Instance = DMA2_Stream3;
|
||||||
|
hdma_sdio.Init.Channel = DMA_CHANNEL_4;
|
||||||
|
hdma_sdio.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
|
||||||
|
hdma_sdio.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
|
||||||
|
hdma_sdio.Init.MemBurst = DMA_MBURST_INC4;
|
||||||
|
hdma_sdio.Init.PeriphBurst = DMA_PBURST_INC4;
|
||||||
|
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
|
||||||
|
#endif
|
||||||
|
HAL_NVIC_EnableIRQ(SDIO_IRQn);
|
||||||
|
hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
|
||||||
|
hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
|
||||||
|
hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
|
||||||
|
hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
|
||||||
|
hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
|
||||||
|
__HAL_LINKDMA(&hsd, hdmarx, hdma_sdio);
|
||||||
|
__HAL_LINKDMA(&hsd, hdmatx, hdma_sdio);
|
||||||
|
|
||||||
|
#ifdef STM32F1xx
|
||||||
|
__HAL_RCC_SDIO_CLK_ENABLE();
|
||||||
|
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||||
|
#else
|
||||||
|
__HAL_RCC_SDIO_FORCE_RESET(); delay(2);
|
||||||
|
__HAL_RCC_SDIO_RELEASE_RESET(); delay(2);
|
||||||
|
__HAL_RCC_SDIO_CLK_ENABLE();
|
||||||
|
|
||||||
|
__HAL_RCC_DMA2_FORCE_RESET(); delay(2);
|
||||||
|
__HAL_RCC_DMA2_RELEASE_RESET(); delay(2);
|
||||||
|
__HAL_RCC_DMA2_CLK_ENABLE();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialize the SDIO (with initial <400Khz Clock)
|
||||||
|
tempreg = 0 // Reset value
|
||||||
|
| SDIO_CLKCR_CLKEN // Clock enabled
|
||||||
|
| SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
|
||||||
|
// Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable
|
||||||
|
SDIO->CLKCR = tempreg;
|
||||||
|
|
||||||
|
// Power up the SDIO
|
||||||
|
SDIO_PowerState_ON(SDIO);
|
||||||
|
hsd.Instance = SDIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SDIO_Init() {
|
||||||
|
uint8_t retryCnt = SDIO_READ_RETRIES;
|
||||||
|
|
||||||
|
bool status;
|
||||||
|
hsd.Instance = SDIO;
|
||||||
|
hsd.State = HAL_SD_STATE_RESET;
|
||||||
|
|
||||||
|
SD_LowLevel_Init();
|
||||||
|
|
||||||
|
uint8_t retry_Cnt = retryCnt;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
hal.watchdog_refresh();
|
hal.watchdog_refresh();
|
||||||
if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required
|
status = (bool) HAL_SD_Init(&hsd);
|
||||||
if (!--retry_Cnt) break;
|
if (!status) break;
|
||||||
|
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
|
||||||
}
|
}
|
||||||
if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode
|
|
||||||
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
|
go_to_transfer_speed();
|
||||||
SD_LowLevel_Init();
|
|
||||||
|
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // go to 4 bit wide mode if pins are defined
|
||||||
retry_Cnt = retryCnt;
|
retry_Cnt = retryCnt;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
hal.watchdog_refresh();
|
hal.watchdog_refresh();
|
||||||
status = (bool) HAL_SD_Init(&hsd);
|
if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required
|
||||||
if (!status) break;
|
if (!--retry_Cnt) break;
|
||||||
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
|
|
||||||
}
|
}
|
||||||
go_to_transfer_speed();
|
if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode
|
||||||
|
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
|
||||||
|
SD_LowLevel_Init();
|
||||||
|
retry_Cnt = retryCnt;
|
||||||
|
for (;;) {
|
||||||
|
hal.watchdog_refresh();
|
||||||
|
status = (bool) HAL_SD_Init(&hsd);
|
||||||
|
if (!status) break;
|
||||||
|
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
|
||||||
|
}
|
||||||
|
go_to_transfer_speed();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read or Write a block
|
||||||
|
* @details Read or Write a block with SDIO
|
||||||
|
*
|
||||||
|
* @param block The block index
|
||||||
|
* @param src The data buffer source for a write
|
||||||
|
* @param dst The data buffer destination for a read
|
||||||
|
*
|
||||||
|
* @return true on success
|
||||||
|
*/
|
||||||
|
static bool SDIO_ReadWriteBlock_DMA(uint32_t block, const uint8_t *src, uint8_t *dst) {
|
||||||
|
if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false;
|
||||||
|
|
||||||
|
hal.watchdog_refresh();
|
||||||
|
|
||||||
|
HAL_StatusTypeDef ret;
|
||||||
|
if (src) {
|
||||||
|
hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
||||||
|
HAL_DMA_Init(&hdma_sdio);
|
||||||
|
ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*)src, block, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
||||||
|
HAL_DMA_Init(&hdma_sdio);
|
||||||
|
ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*)dst, block, 1);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
if (ret != HAL_OK) {
|
||||||
}
|
|
||||||
|
|
||||||
static bool SDIO_ReadWriteBlock_DMA(uint32_t block, const uint8_t *src, uint8_t *dst) {
|
|
||||||
if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false;
|
|
||||||
|
|
||||||
hal.watchdog_refresh();
|
|
||||||
|
|
||||||
HAL_StatusTypeDef ret;
|
|
||||||
if (src) {
|
|
||||||
hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
|
|
||||||
HAL_DMA_Init(&hdma_sdio);
|
|
||||||
ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
|
|
||||||
HAL_DMA_Init(&hdma_sdio);
|
|
||||||
ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ret != HAL_OK) {
|
|
||||||
HAL_DMA_Abort_IT(&hdma_sdio);
|
|
||||||
HAL_DMA_DeInit(&hdma_sdio);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
millis_t timeout = millis() + 500;
|
|
||||||
// Wait the transfer
|
|
||||||
while (hsd.State != HAL_SD_STATE_READY) {
|
|
||||||
if (ELAPSED(millis(), timeout)) {
|
|
||||||
HAL_DMA_Abort_IT(&hdma_sdio);
|
HAL_DMA_Abort_IT(&hdma_sdio);
|
||||||
HAL_DMA_DeInit(&hdma_sdio);
|
HAL_DMA_DeInit(&hdma_sdio);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
millis_t timeout = millis() + SD_TIMEOUT;
|
||||||
|
// Wait the transfer
|
||||||
|
while (hsd.State != HAL_SD_STATE_READY) {
|
||||||
|
if (ELAPSED(millis(), timeout)) {
|
||||||
|
HAL_DMA_Abort_IT(&hdma_sdio);
|
||||||
|
HAL_DMA_DeInit(&hdma_sdio);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0
|
||||||
|
|| __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ }
|
||||||
|
|
||||||
|
HAL_DMA_Abort_IT(&hdma_sdio);
|
||||||
|
HAL_DMA_DeInit(&hdma_sdio);
|
||||||
|
|
||||||
|
timeout = millis() + SD_TIMEOUT;
|
||||||
|
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (ELAPSED(millis(), timeout)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0
|
#endif // !SDIO_FOR_STM32H7
|
||||||
|| __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ }
|
|
||||||
|
|
||||||
HAL_DMA_Abort_IT(&hdma_sdio);
|
|
||||||
HAL_DMA_DeInit(&hdma_sdio);
|
|
||||||
|
|
||||||
timeout = millis() + 500;
|
|
||||||
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (ELAPSED(millis(), timeout)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a block
|
||||||
|
* @details Read a block from media with SDIO
|
||||||
|
*
|
||||||
|
* @param block The block index
|
||||||
|
* @param src The block buffer
|
||||||
|
*
|
||||||
|
* @return true on success
|
||||||
|
*/
|
||||||
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
|
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
|
||||||
uint8_t retries = SDIO_READ_RETRIES;
|
#ifdef SDIO_FOR_STM32H7
|
||||||
while (retries--) if (SDIO_ReadWriteBlock_DMA(block, nullptr, dst)) return true;
|
|
||||||
return false;
|
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
|
||||||
|
|
||||||
|
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
|
||||||
|
if (HAL_GetTick() >= timeout) return false;
|
||||||
|
|
||||||
|
waitingRxCplt = 1;
|
||||||
|
if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t*)dst, block, 1) != HAL_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
timeout = HAL_GetTick() + SD_TIMEOUT;
|
||||||
|
while (waitingRxCplt)
|
||||||
|
if (HAL_GetTick() >= timeout) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
uint8_t retries = SDIO_READ_RETRIES;
|
||||||
|
while (retries--) if (SDIO_ReadWriteBlock_DMA(block, nullptr, dst)) return true;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Write a block
|
||||||
|
* @details Write a block to media with SDIO
|
||||||
|
*
|
||||||
|
* @param block The block index
|
||||||
|
* @param src The block data
|
||||||
|
*
|
||||||
|
* @return true on success
|
||||||
|
*/
|
||||||
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
|
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
|
||||||
uint8_t retries = SDIO_READ_RETRIES;
|
#ifdef SDIO_FOR_STM32H7
|
||||||
while (retries--) if (SDIO_ReadWriteBlock_DMA(block, src, nullptr)) return true;
|
|
||||||
return false;
|
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
|
||||||
|
|
||||||
|
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
|
||||||
|
if (HAL_GetTick() >= timeout) return false;
|
||||||
|
|
||||||
|
waitingTxCplt = 1;
|
||||||
|
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t*)src, block, 1) != HAL_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
timeout = HAL_GetTick() + SD_TIMEOUT;
|
||||||
|
while (waitingTxCplt)
|
||||||
|
if (HAL_GetTick() >= timeout) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
uint8_t retries = SDIO_READ_RETRIES;
|
||||||
|
while (retries--) if (SDIO_ReadWriteBlock_DMA(block, src, nullptr)) return true;
|
||||||
|
return false;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDIO_IsReady() {
|
bool SDIO_IsReady() {
|
||||||
@@ -305,16 +447,5 @@ uint32_t SDIO_GetCardSize() {
|
|||||||
return (uint32_t)(hsd.SdCard.BlockNbr) * (hsd.SdCard.BlockSize);
|
return (uint32_t)(hsd.SdCard.BlockNbr) * (hsd.SdCard.BlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(STM32F1xx)
|
|
||||||
#define DMA_IRQ_HANDLER DMA2_Channel4_5_IRQHandler
|
|
||||||
#elif defined(STM32F4xx)
|
|
||||||
#define DMA_IRQ_HANDLER DMA2_Stream3_IRQHandler
|
|
||||||
#else
|
|
||||||
#error "Unknown STM32 architecture."
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C" void SDIO_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); }
|
|
||||||
extern "C" void DMA_IRQ_HANDLER(void) { HAL_DMA_IRQHandler(&hdma_sdio); }
|
|
||||||
|
|
||||||
#endif // SDIO_SUPPORT
|
#endif // SDIO_SUPPORT
|
||||||
#endif // HAL_STM32
|
#endif // HAL_STM32
|
||||||
|
|||||||
@@ -159,24 +159,28 @@ void GT911::read_reg(uint16_t reg, uint8_t reg_len, uint8_t* r_data, uint8_t r_l
|
|||||||
void GT911::Init() {
|
void GT911::Init() {
|
||||||
OUT_WRITE(GT911_RST_PIN, LOW);
|
OUT_WRITE(GT911_RST_PIN, LOW);
|
||||||
OUT_WRITE(GT911_INT_PIN, LOW);
|
OUT_WRITE(GT911_INT_PIN, LOW);
|
||||||
delay(20);
|
delay(11);
|
||||||
|
WRITE(GT911_INT_PIN, HIGH);
|
||||||
|
delayMicroseconds(110);
|
||||||
WRITE(GT911_RST_PIN, HIGH);
|
WRITE(GT911_RST_PIN, HIGH);
|
||||||
|
delay(6);
|
||||||
|
WRITE(GT911_INT_PIN, LOW);
|
||||||
|
delay(55);
|
||||||
SET_INPUT(GT911_INT_PIN);
|
SET_INPUT(GT911_INT_PIN);
|
||||||
|
|
||||||
sw_iic.init();
|
sw_iic.init();
|
||||||
|
|
||||||
uint8_t clear_reg = 0x0000;
|
uint8_t clear_reg = 0x00;
|
||||||
write_reg(0x814E, 2, &clear_reg, 2); // Reset to 0 for start
|
write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GT911::getFirstTouchPoint(int16_t *x, int16_t *y) {
|
bool GT911::getFirstTouchPoint(int16_t *x, int16_t *y) {
|
||||||
read_reg(0x814E, 2, ®.REG.status, 1);
|
read_reg(0x814E, 2, ®.REG.status, 1);
|
||||||
|
|
||||||
if (reg.REG.status & 0x80) {
|
if (reg.REG.status >= 0x80 && reg.REG.status <= 0x85) {
|
||||||
|
read_reg(0x8150, 2, reg.map + 2, 38);
|
||||||
uint8_t clear_reg = 0x00;
|
uint8_t clear_reg = 0x00;
|
||||||
write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start
|
write_reg(0x814E, 2, &clear_reg, 1); // Reset to 0 for start
|
||||||
read_reg(0x8150, 2, reg.map + 2, 8 * (reg.REG.status & 0x0F));
|
|
||||||
|
|
||||||
// First touch point
|
// First touch point
|
||||||
*x = ((reg.REG.point[0].xh & 0x0F) << 8) | reg.REG.point[0].xl;
|
*x = ((reg.REG.point[0].xh & 0x0F) << 8) | reg.REG.point[0].xl;
|
||||||
*y = ((reg.REG.point[0].yh & 0x0F) << 8) | reg.REG.point[0].yl;
|
*y = ((reg.REG.point[0].yh & 0x0F) << 8) | reg.REG.point[0].yl;
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
|
|
||||||
#include "../../../inc/MarlinConfig.h"
|
#include "../../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
#define GT911_SLAVE_ADDRESS 0xBA
|
#define GT911_SLAVE_ADDRESS 0x28
|
||||||
|
|
||||||
#if !PIN_EXISTS(GT911_RST)
|
#if !PIN_EXISTS(GT911_RST)
|
||||||
#error "GT911_RST_PIN is not defined."
|
#error "GT911_RST_PIN is not defined."
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ uint32_t TFT_FSMC::ReadID(tft_data_t Reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TFT_FSMC::isBusy() {
|
bool TFT_FSMC::isBusy() {
|
||||||
#if defined(STM32F1xx)
|
#ifdef STM32F1xx
|
||||||
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
|
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
|
||||||
#elif defined(STM32F4xx)
|
#elif defined(STM32F4xx)
|
||||||
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
|
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
|
||||||
|
|||||||
@@ -372,9 +372,9 @@ void TFT_LTDC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Cou
|
|||||||
if (MemoryIncrease == DMA_PINC_ENABLE) {
|
if (MemoryIncrease == DMA_PINC_ENABLE) {
|
||||||
DrawImage(x_min, y_cur, x_min + width, y_cur + height, Data);
|
DrawImage(x_min, y_cur, x_min + width, y_cur + height, Data);
|
||||||
Data += width * height;
|
Data += width * height;
|
||||||
} else {
|
|
||||||
DrawRect(x_min, y_cur, x_min + width, y_cur + height, *Data);
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
DrawRect(x_min, y_cur, x_min + width, y_cur + height, *Data);
|
||||||
y_cur += height;
|
y_cur += height;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool TFT_SPI::isBusy() {
|
bool TFT_SPI::isBusy() {
|
||||||
#if defined(STM32F1xx)
|
#ifdef STM32F1xx
|
||||||
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
|
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
|
||||||
#elif defined(STM32F4xx)
|
#elif defined(STM32F4xx)
|
||||||
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
|
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
|
||||||
|
|||||||
@@ -147,17 +147,17 @@ void libServo::move(const int32_t value) {
|
|||||||
uint16_t SR = timer_get_status(tdev);
|
uint16_t SR = timer_get_status(tdev);
|
||||||
if (SR & TIMER_SR_CC1IF) { // channel 1 off
|
if (SR & TIMER_SR_CC1IF) { // channel 1 off
|
||||||
#ifdef SERVO0_PWM_OD
|
#ifdef SERVO0_PWM_OD
|
||||||
OUT_WRITE_OD(SERVO0_PIN, 1); // off
|
OUT_WRITE_OD(SERVO0_PIN, HIGH); // off
|
||||||
#else
|
#else
|
||||||
OUT_WRITE(SERVO0_PIN, 0);
|
OUT_WRITE(SERVO0_PIN, LOW);
|
||||||
#endif
|
#endif
|
||||||
timer_reset_status_bit(tdev, TIMER_SR_CC1IF_BIT);
|
timer_reset_status_bit(tdev, TIMER_SR_CC1IF_BIT);
|
||||||
}
|
}
|
||||||
if (SR & TIMER_SR_CC2IF) { // channel 2 resume
|
if (SR & TIMER_SR_CC2IF) { // channel 2 resume
|
||||||
#ifdef SERVO0_PWM_OD
|
#ifdef SERVO0_PWM_OD
|
||||||
OUT_WRITE_OD(SERVO0_PIN, 0); // on
|
OUT_WRITE_OD(SERVO0_PIN, LOW); // on
|
||||||
#else
|
#else
|
||||||
OUT_WRITE(SERVO0_PIN, 1);
|
OUT_WRITE(SERVO0_PIN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
timer_reset_status_bit(tdev, TIMER_SR_CC2IF_BIT);
|
timer_reset_status_bit(tdev, TIMER_SR_CC2IF_BIT);
|
||||||
}
|
}
|
||||||
@@ -167,9 +167,9 @@ void libServo::move(const int32_t value) {
|
|||||||
timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0);
|
timer_dev *tdev = HAL_get_timer_dev(MF_TIMER_SERVO0);
|
||||||
if (!tdev) return false;
|
if (!tdev) return false;
|
||||||
#ifdef SERVO0_PWM_OD
|
#ifdef SERVO0_PWM_OD
|
||||||
OUT_WRITE_OD(inPin, 1);
|
OUT_WRITE_OD(inPin, HIGH);
|
||||||
#else
|
#else
|
||||||
OUT_WRITE(inPin, 0);
|
OUT_WRITE(inPin, LOW);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
timer_pause(tdev);
|
timer_pause(tdev);
|
||||||
@@ -200,9 +200,9 @@ void libServo::move(const int32_t value) {
|
|||||||
timer_disable_irq(tdev, 1);
|
timer_disable_irq(tdev, 1);
|
||||||
timer_disable_irq(tdev, 2);
|
timer_disable_irq(tdev, 2);
|
||||||
#ifdef SERVO0_PWM_OD
|
#ifdef SERVO0_PWM_OD
|
||||||
OUT_WRITE_OD(pin, 1); // off
|
OUT_WRITE_OD(pin, HIGH); // off
|
||||||
#else
|
#else
|
||||||
OUT_WRITE(pin, 0);
|
OUT_WRITE(pin, LOW);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
||||||
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
||||||
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
|
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
|
||||||
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0)
|
#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
|
||||||
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
|
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
|
||||||
#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17))
|
#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17))
|
||||||
#define pwm_status(pin) HAL_pwm_status(pin)
|
#define pwm_status(pin) HAL_pwm_status(pin)
|
||||||
|
|||||||
@@ -1,139 +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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Software L6470 SPI functions originally from Arduino Sd2Card Library
|
|
||||||
* Copyright (c) 2009 by William Greiman
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
|
||||||
|
|
||||||
#if HAS_L64XX
|
|
||||||
|
|
||||||
#include "Delay.h"
|
|
||||||
|
|
||||||
#include "../../core/serial.h"
|
|
||||||
#include "../../libs/L64XX/L64XX_Marlin.h"
|
|
||||||
|
|
||||||
// Make sure GCC optimizes this file.
|
|
||||||
// Note that this line triggers a bug in GCC which is fixed by casting.
|
|
||||||
// See the note below.
|
|
||||||
#pragma GCC optimize (3)
|
|
||||||
|
|
||||||
// run at ~4Mhz
|
|
||||||
inline uint8_t L6470_SpiTransfer_Mode_0(uint8_t b) { // using Mode 0
|
|
||||||
for (uint8_t bits = 8; bits--;) {
|
|
||||||
WRITE(L6470_CHAIN_MOSI_PIN, b & 0x80);
|
|
||||||
b <<= 1; // little setup time
|
|
||||||
|
|
||||||
WRITE(L6470_CHAIN_SCK_PIN, HIGH);
|
|
||||||
DELAY_NS(125); // 10 cycles @ 84mhz
|
|
||||||
|
|
||||||
b |= (READ(L6470_CHAIN_MISO_PIN) != 0);
|
|
||||||
|
|
||||||
WRITE(L6470_CHAIN_SCK_PIN, LOW);
|
|
||||||
DELAY_NS(125); // 10 cycles @ 84mhz
|
|
||||||
}
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint8_t L6470_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
|
|
||||||
for (uint8_t bits = 8; bits--;) {
|
|
||||||
WRITE(L6470_CHAIN_SCK_PIN, LOW);
|
|
||||||
WRITE(L6470_CHAIN_MOSI_PIN, b & 0x80);
|
|
||||||
|
|
||||||
DELAY_NS(125); // 10 cycles @ 84mhz
|
|
||||||
WRITE(L6470_CHAIN_SCK_PIN, HIGH);
|
|
||||||
DELAY_NS(125); // Need more delay for fast CPUs
|
|
||||||
|
|
||||||
b <<= 1; // little setup time
|
|
||||||
b |= (READ(L6470_CHAIN_MISO_PIN) != 0);
|
|
||||||
}
|
|
||||||
DELAY_NS(125); // 10 cycles @ 84mhz
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* L64XX methods for SPI init and transfer
|
|
||||||
*/
|
|
||||||
void L64XX_Marlin::spi_init() {
|
|
||||||
OUT_WRITE(L6470_CHAIN_SS_PIN, HIGH);
|
|
||||||
OUT_WRITE(L6470_CHAIN_SCK_PIN, HIGH);
|
|
||||||
OUT_WRITE(L6470_CHAIN_MOSI_PIN, HIGH);
|
|
||||||
SET_INPUT(L6470_CHAIN_MISO_PIN);
|
|
||||||
|
|
||||||
#if PIN_EXISTS(L6470_BUSY)
|
|
||||||
SET_INPUT(L6470_BUSY_PIN);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
OUT_WRITE(L6470_CHAIN_MOSI_PIN, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t L64XX_Marlin::transfer_single(uint8_t data, int16_t ss_pin) {
|
|
||||||
// First device in chain has data sent last
|
|
||||||
extDigitalWrite(ss_pin, LOW);
|
|
||||||
|
|
||||||
hal.isr_off(); // Disable interrupts during SPI transfer (can't allow partial command to chips)
|
|
||||||
const uint8_t data_out = L6470_SpiTransfer_Mode_3(data);
|
|
||||||
hal.isr_on(); // Enable interrupts
|
|
||||||
|
|
||||||
extDigitalWrite(ss_pin, HIGH);
|
|
||||||
return data_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t L64XX_Marlin::transfer_chain(uint8_t data, int16_t ss_pin, uint8_t chain_position) {
|
|
||||||
uint8_t data_out = 0;
|
|
||||||
|
|
||||||
// first device in chain has data sent last
|
|
||||||
extDigitalWrite(ss_pin, LOW);
|
|
||||||
|
|
||||||
for (uint8_t i = L64XX::chain[0]; !L64xxManager.spi_abort && i >= 1; i--) { // Send data unless aborted
|
|
||||||
hal.isr_off(); // Disable interrupts during SPI transfer (can't allow partial command to chips)
|
|
||||||
const uint8_t temp = L6470_SpiTransfer_Mode_3(uint8_t(i == chain_position ? data : dSPIN_NOP));
|
|
||||||
hal.isr_on(); // Enable interrupts
|
|
||||||
if (i == chain_position) data_out = temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
extDigitalWrite(ss_pin, HIGH);
|
|
||||||
return data_out;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Platform-supplied L6470 buffer transfer method
|
|
||||||
*/
|
|
||||||
void L64XX_Marlin::transfer(uint8_t L6470_buf[], const uint8_t length) {
|
|
||||||
// First device in chain has its data sent last
|
|
||||||
|
|
||||||
if (spi_active) { // Interrupted SPI transfer so need to
|
|
||||||
WRITE(L6470_CHAIN_SS_PIN, HIGH); // guarantee min high of 650ns
|
|
||||||
DELAY_US(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
WRITE(L6470_CHAIN_SS_PIN, LOW);
|
|
||||||
for (uint8_t i = length; i >= 1; i--)
|
|
||||||
L6470_SpiTransfer_Mode_3(uint8_t(L6470_buf[i]));
|
|
||||||
WRITE(L6470_CHAIN_SS_PIN, HIGH);
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma GCC reset_options
|
|
||||||
|
|
||||||
#endif // HAS_L64XX
|
|
||||||
@@ -135,11 +135,11 @@ static UnwResult UnwTabExecuteInstructions(const UnwindCallbacks *cb, UnwTabStat
|
|||||||
while ((instruction = UnwTabGetNextInstruction(cb, ucb)) != -1) {
|
while ((instruction = UnwTabGetNextInstruction(cb, ucb)) != -1) {
|
||||||
|
|
||||||
if ((instruction & 0xC0) == 0x00) { // ARM_EXIDX_CMD_DATA_POP
|
if ((instruction & 0xC0) == 0x00) { // ARM_EXIDX_CMD_DATA_POP
|
||||||
/* vsp = vsp + (xxxxxx << 2) + 4 */
|
/* vsp += (xxxxxx << 2) + 4 */
|
||||||
ucb->vrs[13] += ((instruction & 0x3F) << 2) + 4;
|
ucb->vrs[13] += ((instruction & 0x3F) << 2) + 4;
|
||||||
}
|
}
|
||||||
else if ((instruction & 0xC0) == 0x40) { // ARM_EXIDX_CMD_DATA_PUSH
|
else if ((instruction & 0xC0) == 0x40) { // ARM_EXIDX_CMD_DATA_PUSH
|
||||||
/* vsp = vsp - (xxxxxx << 2) - 4 */
|
/* vsp -= (xxxxxx << 2) - 4 */
|
||||||
ucb->vrs[13] -= ((instruction & 0x3F) << 2) - 4;
|
ucb->vrs[13] -= ((instruction & 0x3F) << 2) - 4;
|
||||||
}
|
}
|
||||||
else if ((instruction & 0xF0) == 0x80) {
|
else if ((instruction & 0xF0) == 0x80) {
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ uint8_t ServoCount = 0; // the total number of attached
|
|||||||
|
|
||||||
/************ static functions common to all instances ***********************/
|
/************ static functions common to all instances ***********************/
|
||||||
|
|
||||||
static boolean isTimerActive(timer16_Sequence_t timer) {
|
static bool anyTimerChannelActive(const timer16_Sequence_t timer) {
|
||||||
// returns true if any servo is active on this timer
|
// returns true if any servo is active on this timer
|
||||||
LOOP_L_N(channel, SERVOS_PER_TIMER) {
|
LOOP_L_N(channel, SERVOS_PER_TIMER) {
|
||||||
if (SERVO(timer, channel).Pin.isActive)
|
if (SERVO(timer, channel).Pin.isActive)
|
||||||
@@ -101,17 +101,18 @@ int8_t Servo::attach(const int inPin, const int inMin, const int inMax) {
|
|||||||
max = (MAX_PULSE_WIDTH - inMax) / 4;
|
max = (MAX_PULSE_WIDTH - inMax) / 4;
|
||||||
|
|
||||||
// initialize the timer if it has not already been initialized
|
// initialize the timer if it has not already been initialized
|
||||||
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
const timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||||
if (!isTimerActive(timer)) initISR(timer);
|
if (!anyTimerChannelActive(timer)) initISR(timer);
|
||||||
servo_info[servoIndex].Pin.isActive = true; // this must be set after the check for isTimerActive
|
servo_info[servoIndex].Pin.isActive = true; // this must be set after the check for anyTimerChannelActive
|
||||||
|
|
||||||
return servoIndex;
|
return servoIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servo::detach() {
|
void Servo::detach() {
|
||||||
servo_info[servoIndex].Pin.isActive = false;
|
servo_info[servoIndex].Pin.isActive = false;
|
||||||
timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
const timer16_Sequence_t timer = SERVO_INDEX_TO_TIMER(servoIndex);
|
||||||
if (!isTimerActive(timer)) finISR(timer);
|
if (!anyTimerChannelActive(timer)) finISR(timer);
|
||||||
|
//pinMode(servo_info[servoIndex].Pin.nbr, INPUT); // set servo pin to input
|
||||||
}
|
}
|
||||||
|
|
||||||
void Servo::write(int value) {
|
void Servo::write(int value) {
|
||||||
|
|||||||
@@ -70,10 +70,10 @@
|
|||||||
#define ticksToUs(_ticks) (unsigned(_ticks) * (SERVO_TIMER_PRESCALER) / clockCyclesPerMicrosecond())
|
#define ticksToUs(_ticks) (unsigned(_ticks) * (SERVO_TIMER_PRESCALER) / clockCyclesPerMicrosecond())
|
||||||
|
|
||||||
// convenience macros
|
// convenience macros
|
||||||
#define SERVO_INDEX_TO_TIMER(_servo_nbr) ((timer16_Sequence_t)(_servo_nbr / (SERVOS_PER_TIMER))) // returns the timer controlling this servo
|
#define SERVO_INDEX_TO_TIMER(_servo_nbr) timer16_Sequence_t(_servo_nbr / (SERVOS_PER_TIMER)) // the timer controlling this servo
|
||||||
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // returns the index of the servo on this timer
|
#define SERVO_INDEX_TO_CHANNEL(_servo_nbr) (_servo_nbr % (SERVOS_PER_TIMER)) // the index of the servo on this timer
|
||||||
#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // macro to access servo index by timer and channel
|
#define SERVO_INDEX(_timer,_channel) ((_timer*(SERVOS_PER_TIMER)) + _channel) // servo index by timer and channel
|
||||||
#define SERVO(_timer,_channel) (servo_info[SERVO_INDEX(_timer,_channel)]) // macro to access servo class by timer and channel
|
#define SERVO(_timer,_channel) servo_info[SERVO_INDEX(_timer,_channel)] // servo class by timer and channel
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
|
|
||||||
@@ -94,5 +94,5 @@ extern ServoInfo_t servo_info[MAX_SERVOS];
|
|||||||
|
|
||||||
// Public functions
|
// Public functions
|
||||||
|
|
||||||
extern void initISR(timer16_Sequence_t timer);
|
void initISR(const timer16_Sequence_t timer_index);
|
||||||
extern void finISR(timer16_Sequence_t timer);
|
void finISR(const timer16_Sequence_t timer_index);
|
||||||
|
|||||||
+63
-54
@@ -39,17 +39,13 @@
|
|||||||
#endif
|
#endif
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#include "core/utility.h"
|
#include "module/endstops.h"
|
||||||
|
|
||||||
#include "module/motion.h"
|
#include "module/motion.h"
|
||||||
#include "module/planner.h"
|
#include "module/planner.h"
|
||||||
#include "module/endstops.h"
|
|
||||||
#include "module/temperature.h"
|
|
||||||
#include "module/settings.h"
|
|
||||||
#include "module/printcounter.h" // PrintCounter or Stopwatch
|
#include "module/printcounter.h" // PrintCounter or Stopwatch
|
||||||
|
#include "module/settings.h"
|
||||||
#include "module/stepper.h"
|
#include "module/stepper.h"
|
||||||
#include "module/stepper/indirection.h"
|
#include "module/temperature.h"
|
||||||
|
|
||||||
#include "gcode/gcode.h"
|
#include "gcode/gcode.h"
|
||||||
#include "gcode/parser.h"
|
#include "gcode/parser.h"
|
||||||
@@ -125,6 +121,10 @@
|
|||||||
#include "feature/bltouch.h"
|
#include "feature/bltouch.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(BD_SENSOR)
|
||||||
|
#include "feature/bedlevel/bdl/bdl.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(POLL_JOG)
|
#if ENABLED(POLL_JOG)
|
||||||
#include "feature/joystick.h"
|
#include "feature/joystick.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -228,10 +228,6 @@
|
|||||||
#include "feature/mmu/mmu2.h"
|
#include "feature/mmu/mmu2.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_L64XX
|
|
||||||
#include "libs/L64XX/L64XX_Marlin.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(PASSWORD_FEATURE)
|
#if ENABLED(PASSWORD_FEATURE)
|
||||||
#include "feature/password/password.h"
|
#include "feature/password/password.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -252,6 +248,10 @@
|
|||||||
#include "feature/easythreed_ui.h"
|
#include "feature/easythreed_ui.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(MARLIN_TEST_BUILD)
|
||||||
|
#include "tests/marlin_tests.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
PGMSTR(M112_KILL_STR, "M112 Shutdown");
|
PGMSTR(M112_KILL_STR, "M112 Shutdown");
|
||||||
|
|
||||||
MarlinState marlin_state = MF_INITIALIZING;
|
MarlinState marlin_state = MF_INITIALIZING;
|
||||||
@@ -347,7 +347,7 @@ void startOrResumeJob() {
|
|||||||
TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
|
TERN_(GCODE_REPEAT_MARKERS, repeat.reset());
|
||||||
TERN_(CANCEL_OBJECTS, cancelable.reset());
|
TERN_(CANCEL_OBJECTS, cancelable.reset());
|
||||||
TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0);
|
TERN_(LCD_SHOW_E_TOTAL, e_move_accumulator = 0);
|
||||||
#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
|
#if ENABLED(SET_REMAINING_TIME)
|
||||||
ui.reset_remaining_time();
|
ui.reset_remaining_time();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -423,37 +423,38 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||||||
kill();
|
kill();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const bool has_blocks = planner.has_blocks_queued(); // Any moves in the planner?
|
||||||
|
if (has_blocks) gcode.reset_stepper_timeout(ms); // Reset timeout for M18/M84, M85 max 'kill', and laser.
|
||||||
|
|
||||||
// M18 / M84 : Handle steppers inactive time timeout
|
// M18 / M84 : Handle steppers inactive time timeout
|
||||||
if (gcode.stepper_inactive_time) {
|
#if HAS_DISABLE_INACTIVE_AXIS
|
||||||
|
if (gcode.stepper_inactive_time) {
|
||||||
|
|
||||||
static bool already_shutdown_steppers; // = false
|
static bool already_shutdown_steppers; // = false
|
||||||
|
|
||||||
// Any moves in the planner? Resets both the M18/M84
|
if (!has_blocks && !do_reset_timeout && gcode.stepper_inactive_timeout()) {
|
||||||
// activity timeout and the M85 max 'kill' timeout
|
if (!already_shutdown_steppers) {
|
||||||
if (planner.has_blocks_queued())
|
already_shutdown_steppers = true;
|
||||||
gcode.reset_stepper_timeout(ms);
|
|
||||||
else if (!do_reset_timeout && gcode.stepper_inactive_timeout()) {
|
|
||||||
if (!already_shutdown_steppers) {
|
|
||||||
already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this
|
|
||||||
|
|
||||||
// Individual axes will be disabled if configured
|
// Individual axes will be disabled if configured
|
||||||
TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS));
|
TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS));
|
TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS));
|
TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS));
|
TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS));
|
TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS));
|
TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_U, stepper.disable_axis(U_AXIS));
|
TERN_(DISABLE_INACTIVE_U, stepper.disable_axis(U_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_V, stepper.disable_axis(V_AXIS));
|
TERN_(DISABLE_INACTIVE_V, stepper.disable_axis(V_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_W, stepper.disable_axis(W_AXIS));
|
TERN_(DISABLE_INACTIVE_W, stepper.disable_axis(W_AXIS));
|
||||||
TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers());
|
TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers());
|
||||||
|
|
||||||
TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled());
|
TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
already_shutdown_steppers = false;
|
||||||
}
|
}
|
||||||
else
|
#endif
|
||||||
already_shutdown_steppers = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLED(PHOTO_GCODE) && PIN_EXISTS(CHDK)
|
#if ENABLED(PHOTO_GCODE) && PIN_EXISTS(CHDK)
|
||||||
// Check if CHDK should be set to LOW (after M240 set it HIGH)
|
// Check if CHDK should be set to LOW (after M240 set it HIGH)
|
||||||
@@ -487,7 +488,7 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_FREEZE_PIN
|
#if ENABLED(FREEZE_FEATURE)
|
||||||
stepper.frozen = READ(FREEZE_PIN) == FREEZE_STATE;
|
stepper.frozen = READ(FREEZE_PIN) == FREEZE_STATE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -732,8 +733,6 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||||||
|
|
||||||
TERN_(MONITOR_DRIVER_STATUS, monitor_tmc_drivers());
|
TERN_(MONITOR_DRIVER_STATUS, monitor_tmc_drivers());
|
||||||
|
|
||||||
TERN_(MONITOR_L6470_DRIVER_STATUS, L64xxManager.monitor_driver());
|
|
||||||
|
|
||||||
// Limit check_axes_activity frequency to 10Hz
|
// Limit check_axes_activity frequency to 10Hz
|
||||||
static millis_t next_check_axes_ms = 0;
|
static millis_t next_check_axes_ms = 0;
|
||||||
if (ELAPSED(ms, next_check_axes_ms)) {
|
if (ELAPSED(ms, next_check_axes_ms)) {
|
||||||
@@ -775,16 +774,23 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
|
|||||||
* - Handle Joystick jogging
|
* - Handle Joystick jogging
|
||||||
*/
|
*/
|
||||||
void idle(bool no_stepper_sleep/*=false*/) {
|
void idle(bool no_stepper_sleep/*=false*/) {
|
||||||
|
#ifdef MAX7219_DEBUG_PROFILE
|
||||||
|
CodeProfiler idle_profiler;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(MARLIN_DEV_MODE)
|
#if ENABLED(MARLIN_DEV_MODE)
|
||||||
static uint16_t idle_depth = 0;
|
static uint16_t idle_depth = 0;
|
||||||
if (++idle_depth > 5) SERIAL_ECHOLNPGM("idle() call depth: ", idle_depth);
|
if (++idle_depth > 5) SERIAL_ECHOLNPGM("idle() call depth: ", idle_depth);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Bed Distance Sensor task
|
||||||
|
TERN_(BD_SENSOR, bdl.process());
|
||||||
|
|
||||||
// Core Marlin activities
|
// Core Marlin activities
|
||||||
manage_inactivity(no_stepper_sleep);
|
manage_inactivity(no_stepper_sleep);
|
||||||
|
|
||||||
// Manage Heaters (and Watchdog)
|
// Manage Heaters (and Watchdog)
|
||||||
thermalManager.manage_heater();
|
thermalManager.task();
|
||||||
|
|
||||||
// Max7219 heartbeat, animation, etc
|
// Max7219 heartbeat, animation, etc
|
||||||
TERN_(MAX7219_DEBUG, max7219.idle_tasks());
|
TERN_(MAX7219_DEBUG, max7219.idle_tasks());
|
||||||
@@ -1059,7 +1065,6 @@ inline void tmc_standby_setup() {
|
|||||||
* • TMC220x Stepper Drivers (Serial)
|
* • TMC220x Stepper Drivers (Serial)
|
||||||
* • PSU control
|
* • PSU control
|
||||||
* • Power-loss Recovery
|
* • Power-loss Recovery
|
||||||
* • L64XX Stepper Drivers (SPI)
|
|
||||||
* • Stepper Driver Reset: DISABLE
|
* • Stepper Driver Reset: DISABLE
|
||||||
* • TMC Stepper Drivers (SPI)
|
* • TMC Stepper Drivers (SPI)
|
||||||
* • Run hal.init_board() for additional pins setup
|
* • Run hal.init_board() for additional pins setup
|
||||||
@@ -1222,10 +1227,10 @@ void setup() {
|
|||||||
SETUP_RUN(hal.init());
|
SETUP_RUN(hal.init());
|
||||||
|
|
||||||
// Init and disable SPI thermocouples; this is still needed
|
// Init and disable SPI thermocouples; this is still needed
|
||||||
#if TEMP_SENSOR_0_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E0))
|
#if TEMP_SENSOR_IS_MAX_TC(0) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E0))
|
||||||
OUT_WRITE(TEMP_0_CS_PIN, HIGH); // Disable
|
OUT_WRITE(TEMP_0_CS_PIN, HIGH); // Disable
|
||||||
#endif
|
#endif
|
||||||
#if TEMP_SENSOR_1_IS_MAX_TC || (TEMP_SENSOR_REDUNDANT_IS_MAX_TC && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
#if TEMP_SENSOR_IS_MAX_TC(1) || (TEMP_SENSOR_IS_MAX_TC(REDUNDANT) && REDUNDANT_TEMP_MATCH(SOURCE, E1))
|
||||||
OUT_WRITE(TEMP_1_CS_PIN, HIGH);
|
OUT_WRITE(TEMP_1_CS_PIN, HIGH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1241,6 +1246,13 @@ void setup() {
|
|||||||
SETUP_RUN(tmc_serial_begin());
|
SETUP_RUN(tmc_serial_begin());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAS_TMC_SPI
|
||||||
|
#if DISABLED(TMC_USE_SW_SPI)
|
||||||
|
SETUP_RUN(SPI.begin());
|
||||||
|
#endif
|
||||||
|
SETUP_RUN(tmc_init_cs_pins());
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(PSU_CONTROL)
|
#if ENABLED(PSU_CONTROL)
|
||||||
SETUP_LOG("PSU_CONTROL");
|
SETUP_LOG("PSU_CONTROL");
|
||||||
powerManager.init();
|
powerManager.init();
|
||||||
@@ -1250,21 +1262,10 @@ void setup() {
|
|||||||
SETUP_RUN(recovery.setup());
|
SETUP_RUN(recovery.setup());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_L64XX
|
|
||||||
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAS_STEPPER_RESET
|
#if HAS_STEPPER_RESET
|
||||||
SETUP_RUN(disableStepperDrivers());
|
SETUP_RUN(disableStepperDrivers());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_TMC_SPI
|
|
||||||
#if DISABLED(TMC_USE_SW_SPI)
|
|
||||||
SETUP_RUN(SPI.begin());
|
|
||||||
#endif
|
|
||||||
SETUP_RUN(tmc_init_cs_pins());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
SETUP_RUN(hal.init_board());
|
SETUP_RUN(hal.init_board());
|
||||||
|
|
||||||
SETUP_RUN(esp_wifi_init());
|
SETUP_RUN(esp_wifi_init());
|
||||||
@@ -1638,9 +1639,15 @@ void setup() {
|
|||||||
SETUP_RUN(test_tmc_connection());
|
SETUP_RUN(test_tmc_connection());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(BD_SENSOR)
|
||||||
|
SETUP_RUN(bdl.init(I2C_BD_SDA_PIN, I2C_BD_SCL_PIN, I2C_BD_DELAY));
|
||||||
|
#endif
|
||||||
|
|
||||||
marlin_state = MF_RUNNING;
|
marlin_state = MF_RUNNING;
|
||||||
|
|
||||||
SETUP_LOG("setup() completed.");
|
SETUP_LOG("setup() completed.");
|
||||||
|
|
||||||
|
TERN_(MARLIN_TEST_BUILD, runStartupTests());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1675,5 +1682,7 @@ void loop() {
|
|||||||
|
|
||||||
TERN_(HAS_TFT_LVGL_UI, printer_state_polling());
|
TERN_(HAS_TFT_LVGL_UI, printer_state_polling());
|
||||||
|
|
||||||
|
TERN_(MARLIN_TEST_BUILD, runPeriodicTests());
|
||||||
|
|
||||||
} while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards
|
} while (ENABLED(__AVR__)); // Loop forever on slower (AVR) boards
|
||||||
}
|
}
|
||||||
|
|||||||
+77
-67
@@ -161,7 +161,7 @@
|
|||||||
#define BOARD_PICA_REVB 1324 // PICA Shield (original version)
|
#define BOARD_PICA_REVB 1324 // PICA Shield (original version)
|
||||||
#define BOARD_PICA 1325 // PICA Shield (rev C or later)
|
#define BOARD_PICA 1325 // PICA Shield (rev C or later)
|
||||||
#define BOARD_INTAMSYS40 1326 // Intamsys 4.0 (Funmat HT)
|
#define BOARD_INTAMSYS40 1326 // Intamsys 4.0 (Funmat HT)
|
||||||
#define BOARD_MALYAN_M180 1327 // Malyan M180 Mainboard Version 2 (no display function, direct gcode only)
|
#define BOARD_MALYAN_M180 1327 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
|
||||||
#define BOARD_GT2560_V4_A20 1328 // Geeetech GT2560 Rev B for A20(M/T/D)
|
#define BOARD_GT2560_V4_A20 1328 // Geeetech GT2560 Rev B for A20(M/T/D)
|
||||||
#define BOARD_PROTONEER_CNC_SHIELD_V3 1329 // Mega controller & Protoneer CNC Shield V3.00
|
#define BOARD_PROTONEER_CNC_SHIELD_V3 1329 // Mega controller & Protoneer CNC Shield V3.00
|
||||||
#define BOARD_WEEDO_62A 1330 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
|
#define BOARD_WEEDO_62A 1330 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
|
||||||
@@ -238,6 +238,7 @@
|
|||||||
#define BOARD_BTT_SKR_V1_1 2012 // BigTreeTech SKR v1.1
|
#define BOARD_BTT_SKR_V1_1 2012 // BigTreeTech SKR v1.1
|
||||||
#define BOARD_BTT_SKR_V1_3 2013 // BigTreeTech SKR v1.3
|
#define BOARD_BTT_SKR_V1_3 2013 // BigTreeTech SKR v1.3
|
||||||
#define BOARD_BTT_SKR_V1_4 2014 // BigTreeTech SKR v1.4
|
#define BOARD_BTT_SKR_V1_4 2014 // BigTreeTech SKR v1.4
|
||||||
|
#define BOARD_EMOTRONIC 2015 // eMotion-Tech eMotronic
|
||||||
|
|
||||||
//
|
//
|
||||||
// LPC1769 ARM Cortex M3
|
// LPC1769 ARM Cortex M3
|
||||||
@@ -328,44 +329,47 @@
|
|||||||
#define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
|
#define BOARD_BTT_SKR_MINI_E3_V1_2 4025 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
|
||||||
#define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC / STM32F103RE)
|
#define BOARD_BTT_SKR_MINI_E3_V2_0 4026 // BigTreeTech SKR Mini E3 V2.0 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_BTT_SKR_MINI_E3_V3_0 4027 // BigTreeTech SKR Mini E3 V3.0 (STM32G0B1RE)
|
#define BOARD_BTT_SKR_MINI_E3_V3_0 4027 // BigTreeTech SKR Mini E3 V3.0 (STM32G0B1RE)
|
||||||
#define BOARD_BTT_SKR_MINI_MZ_V1_0 4028 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC)
|
#define BOARD_BTT_SKR_MINI_E3_V3_0_1 4028 // BigTreeTech SKR Mini E3 V3.0.1 (STM32F401RC)
|
||||||
#define BOARD_BTT_SKR_E3_DIP 4029 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
|
#define BOARD_BTT_SKR_MINI_MZ_V1_0 4029 // BigTreeTech SKR Mini MZ V1.0 (STM32F103RC)
|
||||||
#define BOARD_BTT_SKR_CR6 4030 // BigTreeTech SKR CR6 v1.0 (STM32F103RE)
|
#define BOARD_BTT_SKR_E3_DIP 4030 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_JGAURORA_A5S_A1 4031 // JGAurora A5S A1 (STM32F103ZE)
|
#define BOARD_BTT_SKR_CR6 4031 // BigTreeTech SKR CR6 v1.0 (STM32F103RE)
|
||||||
#define BOARD_FYSETC_AIO_II 4032 // FYSETC AIO_II
|
#define BOARD_JGAURORA_A5S_A1 4032 // JGAurora A5S A1 (STM32F103ZE)
|
||||||
#define BOARD_FYSETC_CHEETAH 4033 // FYSETC Cheetah
|
#define BOARD_FYSETC_AIO_II 4033 // FYSETC AIO_II (STM32F103RC)
|
||||||
#define BOARD_FYSETC_CHEETAH_V12 4034 // FYSETC Cheetah V1.2
|
#define BOARD_FYSETC_CHEETAH 4034 // FYSETC Cheetah (STM32F103RC)
|
||||||
#define BOARD_LONGER3D_LK 4035 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VE
|
#define BOARD_FYSETC_CHEETAH_V12 4035 // FYSETC Cheetah V1.2 (STM32F103RC)
|
||||||
#define BOARD_CCROBOT_MEEB_3DP 4036 // ccrobot-online.com MEEB_3DP (STM32F103RC)
|
#define BOARD_LONGER3D_LK 4036 // Longer3D LK1/2 - Alfawise U20/U20+/U30 (STM32F103VE)
|
||||||
#define BOARD_CHITU3D_V5 4037 // Chitu3D TronXY X5SA V5 Board
|
#define BOARD_CCROBOT_MEEB_3DP 4037 // ccrobot-online.com MEEB_3DP (STM32F103RC)
|
||||||
#define BOARD_CHITU3D_V6 4038 // Chitu3D TronXY X5SA V6 Board
|
#define BOARD_CHITU3D_V5 4038 // Chitu3D TronXY X5SA V5 Board (STM32F103ZE)
|
||||||
#define BOARD_CHITU3D_V9 4039 // Chitu3D TronXY X5SA V9 Board
|
#define BOARD_CHITU3D_V6 4039 // Chitu3D TronXY X5SA V6 Board (STM32F103ZE)
|
||||||
#define BOARD_CREALITY_V4 4040 // Creality v4.x (STM32F103RC / STM32F103RE)
|
#define BOARD_CHITU3D_V9 4040 // Chitu3D TronXY X5SA V9 Board (STM32F103ZE)
|
||||||
#define BOARD_CREALITY_V422 4041 // Creality v4.2.2 (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V4 4041 // Creality v4.x (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V423 4042 // Creality v4.2.3 (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V422 4042 // Creality v4.2.2 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V427 4043 // Creality v4.2.7 (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V423 4043 // Creality v4.2.3 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V4210 4044 // Creality v4.2.10 (STM32F103RC / STM32F103RE) as found in the CR-30
|
#define BOARD_CREALITY_V425 4044 // Creality v4.2.5 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V431 4045 // Creality v4.3.1 (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V427 4045 // Creality v4.2.7 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V431_A 4046 // Creality v4.3.1a (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V4210 4046 // Creality v4.2.10 (STM32F103RC / STM32F103RE) as found in the CR-30
|
||||||
#define BOARD_CREALITY_V431_B 4047 // Creality v4.3.1b (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V431 4047 // Creality v4.3.1 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V431_C 4048 // Creality v4.3.1c (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V431_A 4048 // Creality v4.3.1a (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V431_D 4049 // Creality v4.3.1d (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V431_B 4049 // Creality v4.3.1b (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V452 4050 // Creality v4.5.2 (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V431_C 4050 // Creality v4.3.1c (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V453 4051 // Creality v4.5.3 (STM32F103RC / STM32F103RE)
|
#define BOARD_CREALITY_V431_D 4051 // Creality v4.3.1d (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V24S1 4052 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7
|
#define BOARD_CREALITY_V452 4052 // Creality v4.5.2 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V24S1_301 4053 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1
|
#define BOARD_CREALITY_V453 4053 // Creality v4.5.3 (STM32F103RC / STM32F103RE)
|
||||||
#define BOARD_CREALITY_V25S1 4054 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro
|
#define BOARD_CREALITY_V521 4054 // Creality v5.2.1 (STM32F103VE) as found in the SV04
|
||||||
#define BOARD_TRIGORILLA_PRO 4055 // Trigorilla Pro (STM32F103ZE)
|
#define BOARD_CREALITY_V24S1 4055 // Creality v2.4.S1 (STM32F103RC / STM32F103RE) v101 as found in the Ender-7
|
||||||
#define BOARD_FLY_MINI 4056 // FLYmaker FLY MINI (STM32F103RC)
|
#define BOARD_CREALITY_V24S1_301 4056 // Creality v2.4.S1_301 (STM32F103RC / STM32F103RE) v301 as found in the Ender-3 S1
|
||||||
#define BOARD_FLSUN_HISPEED 4057 // FLSUN HiSpeedV1 (STM32F103VE)
|
#define BOARD_CREALITY_V25S1 4057 // Creality v2.5.S1 (STM32F103RE) as found in the CR-10 Smart Pro
|
||||||
#define BOARD_BEAST 4058 // STM32F103RE Libmaple-based controller
|
#define BOARD_TRIGORILLA_PRO 4058 // Trigorilla Pro (STM32F103ZE)
|
||||||
#define BOARD_MINGDA_MPX_ARM_MINI 4059 // STM32F103ZE Mingda MD-16
|
#define BOARD_FLY_MINI 4059 // FLYmaker FLY MINI (STM32F103RC)
|
||||||
#define BOARD_GTM32_PRO_VD 4060 // STM32F103VE controller
|
#define BOARD_FLSUN_HISPEED 4060 // FLSUN HiSpeedV1 (STM32F103VE)
|
||||||
#define BOARD_ZONESTAR_ZM3E2 4061 // Zonestar ZM3E2 (STM32F103RC)
|
#define BOARD_BEAST 4061 // STM32F103RE Libmaple-based controller
|
||||||
#define BOARD_ZONESTAR_ZM3E4 4062 // Zonestar ZM3E4 V1 (STM32F103VC)
|
#define BOARD_MINGDA_MPX_ARM_MINI 4062 // STM32F103ZE Mingda MD-16
|
||||||
#define BOARD_ZONESTAR_ZM3E4V2 4063 // Zonestar ZM3E4 V2 (STM32F103VC)
|
#define BOARD_GTM32_PRO_VD 4063 // STM32F103VE controller
|
||||||
#define BOARD_ERYONE_ERY32_MINI 4064 // Eryone Ery32 mini (STM32F103VE)
|
#define BOARD_ZONESTAR_ZM3E2 4064 // Zonestar ZM3E2 (STM32F103RC)
|
||||||
#define BOARD_PANDA_PI_V29 4065 // Panda Pi V2.9 - Standalone (STM32F103RC)
|
#define BOARD_ZONESTAR_ZM3E4 4065 // Zonestar ZM3E4 V1 (STM32F103VC)
|
||||||
|
#define BOARD_ZONESTAR_ZM3E4V2 4066 // Zonestar ZM3E4 V2 (STM32F103VC)
|
||||||
|
#define BOARD_ERYONE_ERY32_MINI 4067 // Eryone Ery32 mini (STM32F103VE)
|
||||||
|
#define BOARD_PANDA_PI_V29 4068 // Panda Pi V2.9 - Standalone (STM32F103RC)
|
||||||
|
|
||||||
//
|
//
|
||||||
// ARM Cortex-M4F
|
// ARM Cortex-M4F
|
||||||
@@ -385,40 +389,43 @@
|
|||||||
#define BOARD_RUMBA32_BTT 4204 // RUMBA32 STM32F446VE based controller from BIGTREETECH
|
#define BOARD_RUMBA32_BTT 4204 // RUMBA32 STM32F446VE based controller from BIGTREETECH
|
||||||
#define BOARD_BLACK_STM32F407VE 4205 // BLACK_STM32F407VE
|
#define BOARD_BLACK_STM32F407VE 4205 // BLACK_STM32F407VE
|
||||||
#define BOARD_BLACK_STM32F407ZE 4206 // BLACK_STM32F407ZE
|
#define BOARD_BLACK_STM32F407ZE 4206 // BLACK_STM32F407ZE
|
||||||
#define BOARD_STEVAL_3DP001V1 4207 // STEVAL-3DP001V1 3D PRINTER BOARD
|
#define BOARD_BTT_SKR_PRO_V1_1 4207 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
|
||||||
#define BOARD_BTT_SKR_PRO_V1_1 4208 // BigTreeTech SKR Pro v1.1 (STM32F407ZG)
|
#define BOARD_BTT_SKR_PRO_V1_2 4208 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
|
||||||
#define BOARD_BTT_SKR_PRO_V1_2 4209 // BigTreeTech SKR Pro v1.2 (STM32F407ZG)
|
#define BOARD_BTT_BTT002_V1_0 4209 // BigTreeTech BTT002 v1.0 (STM32F407VG)
|
||||||
#define BOARD_BTT_BTT002_V1_0 4210 // BigTreeTech BTT002 v1.0 (STM32F407VG)
|
#define BOARD_BTT_E3_RRF 4210 // BigTreeTech E3 RRF (STM32F407VG)
|
||||||
#define BOARD_BTT_E3_RRF 4211 // BigTreeTech E3 RRF (STM32F407VG)
|
#define BOARD_BTT_SKR_V2_0_REV_A 4211 // BigTreeTech SKR v2.0 Rev A (STM32F407VG)
|
||||||
#define BOARD_BTT_SKR_V2_0_REV_A 4212 // BigTreeTech SKR v2.0 Rev A (STM32F407VG)
|
#define BOARD_BTT_SKR_V2_0_REV_B 4212 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG)
|
||||||
#define BOARD_BTT_SKR_V2_0_REV_B 4213 // BigTreeTech SKR v2.0 Rev B (STM32F407VG/STM32F429VG)
|
#define BOARD_BTT_GTR_V1_0 4213 // BigTreeTech GTR v1.0 (STM32F407IGT)
|
||||||
#define BOARD_BTT_GTR_V1_0 4214 // BigTreeTech GTR v1.0 (STM32F407IGT)
|
#define BOARD_BTT_OCTOPUS_V1_0 4214 // BigTreeTech Octopus v1.0 (STM32F446ZE)
|
||||||
#define BOARD_BTT_OCTOPUS_V1_0 4215 // BigTreeTech Octopus v1.0 (STM32F446ZE)
|
#define BOARD_BTT_OCTOPUS_V1_1 4215 // BigTreeTech Octopus v1.1 (STM32F446ZE)
|
||||||
#define BOARD_BTT_OCTOPUS_V1_1 4216 // BigTreeTech Octopus v1.1 (STM32F446ZE)
|
#define BOARD_BTT_OCTOPUS_PRO_V1_0 4216 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE / STM32F429ZG)
|
||||||
#define BOARD_BTT_OCTOPUS_PRO_V1_0 4217 // BigTreeTech Octopus Pro v1.0 (STM32F446ZE/STM32F429ZG)
|
#define BOARD_LERDGE_K 4217 // Lerdge K (STM32F407ZG)
|
||||||
#define BOARD_LERDGE_K 4218 // Lerdge K (STM32F407ZG)
|
#define BOARD_LERDGE_S 4218 // Lerdge S (STM32F407VE)
|
||||||
#define BOARD_LERDGE_S 4219 // Lerdge S (STM32F407VE)
|
#define BOARD_LERDGE_X 4219 // Lerdge X (STM32F407VE)
|
||||||
#define BOARD_LERDGE_X 4220 // Lerdge X (STM32F407VE)
|
#define BOARD_VAKE403D 4220 // VAkE 403D (STM32F446VE)
|
||||||
#define BOARD_VAKE403D 4221 // VAkE 403D (STM32F446VE)
|
#define BOARD_FYSETC_S6 4221 // FYSETC S6 (STM32F446VE)
|
||||||
#define BOARD_FYSETC_S6 4222 // FYSETC S6 (STM32F446VE)
|
#define BOARD_FYSETC_S6_V2_0 4222 // FYSETC S6 v2.0 (STM32F446VE)
|
||||||
#define BOARD_FYSETC_S6_V2_0 4223 // FYSETC S6 v2.0 (STM32F446VE)
|
#define BOARD_FYSETC_SPIDER 4223 // FYSETC Spider (STM32F446VE)
|
||||||
#define BOARD_FYSETC_SPIDER 4224 // FYSETC Spider (STM32F446VE)
|
#define BOARD_FLYF407ZG 4224 // FLYmaker FLYF407ZG (STM32F407ZG)
|
||||||
#define BOARD_FLYF407ZG 4225 // FLYmaker FLYF407ZG (STM32F407ZG)
|
#define BOARD_MKS_ROBIN2 4225 // MKS_ROBIN2 (STM32F407ZE)
|
||||||
#define BOARD_MKS_ROBIN2 4226 // MKS_ROBIN2 (STM32F407ZE)
|
#define BOARD_MKS_ROBIN_PRO_V2 4226 // MKS Robin Pro V2 (STM32F407VE)
|
||||||
#define BOARD_MKS_ROBIN_PRO_V2 4227 // MKS Robin Pro V2 (STM32F407VE)
|
#define BOARD_MKS_ROBIN_NANO_V3 4227 // MKS Robin Nano V3 (STM32F407VG)
|
||||||
#define BOARD_MKS_ROBIN_NANO_V3 4228 // MKS Robin Nano V3 (STM32F407VG)
|
#define BOARD_MKS_ROBIN_NANO_V3_1 4228 // MKS Robin Nano V3.1 (STM32F407VE)
|
||||||
#define BOARD_MKS_ROBIN_NANO_V3_1 4229 // MKS Robin Nano V3.1 (STM32F407VE)
|
#define BOARD_MKS_MONSTER8_V1 4229 // MKS Monster8 V1 (STM32F407VE)
|
||||||
#define BOARD_MKS_MONSTER8 4230 // MKS Monster8 (STM32F407VG)
|
#define BOARD_MKS_MONSTER8_V2 4230 // MKS Monster8 V2 (STM32F407VE)
|
||||||
#define BOARD_ANET_ET4 4231 // ANET ET4 V1.x (STM32F407VG)
|
#define BOARD_ANET_ET4 4231 // ANET ET4 V1.x (STM32F407VG)
|
||||||
#define BOARD_ANET_ET4P 4232 // ANET ET4P V1.x (STM32F407VG)
|
#define BOARD_ANET_ET4P 4232 // ANET ET4P V1.x (STM32F407VG)
|
||||||
#define BOARD_FYSETC_CHEETAH_V20 4233 // FYSETC Cheetah V2.0
|
#define BOARD_FYSETC_CHEETAH_V20 4233 // FYSETC Cheetah V2.0 (STM32F401RC)
|
||||||
#define BOARD_TH3D_EZBOARD_V2 4234 // TH3D EZBoard v2.0
|
#define BOARD_TH3D_EZBOARD_V2 4234 // TH3D EZBoard v2.0 (STM32F405RG)
|
||||||
#define BOARD_INDEX_REV03 4235 // Index PnP Controller REV03 (STM32F407VE/VG)
|
#define BOARD_OPULO_LUMEN_REV3 4235 // Opulo Lumen PnP Controller REV3 (STM32F407VE / STM32F407VG)
|
||||||
#define BOARD_MKS_ROBIN_NANO_V1_3_F4 4236 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE)
|
#define BOARD_MKS_ROBIN_NANO_V1_3_F4 4236 // MKS Robin Nano V1.3 and MKS Robin Nano-S V1.3 (STM32F407VE)
|
||||||
#define BOARD_MKS_EAGLE 4237 // MKS Eagle (STM32F407VE)
|
#define BOARD_MKS_EAGLE 4237 // MKS Eagle (STM32F407VE)
|
||||||
#define BOARD_ARTILLERY_RUBY 4238 // Artillery Ruby (STM32F401RC)
|
#define BOARD_ARTILLERY_RUBY 4238 // Artillery Ruby (STM32F401RC)
|
||||||
#define BOARD_FYSETC_SPIDER_V2_2 4239 // FYSETC Spider V2.2 (STM32F446VE)
|
#define BOARD_FYSETC_SPIDER_V2_2 4239 // FYSETC Spider V2.2 (STM32F446VE)
|
||||||
#define BOARD_CREALITY_V24S1_301F4 4240 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
|
#define BOARD_CREALITY_V24S1_301F4 4240 // Creality v2.4.S1_301F4 (STM32F401RC) as found in the Ender-3 S1 F4
|
||||||
|
#define BOARD_OPULO_LUMEN_REV4 4241 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG)
|
||||||
|
#define BOARD_FYSETC_SPIDER_KING407 4242 // FYSETC Spider King407 (STM32F407ZG)
|
||||||
|
#define BOARD_MKS_SKIPR_V1 4243 // MKS SKIPR v1.0 all-in-one board (STM32F407VE)
|
||||||
|
|
||||||
//
|
//
|
||||||
// ARM Cortex M7
|
// ARM Cortex M7
|
||||||
@@ -428,7 +435,10 @@
|
|||||||
#define BOARD_TEENSY41 5001 // Teensy 4.1
|
#define BOARD_TEENSY41 5001 // Teensy 4.1
|
||||||
#define BOARD_T41U5XBB 5002 // T41U5XBB Teensy 4.1 breakout board
|
#define BOARD_T41U5XBB 5002 // T41U5XBB Teensy 4.1 breakout board
|
||||||
#define BOARD_NUCLEO_F767ZI 5003 // ST NUCLEO-F767ZI Dev Board
|
#define BOARD_NUCLEO_F767ZI 5003 // ST NUCLEO-F767ZI Dev Board
|
||||||
#define BOARD_BTT_SKR_SE_BX 5004 // BigTreeTech SKR SE BX (STM32H743II)
|
#define BOARD_BTT_SKR_SE_BX_V2 5004 // BigTreeTech SKR SE BX V2.0 (STM32H743II)
|
||||||
|
#define BOARD_BTT_SKR_SE_BX_V3 5005 // BigTreeTech SKR SE BX V3.0 (STM32H743II)
|
||||||
|
#define BOARD_BTT_SKR_V3_0 5006 // BigTreeTech SKR V3.0 (STM32H743VG)
|
||||||
|
#define BOARD_BTT_SKR_V3_0_EZ 5007 // BigTreeTech SKR V3.0 EZ (STM32H743VG)
|
||||||
|
|
||||||
//
|
//
|
||||||
// Espressif ESP32 WiFi
|
// Espressif ESP32 WiFi
|
||||||
|
|||||||
@@ -30,10 +30,6 @@
|
|||||||
#define _A5984 0x5984
|
#define _A5984 0x5984
|
||||||
#define _DRV8825 0x8825
|
#define _DRV8825 0x8825
|
||||||
#define _LV8729 0x8729
|
#define _LV8729 0x8729
|
||||||
#define _L6470 0x6470
|
|
||||||
#define _L6474 0x6474
|
|
||||||
#define _L6480 0x6480
|
|
||||||
#define _POWERSTEP01 0xF00D
|
|
||||||
#define _TB6560 0x6560
|
#define _TB6560 0x6560
|
||||||
#define _TB6600 0x6600
|
#define _TB6600 0x6600
|
||||||
#define _TMC2100 0x2100
|
#define _TMC2100 0x2100
|
||||||
@@ -193,16 +189,3 @@
|
|||||||
#if HAS_DRIVER(TMC26X)
|
#if HAS_DRIVER(TMC26X)
|
||||||
#define HAS_TMC26X 1
|
#define HAS_TMC26X 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//
|
|
||||||
// L64XX Stepper Drivers
|
|
||||||
//
|
|
||||||
|
|
||||||
#if HAS_DRIVER(L6470) || HAS_DRIVER(L6474) || HAS_DRIVER(L6480) || HAS_DRIVER(POWERSTEP01)
|
|
||||||
#define HAS_L64XX 1
|
|
||||||
#endif
|
|
||||||
#if HAS_L64XX && !HAS_DRIVER(L6474)
|
|
||||||
#define HAS_L64XX_NOT_L6474 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AXIS_IS_L64XX(A) (AXIS_DRIVER_TYPE_##A(L6470) || AXIS_DRIVER_TYPE_##A(L6474) || AXIS_DRIVER_TYPE_##A(L6480) || AXIS_DRIVER_TYPE_##A(POWERSTEP01))
|
|
||||||
|
|||||||
@@ -174,6 +174,7 @@
|
|||||||
#define STR_SD_VOL_INIT_FAIL "volume.init failed"
|
#define STR_SD_VOL_INIT_FAIL "volume.init failed"
|
||||||
#define STR_SD_OPENROOT_FAIL "openRoot failed"
|
#define STR_SD_OPENROOT_FAIL "openRoot failed"
|
||||||
#define STR_SD_CARD_OK "SD card ok"
|
#define STR_SD_CARD_OK "SD card ok"
|
||||||
|
#define STR_SD_CARD_RELEASED "SD card released"
|
||||||
#define STR_SD_WORKDIR_FAIL "workDir open failed"
|
#define STR_SD_WORKDIR_FAIL "workDir open failed"
|
||||||
#define STR_SD_OPEN_FILE_FAIL "open failed, File: "
|
#define STR_SD_OPEN_FILE_FAIL "open failed, File: "
|
||||||
#define STR_SD_FILE_OPENED "File opened: "
|
#define STR_SD_FILE_OPENED "File opened: "
|
||||||
@@ -227,10 +228,6 @@
|
|||||||
#define STR_PID_DEBUG " PID_DEBUG "
|
#define STR_PID_DEBUG " PID_DEBUG "
|
||||||
#define STR_PID_DEBUG_INPUT ": Input "
|
#define STR_PID_DEBUG_INPUT ": Input "
|
||||||
#define STR_PID_DEBUG_OUTPUT " Output "
|
#define STR_PID_DEBUG_OUTPUT " Output "
|
||||||
#define STR_PID_DEBUG_PTERM " pTerm "
|
|
||||||
#define STR_PID_DEBUG_ITERM " iTerm "
|
|
||||||
#define STR_PID_DEBUG_DTERM " dTerm "
|
|
||||||
#define STR_PID_DEBUG_CTERM " cTerm "
|
|
||||||
#define STR_INVALID_EXTRUDER_NUM " - Invalid extruder number !"
|
#define STR_INVALID_EXTRUDER_NUM " - Invalid extruder number !"
|
||||||
#define STR_MPC_AUTOTUNE "MPC Autotune"
|
#define STR_MPC_AUTOTUNE "MPC Autotune"
|
||||||
#define STR_MPC_AUTOTUNE_START " start for " STR_E
|
#define STR_MPC_AUTOTUNE_START " start for " STR_E
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if !defined(__has_include)
|
#ifndef __has_include
|
||||||
#define __has_include(...) 1
|
#define __has_include(...) 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -338,6 +338,12 @@
|
|||||||
#define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K)
|
#define GANG_N_1(N,K) _GANG_N(N,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K,K)
|
||||||
|
|
||||||
// Macros for initializing arrays
|
// Macros for initializing arrays
|
||||||
|
#define LIST_26(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z
|
||||||
|
#define LIST_25(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y
|
||||||
|
#define LIST_24(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X
|
||||||
|
#define LIST_23(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W
|
||||||
|
#define LIST_22(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V
|
||||||
|
#define LIST_21(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U
|
||||||
#define LIST_20(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T
|
#define LIST_20(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T
|
||||||
#define LIST_19(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S
|
#define LIST_19(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S
|
||||||
#define LIST_18(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R
|
#define LIST_18(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,...) A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R
|
||||||
@@ -644,8 +650,8 @@
|
|||||||
#define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0
|
#define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0
|
||||||
#define PROBE() ~, 1 // Second item will be 1 if this is passed
|
#define PROBE() ~, 1 // Second item will be 1 if this is passed
|
||||||
#define _NOT_0 PROBE()
|
#define _NOT_0 PROBE()
|
||||||
#define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'.
|
#define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'.
|
||||||
#define _BOOL(x) NOT(NOT(x)) // NOT('0') gets '0'. Anything else gets '1'.
|
#define _BOOL(x) NOT(NOT(x)) // _BOOL('0') gets '0'. Anything else gets '1'.
|
||||||
|
|
||||||
#define IF_ELSE(TF) _IF_ELSE(_BOOL(TF))
|
#define IF_ELSE(TF) _IF_ELSE(_BOOL(TF))
|
||||||
#define _IF_ELSE(TF) _CAT(_IF_, TF)
|
#define _IF_ELSE(TF) _CAT(_IF_, TF)
|
||||||
@@ -659,7 +665,6 @@
|
|||||||
#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
|
#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
|
||||||
#define _END_OF_ARGUMENTS_() 0
|
#define _END_OF_ARGUMENTS_() 0
|
||||||
|
|
||||||
|
|
||||||
// Simple Inline IF Macros, friendly to use in other macro definitions
|
// Simple Inline IF Macros, friendly to use in other macro definitions
|
||||||
#define IF(O, A, B) ((O) ? (A) : (B))
|
#define IF(O, A, B) ((O) ? (A) : (B))
|
||||||
#define IF_0(O, A) IF(O, A, 0)
|
#define IF_0(O, A) IF(O, A, 0)
|
||||||
@@ -731,3 +736,9 @@
|
|||||||
#define __MAPLIST() _MAPLIST
|
#define __MAPLIST() _MAPLIST
|
||||||
|
|
||||||
#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V))
|
#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V))
|
||||||
|
|
||||||
|
// Temperature Sensor Config
|
||||||
|
#define TEMP_SENSOR(N) TEMP_SENSOR_##N
|
||||||
|
#define _HAS_E_TEMP(N) || TEMP_SENSOR(N)
|
||||||
|
#define HAS_E_TEMP_SENSOR (0 REPEAT(EXTRUDERS, _HAS_E_TEMP))
|
||||||
|
#define TEMP_SENSOR_IS_MAX_TC(T) (TEMP_SENSOR(T) == -5 || TEMP_SENSOR(T) == -3 || TEMP_SENSOR(T) == -2)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T"); PGMSTR(NUL_STR, "");
|
|||||||
|
|
||||||
#define _N_STR(N) PGMSTR(N##_STR, STR_##N);
|
#define _N_STR(N) PGMSTR(N##_STR, STR_##N);
|
||||||
#define _N_LBL(N) PGMSTR(N##_LBL, STR_##N ":");
|
#define _N_LBL(N) PGMSTR(N##_LBL, STR_##N ":");
|
||||||
#define _SP_N_STR(N) PGMSTR(SP_##N##_STR, STR_##N ":");
|
#define _SP_N_STR(N) PGMSTR(SP_##N##_STR, " " STR_##N);
|
||||||
#define _SP_N_LBL(N) PGMSTR(SP_##N##_LBL, " " STR_##N ":");
|
#define _SP_N_LBL(N) PGMSTR(SP_##N##_LBL, " " STR_##N ":");
|
||||||
MAP(_N_STR, LOGICAL_AXIS_NAMES); MAP(_SP_N_STR, LOGICAL_AXIS_NAMES);
|
MAP(_N_STR, LOGICAL_AXIS_NAMES); MAP(_SP_N_STR, LOGICAL_AXIS_NAMES);
|
||||||
MAP(_N_LBL, LOGICAL_AXIS_NAMES); MAP(_SP_N_LBL, LOGICAL_AXIS_NAMES);
|
MAP(_N_LBL, LOGICAL_AXIS_NAMES); MAP(_SP_N_LBL, LOGICAL_AXIS_NAMES);
|
||||||
@@ -72,8 +72,8 @@ void serial_print_P(PGM_P str) {
|
|||||||
while (const char c = pgm_read_byte(str++)) SERIAL_CHAR(c);
|
while (const char c = pgm_read_byte(str++)) SERIAL_CHAR(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void serial_echo_start() { static PGMSTR(echomagic, "echo:"); serial_print_P(echomagic); }
|
void serial_echo_start() { serial_print(F("echo:")); }
|
||||||
void serial_error_start() { static PGMSTR(errormagic, "Error:"); serial_print_P(errormagic); }
|
void serial_error_start() { serial_print(F("Error:")); }
|
||||||
|
|
||||||
void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); }
|
void serial_spaces(uint8_t count) { count *= (PROPORTIONAL_FONT_RATIO); while (count--) SERIAL_CHAR(' '); }
|
||||||
|
|
||||||
|
|||||||
+21
-17
@@ -113,8 +113,8 @@ struct Flags<1> {
|
|||||||
void set(const int) { b = true; }
|
void set(const int) { b = true; }
|
||||||
void clear(const int) { b = false; }
|
void clear(const int) { b = false; }
|
||||||
bool test(const int) const { return b; }
|
bool test(const int) const { return b; }
|
||||||
bool operator[](const int) { return b; }
|
bool& operator[](const int) { return b; }
|
||||||
bool operator[](const int) const { return b; }
|
bool operator[](const int) const { return b; }
|
||||||
int size() const { return sizeof(b); }
|
int size() const { return sizeof(b); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -347,6 +347,10 @@ struct XYval {
|
|||||||
FI operator T* () { return pos; }
|
FI operator T* () { return pos; }
|
||||||
// If any element is true then it's true
|
// If any element is true then it's true
|
||||||
FI operator bool() { return x || y; }
|
FI operator bool() { return x || y; }
|
||||||
|
// Smallest element
|
||||||
|
FI T _min() const { return _MIN(x, y); }
|
||||||
|
// Largest element
|
||||||
|
FI T _max() const { return _MAX(x, y); }
|
||||||
|
|
||||||
// Explicit copy and copies with conversion
|
// Explicit copy and copies with conversion
|
||||||
FI XYval<T> copy() const { return *this; }
|
FI XYval<T> copy() const { return *this; }
|
||||||
@@ -436,15 +440,9 @@ struct XYval {
|
|||||||
FI XYval<T>& operator<<=(const int &v) { _LS(x); _LS(y); return *this; }
|
FI XYval<T>& operator<<=(const int &v) { _LS(x); _LS(y); return *this; }
|
||||||
|
|
||||||
// Exact comparisons. For floats a "NEAR" operation may be better.
|
// Exact comparisons. For floats a "NEAR" operation may be better.
|
||||||
FI bool operator==(const XYval<T> &rs) { return x == rs.x && y == rs.y; }
|
|
||||||
FI bool operator==(const XYZval<T> &rs) { return x == rs.x && y == rs.y; }
|
|
||||||
FI bool operator==(const XYZEval<T> &rs) { return x == rs.x && y == rs.y; }
|
|
||||||
FI bool operator==(const XYval<T> &rs) const { return x == rs.x && y == rs.y; }
|
FI bool operator==(const XYval<T> &rs) const { return x == rs.x && y == rs.y; }
|
||||||
FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y; }
|
FI bool operator==(const XYZval<T> &rs) const { return x == rs.x && y == rs.y; }
|
||||||
FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y; }
|
FI bool operator==(const XYZEval<T> &rs) const { return x == rs.x && y == rs.y; }
|
||||||
FI bool operator!=(const XYval<T> &rs) { return !operator==(rs); }
|
|
||||||
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
|
|
||||||
FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); }
|
|
||||||
FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); }
|
FI bool operator!=(const XYval<T> &rs) const { return !operator==(rs); }
|
||||||
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
||||||
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
||||||
@@ -494,10 +492,10 @@ struct XYZval {
|
|||||||
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; }
|
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; }
|
||||||
#endif
|
#endif
|
||||||
#if HAS_V_AXIS
|
#if HAS_V_AXIS
|
||||||
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; }
|
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; }
|
||||||
#endif
|
#endif
|
||||||
#if HAS_W_AXIS
|
#if HAS_W_AXIS
|
||||||
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm, const T po) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; v = pv; }
|
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu, const T pv) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; v = pv; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Length reduced to one dimension
|
// Length reduced to one dimension
|
||||||
@@ -506,6 +504,10 @@ struct XYZval {
|
|||||||
FI operator T* () { return pos; }
|
FI operator T* () { return pos; }
|
||||||
// If any element is true then it's true
|
// If any element is true then it's true
|
||||||
FI operator bool() { return NUM_AXIS_GANG(x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
FI operator bool() { return NUM_AXIS_GANG(x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
||||||
|
// Smallest element
|
||||||
|
FI T _min() const { return _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)); }
|
||||||
|
// Largest element
|
||||||
|
FI T _max() const { return _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)); }
|
||||||
|
|
||||||
// Explicit copy and copies with conversion
|
// Explicit copy and copies with conversion
|
||||||
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
|
FI XYZval<T> copy() const { XYZval<T> o = *this; return o; }
|
||||||
@@ -599,9 +601,7 @@ struct XYZval {
|
|||||||
FI XYZval<T>& operator<<=(const int &v) { NUM_AXIS_CODE(_LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; }
|
FI XYZval<T>& operator<<=(const int &v) { NUM_AXIS_CODE(_LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; }
|
||||||
|
|
||||||
// Exact comparisons. For floats a "NEAR" operation may be better.
|
// Exact comparisons. For floats a "NEAR" operation may be better.
|
||||||
FI bool operator==(const XYZEval<T> &rs) { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
|
||||||
FI bool operator==(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
FI bool operator==(const XYZEval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
||||||
FI bool operator!=(const XYZEval<T> &rs) { return !operator==(rs); }
|
|
||||||
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -634,10 +634,10 @@ struct XYZEval {
|
|||||||
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; }
|
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; }
|
||||||
#endif
|
#endif
|
||||||
#if HAS_V_AXIS
|
#if HAS_V_AXIS
|
||||||
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; }
|
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; }
|
||||||
#endif
|
#endif
|
||||||
#if HAS_W_AXIS
|
#if HAS_W_AXIS
|
||||||
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pm, const T po) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pm; v = pv; }
|
FI void set(const T px, const T py, const T pz, const T pi, const T pj, const T pk, const T pu, const T pv) { x = px; y = py; z = pz; i = pi; j = pj; k = pk; u = pu; v = pv; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Setters taking struct types and arrays
|
// Setters taking struct types and arrays
|
||||||
@@ -659,6 +659,10 @@ struct XYZEval {
|
|||||||
FI operator T* () { return pos; }
|
FI operator T* () { return pos; }
|
||||||
// If any element is true then it's true
|
// If any element is true then it's true
|
||||||
FI operator bool() { return 0 LOGICAL_AXIS_GANG(|| e, || x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
FI operator bool() { return 0 LOGICAL_AXIS_GANG(|| e, || x, || y, || z, || i, || j, || k, || u, || v, || w); }
|
||||||
|
// Smallest element
|
||||||
|
FI T _min() const { return _MIN(LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)); }
|
||||||
|
// Largest element
|
||||||
|
FI T _max() const { return _MAX(LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w)); }
|
||||||
|
|
||||||
// Explicit copy and copies with conversion
|
// Explicit copy and copies with conversion
|
||||||
FI XYZEval<T> copy() const { XYZEval<T> v = *this; return v; }
|
FI XYZEval<T> copy() const { XYZEval<T> v = *this; return v; }
|
||||||
@@ -688,7 +692,7 @@ struct XYZEval {
|
|||||||
FI const T& operator[](const int n) const { return pos[n]; }
|
FI const T& operator[](const int n) const { return pos[n]; }
|
||||||
|
|
||||||
// Assignment operator overrides do the expected thing
|
// Assignment operator overrides do the expected thing
|
||||||
FI XYZEval<T>& operator= (const T v) { set(LIST_N_1(NUM_AXES, v)); return *this; }
|
FI XYZEval<T>& operator= (const T v) { set(LOGICAL_AXIS_LIST_1(v)); return *this; }
|
||||||
FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; }
|
FI XYZEval<T>& operator= (const XYval<T> &rs) { set(rs.x, rs.y); return *this; }
|
||||||
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(NUM_AXIS_ELEM(rs)); return *this; }
|
FI XYZEval<T>& operator= (const XYZval<T> &rs) { set(NUM_AXIS_ELEM(rs)); return *this; }
|
||||||
|
|
||||||
@@ -750,10 +754,10 @@ struct XYZEval {
|
|||||||
FI XYZEval<T>& operator<<=(const int &v) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; }
|
FI XYZEval<T>& operator<<=(const int &v) { LOGICAL_AXIS_CODE(_LS(e), _LS(x), _LS(y), _LS(z), _LS(i), _LS(j), _LS(k), _LS(u), _LS(v), _LS(w)); return *this; }
|
||||||
|
|
||||||
// Exact comparisons. For floats a "NEAR" operation may be better.
|
// Exact comparisons. For floats a "NEAR" operation may be better.
|
||||||
FI bool operator==(const XYZval<T> &rs) { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
|
||||||
FI bool operator==(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
FI bool operator==(const XYZval<T> &rs) const { return true NUM_AXIS_GANG(&& x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
||||||
FI bool operator!=(const XYZval<T> &rs) { return !operator==(rs); }
|
FI bool operator==(const XYZEval<T> &rs) const { return true LOGICAL_AXIS_GANG(&& e == rs.e, && x == rs.x, && y == rs.y, && z == rs.z, && i == rs.i, && j == rs.j, && k == rs.k, && u == rs.u, && v == rs.v, && w == rs.w); }
|
||||||
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
FI bool operator!=(const XYZval<T> &rs) const { return !operator==(rs); }
|
||||||
|
FI bool operator!=(const XYZEval<T> &rs) const { return !operator==(rs); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#undef _RECIP
|
#undef _RECIP
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ void safe_delay(millis_t ms) {
|
|||||||
while (ms > 50) {
|
while (ms > 50) {
|
||||||
ms -= 50;
|
ms -= 50;
|
||||||
delay(50);
|
delay(50);
|
||||||
thermalManager.manage_heater();
|
thermalManager.task();
|
||||||
}
|
}
|
||||||
delay(ms);
|
delay(ms);
|
||||||
thermalManager.manage_heater(); // This keeps us safe if too many small safe_delay() calls are made
|
thermalManager.task(); // This keeps us safe if too many small safe_delay() calls are made
|
||||||
}
|
}
|
||||||
|
|
||||||
// A delay to provide brittle hosts time to receive bytes
|
// A delay to provide brittle hosts time to receive bytes
|
||||||
@@ -51,7 +51,7 @@ void safe_delay(millis_t ms) {
|
|||||||
|
|
||||||
#include "../module/probe.h"
|
#include "../module/probe.h"
|
||||||
#include "../module/motion.h"
|
#include "../module/motion.h"
|
||||||
#include "../module/stepper.h"
|
#include "../module/planner.h"
|
||||||
#include "../libs/numtostr.h"
|
#include "../libs/numtostr.h"
|
||||||
#include "../feature/bedlevel/bedlevel.h"
|
#include "../feature/bedlevel/bedlevel.h"
|
||||||
|
|
||||||
@@ -70,6 +70,7 @@ void safe_delay(millis_t ms) {
|
|||||||
TERN_(NOZZLE_AS_PROBE, "NOZZLE_AS_PROBE")
|
TERN_(NOZZLE_AS_PROBE, "NOZZLE_AS_PROBE")
|
||||||
TERN_(FIX_MOUNTED_PROBE, "FIX_MOUNTED_PROBE")
|
TERN_(FIX_MOUNTED_PROBE, "FIX_MOUNTED_PROBE")
|
||||||
TERN_(HAS_Z_SERVO_PROBE, TERN(BLTOUCH, "BLTOUCH", "SERVO PROBE"))
|
TERN_(HAS_Z_SERVO_PROBE, TERN(BLTOUCH, "BLTOUCH", "SERVO PROBE"))
|
||||||
|
TERN_(BD_SENSOR, "BD_SENSOR")
|
||||||
TERN_(TOUCH_MI_PROBE, "TOUCH_MI_PROBE")
|
TERN_(TOUCH_MI_PROBE, "TOUCH_MI_PROBE")
|
||||||
TERN_(Z_PROBE_SLED, "Z_PROBE_SLED")
|
TERN_(Z_PROBE_SLED, "Z_PROBE_SLED")
|
||||||
TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY")
|
TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY")
|
||||||
@@ -132,11 +133,10 @@ void safe_delay(millis_t ms) {
|
|||||||
#else
|
#else
|
||||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||||
SERIAL_ECHOPGM("UBL Adjustment Z");
|
SERIAL_ECHOPGM("UBL Adjustment Z");
|
||||||
const float rz = bedlevel.get_z_correction(current_position);
|
|
||||||
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
|
||||||
SERIAL_ECHOPGM("ABL Adjustment Z");
|
SERIAL_ECHOPGM("ABL Adjustment Z");
|
||||||
const float rz = bedlevel.get_z_correction(current_position);
|
|
||||||
#endif
|
#endif
|
||||||
|
const float rz = bedlevel.get_z_correction(current_position);
|
||||||
SERIAL_ECHO(ftostr43sign(rz, '+'));
|
SERIAL_ECHO(ftostr43sign(rz, '+'));
|
||||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||||
if (planner.z_fade_height) {
|
if (planner.z_fade_height) {
|
||||||
@@ -156,11 +156,13 @@ void safe_delay(millis_t ms) {
|
|||||||
SERIAL_ECHOPGM("Mesh Bed Leveling");
|
SERIAL_ECHOPGM("Mesh Bed Leveling");
|
||||||
if (planner.leveling_active) {
|
if (planner.leveling_active) {
|
||||||
SERIAL_ECHOLNPGM(" (enabled)");
|
SERIAL_ECHOLNPGM(" (enabled)");
|
||||||
SERIAL_ECHOPGM("MBL Adjustment Z", ftostr43sign(bedlevel.get_z(current_position), '+'));
|
const float z_offset = bedlevel.get_z_offset(),
|
||||||
|
z_correction = bedlevel.get_z_correction(current_position);
|
||||||
|
SERIAL_ECHOPGM("MBL Adjustment Z", ftostr43sign(z_offset + z_correction, '+'));
|
||||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||||
if (planner.z_fade_height) {
|
if (planner.z_fade_height) {
|
||||||
SERIAL_ECHOPGM(" (", ftostr43sign(
|
SERIAL_ECHOPGM(" (", ftostr43sign(
|
||||||
bedlevel.get_z(current_position, planner.fade_scaling_factor_for_z(current_position.z)), '+'
|
z_offset + z_correction * planner.fade_scaling_factor_for_z(current_position.z), '+'
|
||||||
));
|
));
|
||||||
SERIAL_CHAR(')');
|
SERIAL_CHAR(')');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ void safe_delay(millis_t ms); // Delay ensuring that temperatures are
|
|||||||
#define log_machine_info() NOOP
|
#define log_machine_info() NOOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A restorer instance remembers a variable's value before setting a
|
||||||
|
* new value, then restores the old value when it goes out of scope.
|
||||||
|
* Put operator= on your type to get extended behavior on value change.
|
||||||
|
*/
|
||||||
template<typename T>
|
template<typename T>
|
||||||
class restorer {
|
class restorer {
|
||||||
T& ref_;
|
T& ref_;
|
||||||
|
|||||||
@@ -54,6 +54,18 @@ void Babystep::add_mm(const AxisEnum axis, const_float_t mm) {
|
|||||||
add_steps(axis, mm * planner.settings.axis_steps_per_mm[axis]);
|
add_steps(axis, mm * planner.settings.axis_steps_per_mm[axis]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if ENABLED(BD_SENSOR)
|
||||||
|
void Babystep::set_mm(const AxisEnum axis, const_float_t mm) {
|
||||||
|
//if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axes_should_home(_BV(axis))) return;
|
||||||
|
const int16_t distance = mm * planner.settings.axis_steps_per_mm[axis];
|
||||||
|
accum = distance; // Count up babysteps for the UI
|
||||||
|
steps[BS_AXIS_IND(axis)] = distance;
|
||||||
|
TERN_(BABYSTEP_DISPLAY_TOTAL, axis_total[BS_TOTAL_IND(axis)] = distance);
|
||||||
|
TERN_(BABYSTEP_ALWAYS_AVAILABLE, gcode.reset_stepper_timeout());
|
||||||
|
TERN_(INTEGRATED_BABYSTEPPING, if (has_steps()) stepper.initiateBabystepping());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void Babystep::add_steps(const AxisEnum axis, const int16_t distance) {
|
void Babystep::add_steps(const AxisEnum axis, const int16_t distance) {
|
||||||
if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axes_should_home(_BV(axis))) return;
|
if (DISABLED(BABYSTEP_WITHOUT_HOMING) && axes_should_home(_BV(axis))) return;
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,10 @@ public:
|
|||||||
static void add_steps(const AxisEnum axis, const int16_t distance);
|
static void add_steps(const AxisEnum axis, const int16_t distance);
|
||||||
static void add_mm(const AxisEnum axis, const_float_t mm);
|
static void add_mm(const AxisEnum axis, const_float_t mm);
|
||||||
|
|
||||||
|
#if ENABLED(BD_SENSOR)
|
||||||
|
static void set_mm(const AxisEnum axis, const_float_t mm);
|
||||||
|
#endif
|
||||||
|
|
||||||
static bool has_steps() {
|
static bool has_steps() {
|
||||||
return steps[BS_AXIS_IND(X_AXIS)] || steps[BS_AXIS_IND(Y_AXIS)] || steps[BS_AXIS_IND(Z_AXIS)];
|
return steps[BS_AXIS_IND(X_AXIS)] || steps[BS_AXIS_IND(Y_AXIS)] || steps[BS_AXIS_IND(Z_AXIS)];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
|
#if ENABLED(BD_SENSOR)
|
||||||
|
|
||||||
|
#include "../../../MarlinCore.h"
|
||||||
|
#include "../../../gcode/gcode.h"
|
||||||
|
#include "../../../module/settings.h"
|
||||||
|
#include "../../../module/motion.h"
|
||||||
|
#include "../../../module/planner.h"
|
||||||
|
#include "../../../module/stepper.h"
|
||||||
|
#include "../../../module/probe.h"
|
||||||
|
#include "../../../module/temperature.h"
|
||||||
|
#include "../../../module/endstops.h"
|
||||||
|
#include "../../babystep.h"
|
||||||
|
|
||||||
|
// I2C software Master library for segment bed heating and bed distance sensor
|
||||||
|
#include <Panda_segmentBed_I2C.h>
|
||||||
|
|
||||||
|
#include "bdl.h"
|
||||||
|
BDS_Leveling bdl;
|
||||||
|
|
||||||
|
//#define DEBUG_OUT_BD
|
||||||
|
|
||||||
|
// M102 S-5 Read raw Calibrate data
|
||||||
|
// M102 S-6 Start Calibrate
|
||||||
|
// M102 S4 Set the adjustable Z height value (e.g., 'M102 S4' means it will do adjusting while the Z height <= 0.4mm , disable with 'M102 S0'.)
|
||||||
|
// M102 S-1 Read sensor information
|
||||||
|
|
||||||
|
#define MAX_BD_HEIGHT 4.0f
|
||||||
|
#define CMD_START_READ_CALIBRATE_DATA 1017
|
||||||
|
#define CMD_END_READ_CALIBRATE_DATA 1018
|
||||||
|
#define CMD_START_CALIBRATE 1019
|
||||||
|
#define CMD_END_CALIBRATE 1021
|
||||||
|
#define CMD_READ_VERSION 1016
|
||||||
|
|
||||||
|
I2C_SegmentBED BD_I2C_SENSOR;
|
||||||
|
|
||||||
|
#define BD_SENSOR_I2C_ADDR 0x3C
|
||||||
|
|
||||||
|
int8_t BDS_Leveling::config_state;
|
||||||
|
uint8_t BDS_Leveling::homing;
|
||||||
|
|
||||||
|
void BDS_Leveling::echo_name() { SERIAL_ECHOPGM("Bed Distance Leveling"); }
|
||||||
|
|
||||||
|
void BDS_Leveling::init(uint8_t _sda, uint8_t _scl, uint16_t delay_s) {
|
||||||
|
int ret = BD_I2C_SENSOR.i2c_init(_sda, _scl, BD_SENSOR_I2C_ADDR, delay_s);
|
||||||
|
if (ret != 1) SERIAL_ECHOLNPGM("BD_I2C_SENSOR Init Fail return code:", ret);
|
||||||
|
config_state = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
float BDS_Leveling::read() {
|
||||||
|
const uint16_t tmp = BD_I2C_SENSOR.BD_i2c_read();
|
||||||
|
float BD_z = NAN;
|
||||||
|
if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) && (tmp & 0x3FF) < 1020)
|
||||||
|
BD_z = (tmp & 0x3FF) / 100.0f;
|
||||||
|
return BD_z;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BDS_Leveling::process() {
|
||||||
|
//if (config_state == 0) return;
|
||||||
|
static millis_t next_check_ms = 0; // starting at T=0
|
||||||
|
static float z_pose = 0.0f;
|
||||||
|
const millis_t ms = millis();
|
||||||
|
if (ELAPSED(ms, next_check_ms)) { // timed out (or first run)
|
||||||
|
next_check_ms = ms + (config_state < 0 ? 1000 : 100); // check at 1Hz or 10Hz
|
||||||
|
|
||||||
|
unsigned short tmp = 0;
|
||||||
|
const float cur_z = planner.get_axis_position_mm(Z_AXIS); //current_position.z
|
||||||
|
static float old_cur_z = cur_z,
|
||||||
|
old_buf_z = current_position.z;
|
||||||
|
|
||||||
|
tmp = BD_I2C_SENSOR.BD_i2c_read();
|
||||||
|
if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) && (tmp & 0x3FF) < 1020) {
|
||||||
|
const float z_sensor = (tmp & 0x3FF) / 100.0f;
|
||||||
|
if (cur_z < 0) config_state = 0;
|
||||||
|
//float abs_z = current_position.z > cur_z ? (current_position.z - cur_z) : (cur_z - current_position.z);
|
||||||
|
#if ENABLED(BABYSTEPPING)
|
||||||
|
if (cur_z < config_state * 0.1f
|
||||||
|
&& config_state > 0
|
||||||
|
&& old_cur_z == cur_z
|
||||||
|
&& old_buf_z == current_position.z
|
||||||
|
&& z_sensor < (MAX_BD_HEIGHT)
|
||||||
|
) {
|
||||||
|
babystep.set_mm(Z_AXIS, cur_z - z_sensor);
|
||||||
|
#if ENABLED(DEBUG_OUT_BD)
|
||||||
|
SERIAL_ECHOLNPGM("BD:", z_sensor, ", Z:", cur_z, "|", current_position.z);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
babystep.set_mm(Z_AXIS, 0); //if (old_cur_z <= cur_z) Z_DIR_WRITE(!INVERT_Z_DIR);
|
||||||
|
stepper.set_directions();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
old_cur_z = cur_z;
|
||||||
|
old_buf_z = current_position.z;
|
||||||
|
endstops.bdp_state_update(z_sensor <= 0.01f);
|
||||||
|
//endstops.update();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
stepper.set_directions();
|
||||||
|
|
||||||
|
#if ENABLED(DEBUG_OUT_BD)
|
||||||
|
SERIAL_ECHOLNPGM("BD:", tmp & 0x3FF, ", Z:", cur_z, "|", current_position.z);
|
||||||
|
if (BD_I2C_SENSOR.BD_Check_OddEven(tmp) == 0) SERIAL_ECHOLNPGM("errorCRC");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if ((tmp & 0x3FF) > 1020) {
|
||||||
|
BD_I2C_SENSOR.BD_i2c_stop();
|
||||||
|
safe_delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read raw calibrate data
|
||||||
|
if (config_state == -5) {
|
||||||
|
BD_I2C_SENSOR.BD_i2c_write(CMD_START_READ_CALIBRATE_DATA);
|
||||||
|
safe_delay(1000);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_BD_HEIGHT * 10; i++) {
|
||||||
|
tmp = BD_I2C_SENSOR.BD_i2c_read();
|
||||||
|
SERIAL_ECHOLNPGM("Calibrate data:", i, ",", tmp & 0x3FF, ", check:", BD_I2C_SENSOR.BD_Check_OddEven(tmp));
|
||||||
|
safe_delay(500);
|
||||||
|
}
|
||||||
|
config_state = 0;
|
||||||
|
BD_I2C_SENSOR.BD_i2c_write(CMD_END_READ_CALIBRATE_DATA);
|
||||||
|
safe_delay(500);
|
||||||
|
}
|
||||||
|
else if (config_state <= -6) { // Start Calibrate
|
||||||
|
safe_delay(100);
|
||||||
|
if (config_state == -6) {
|
||||||
|
//BD_I2C_SENSOR.BD_i2c_write(1019); // begin calibrate
|
||||||
|
//delay(1000);
|
||||||
|
gcode.stepper_inactive_time = SEC_TO_MS(60 * 5);
|
||||||
|
gcode.process_subcommands_now(F("M17 Z"));
|
||||||
|
gcode.process_subcommands_now(F("G1 Z0.0"));
|
||||||
|
z_pose = 0;
|
||||||
|
safe_delay(1000);
|
||||||
|
BD_I2C_SENSOR.BD_i2c_write(CMD_START_CALIBRATE); // Begin calibrate
|
||||||
|
SERIAL_ECHOLNPGM("Begin calibrate");
|
||||||
|
safe_delay(2000);
|
||||||
|
config_state = -7;
|
||||||
|
}
|
||||||
|
else if (planner.get_axis_position_mm(Z_AXIS) < 10.0f) {
|
||||||
|
if (z_pose >= MAX_BD_HEIGHT) {
|
||||||
|
BD_I2C_SENSOR.BD_i2c_write(CMD_END_CALIBRATE); // End calibrate
|
||||||
|
SERIAL_ECHOLNPGM("End calibrate data");
|
||||||
|
z_pose = 7;
|
||||||
|
config_state = 0;
|
||||||
|
safe_delay(1000);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
float tmp_k = 0;
|
||||||
|
char tmp_1[30];
|
||||||
|
sprintf_P(tmp_1, PSTR("G1 Z%d.%d"), int(z_pose), int(int(z_pose * 10) % 10));
|
||||||
|
gcode.process_subcommands_now(tmp_1);
|
||||||
|
|
||||||
|
SERIAL_ECHO(tmp_1);
|
||||||
|
SERIAL_ECHOLNPGM(" ,Z:", current_position.z);
|
||||||
|
|
||||||
|
while (tmp_k < (z_pose - 0.1f)) {
|
||||||
|
tmp_k = planner.get_axis_position_mm(Z_AXIS);
|
||||||
|
safe_delay(1);
|
||||||
|
}
|
||||||
|
safe_delay(800);
|
||||||
|
tmp = (z_pose + 0.0001f) * 10;
|
||||||
|
BD_I2C_SENSOR.BD_i2c_write(tmp);
|
||||||
|
SERIAL_ECHOLNPGM("w:", tmp, ",Zpose:", z_pose);
|
||||||
|
z_pose += 0.1001f;
|
||||||
|
//queue.enqueue_now_P(PSTR("G90"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // BD_SENSOR
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class BDS_Leveling {
|
||||||
|
public:
|
||||||
|
static int8_t config_state;
|
||||||
|
static uint8_t homing;
|
||||||
|
static void echo_name();
|
||||||
|
static void init(uint8_t _sda, uint8_t _scl, uint16_t delay_s);
|
||||||
|
static void process();
|
||||||
|
static float read();
|
||||||
|
};
|
||||||
|
|
||||||
|
extern BDS_Leveling bdl;
|
||||||
@@ -75,9 +75,9 @@ void set_bed_leveling_enabled(const bool enable/*=true*/) {
|
|||||||
planner.synchronize();
|
planner.synchronize();
|
||||||
|
|
||||||
// Get the corrected leveled / unleveled position
|
// Get the corrected leveled / unleveled position
|
||||||
planner.apply_modifiers(current_position); // Physical position with all modifiers
|
planner.apply_modifiers(current_position, true); // Physical position with all modifiers
|
||||||
planner.leveling_active ^= true; // Toggle leveling between apply and unapply
|
planner.leveling_active ^= true; // Toggle leveling between apply and unapply
|
||||||
planner.unapply_modifiers(current_position); // Logical position with modifiers removed
|
planner.unapply_modifiers(current_position, true); // Logical position with modifiers removed
|
||||||
|
|
||||||
sync_plan_position();
|
sync_plan_position();
|
||||||
_report_leveling();
|
_report_leveling();
|
||||||
@@ -154,7 +154,7 @@ void reset_bed_level() {
|
|||||||
#endif
|
#endif
|
||||||
LOOP_L_N(x, sx) {
|
LOOP_L_N(x, sx) {
|
||||||
SERIAL_CHAR(' ');
|
SERIAL_CHAR(' ');
|
||||||
const float offset = values[x * sx + y];
|
const float offset = values[x * sy + y];
|
||||||
if (!isnan(offset)) {
|
if (!isnan(offset)) {
|
||||||
if (offset >= 0) SERIAL_CHAR('+');
|
if (offset >= 0) SERIAL_CHAR('+');
|
||||||
SERIAL_ECHO_F(offset, int(precision));
|
SERIAL_ECHO_F(offset, int(precision));
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
#include "../../../libs/hex_print.h"
|
#include "../../../libs/hex_print.h"
|
||||||
#include "../../../module/settings.h"
|
#include "../../../module/settings.h"
|
||||||
#include "../../../lcd/marlinui.h"
|
#include "../../../lcd/marlinui.h"
|
||||||
#include "../../../module/stepper.h"
|
|
||||||
#include "../../../module/planner.h"
|
#include "../../../module/planner.h"
|
||||||
#include "../../../module/motion.h"
|
#include "../../../module/motion.h"
|
||||||
#include "../../../module/probe.h"
|
#include "../../../module/probe.h"
|
||||||
@@ -408,7 +407,7 @@ void unified_bed_leveling::G29() {
|
|||||||
z_values[x][x2] += 9.999f; // We want the altered line several mesh points thick
|
z_values[x][x2] += 9.999f; // We want the altered line several mesh points thick
|
||||||
#if ENABLED(EXTENSIBLE_UI)
|
#if ENABLED(EXTENSIBLE_UI)
|
||||||
ExtUI::onMeshUpdate(x, x, z_values[x][x]);
|
ExtUI::onMeshUpdate(x, x, z_values[x][x]);
|
||||||
ExtUI::onMeshUpdate(x, (x2), z_values[x][x2]);
|
ExtUI::onMeshUpdate(x, x2, z_values[x][x2]);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -26,7 +26,6 @@
|
|||||||
|
|
||||||
#include "../bedlevel.h"
|
#include "../bedlevel.h"
|
||||||
#include "../../../module/planner.h"
|
#include "../../../module/planner.h"
|
||||||
#include "../../../module/stepper.h"
|
|
||||||
#include "../../../module/motion.h"
|
#include "../../../module/motion.h"
|
||||||
|
|
||||||
#if ENABLED(DELTA)
|
#if ENABLED(DELTA)
|
||||||
@@ -36,8 +35,18 @@
|
|||||||
#include "../../../MarlinCore.h"
|
#include "../../../MarlinCore.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
//#define DEBUG_UBL_MOTION
|
||||||
|
#define DEBUG_OUT ENABLED(DEBUG_UBL_MOTION)
|
||||||
|
#include "../../../core/debug_out.h"
|
||||||
|
|
||||||
#if !UBL_SEGMENTED
|
#if !UBL_SEGMENTED
|
||||||
|
|
||||||
|
// TODO: The first and last parts of a move might result in very short segment(s)
|
||||||
|
// after getting split on the cell boundary, so moves like that should not
|
||||||
|
// get split. This will be most common for moves that start/end near the
|
||||||
|
// corners of cells. To fix the issue, simply check if the start/end of the line
|
||||||
|
// is very close to a cell boundary in advance and don't split the line there.
|
||||||
|
|
||||||
void unified_bed_leveling::line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const uint8_t extruder) {
|
void unified_bed_leveling::line_to_destination_cartesian(const_feedRate_t scaled_fr_mm_s, const uint8_t extruder) {
|
||||||
/**
|
/**
|
||||||
* Much of the nozzle movement will be within the same cell. So we will do as little computation
|
* Much of the nozzle movement will be within the same cell. So we will do as little computation
|
||||||
@@ -176,7 +185,9 @@
|
|||||||
dest.z += z0;
|
dest.z += z0;
|
||||||
planner.buffer_segment(dest, scaled_fr_mm_s, extruder);
|
planner.buffer_segment(dest, scaled_fr_mm_s, extruder);
|
||||||
|
|
||||||
} //else printf("FIRST MOVE PRUNED ");
|
}
|
||||||
|
else
|
||||||
|
DEBUG_ECHOLNPGM("[ubl] skip Y segment");
|
||||||
}
|
}
|
||||||
|
|
||||||
// At the final destination? Usually not, but when on a Y Mesh Line it's completed.
|
// At the final destination? Usually not, but when on a Y Mesh Line it's completed.
|
||||||
@@ -225,7 +236,9 @@
|
|||||||
dest.z += z0;
|
dest.z += z0;
|
||||||
if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break;
|
if (!planner.buffer_segment(dest, scaled_fr_mm_s, extruder)) break;
|
||||||
|
|
||||||
} //else printf("FIRST MOVE PRUNED ");
|
}
|
||||||
|
else
|
||||||
|
DEBUG_ECHOLNPGM("[ubl] skip Y segment");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xy_pos_t(current_position) != xy_pos_t(end))
|
if (xy_pos_t(current_position) != xy_pos_t(end))
|
||||||
@@ -360,11 +373,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NOLESS(segments, 1U); // Must have at least one segment
|
NOLESS(segments, 1U); // Must have at least one segment
|
||||||
const float inv_segments = 1.0f / segments, // Reciprocal to save calculation
|
const float inv_segments = 1.0f / segments; // Reciprocal to save calculation
|
||||||
segment_xyz_mm = SQRT(cart_xy_mm_2 + sq(total.z)) * inv_segments; // Length of each segment
|
|
||||||
|
|
||||||
|
// Add hints to help optimize the move
|
||||||
|
PlannerHints hints(SQRT(cart_xy_mm_2 + sq(total.z)) * inv_segments); // Length of each segment
|
||||||
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
#if ENABLED(SCARA_FEEDRATE_SCALING)
|
||||||
const float inv_duration = scaled_fr_mm_s / segment_xyz_mm;
|
hints.inv_duration = scaled_fr_mm_s / hints.millimeters;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
xyze_float_t diff = total * inv_segments;
|
xyze_float_t diff = total * inv_segments;
|
||||||
@@ -378,13 +392,9 @@
|
|||||||
if (!planner.leveling_active || !planner.leveling_active_at_z(destination.z)) {
|
if (!planner.leveling_active || !planner.leveling_active_at_z(destination.z)) {
|
||||||
while (--segments) {
|
while (--segments) {
|
||||||
raw += diff;
|
raw += diff;
|
||||||
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, segment_xyz_mm
|
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, hints);
|
||||||
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder, segment_xyz_mm
|
planner.buffer_line(destination, scaled_fr_mm_s, active_extruder, hints);
|
||||||
OPTARG(SCARA_FEEDRATE_SCALING, inv_duration)
|
|
||||||
);
|
|
||||||
return false; // Did not set current from destination
|
return false; // Did not set current from destination
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,10 +423,12 @@
|
|||||||
LIMIT(icell.x, 0, GRID_MAX_CELLS_X);
|
LIMIT(icell.x, 0, GRID_MAX_CELLS_X);
|
||||||
LIMIT(icell.y, 0, GRID_MAX_CELLS_Y);
|
LIMIT(icell.y, 0, GRID_MAX_CELLS_Y);
|
||||||
|
|
||||||
float z_x0y0 = z_values[icell.x ][icell.y ], // z at lower left corner
|
const int8_t ncellx = _MIN(icell.x+1, GRID_MAX_CELLS_X),
|
||||||
z_x1y0 = z_values[icell.x+1][icell.y ], // z at upper left corner
|
ncelly = _MIN(icell.y+1, GRID_MAX_CELLS_Y);
|
||||||
z_x0y1 = z_values[icell.x ][icell.y+1], // z at lower right corner
|
float z_x0y0 = z_values[icell.x][icell.y], // z at lower left corner
|
||||||
z_x1y1 = z_values[icell.x+1][icell.y+1]; // z at upper right corner
|
z_x1y0 = z_values[ncellx ][icell.y], // z at upper left corner
|
||||||
|
z_x0y1 = z_values[icell.x][ncelly ], // z at lower right corner
|
||||||
|
z_x1y1 = z_values[ncellx ][ncelly ]; // z at upper right corner
|
||||||
|
|
||||||
if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_active (G29 A)
|
if (isnan(z_x0y0)) z_x0y0 = 0; // ideally activating planner.leveling_active (G29 A)
|
||||||
if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points
|
if (isnan(z_x1y0)) z_x1y0 = 0; // should refuse if any invalid mesh points
|
||||||
@@ -453,7 +465,7 @@
|
|||||||
TERN_(ENABLE_LEVELING_FADE_HEIGHT, * fade_scaling_factor); // apply fade factor to interpolated height
|
TERN_(ENABLE_LEVELING_FADE_HEIGHT, * fade_scaling_factor); // apply fade factor to interpolated height
|
||||||
|
|
||||||
const float oldz = raw.z; raw.z += z_cxcy;
|
const float oldz = raw.z; raw.z += z_cxcy;
|
||||||
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, segment_xyz_mm OPTARG(SCARA_FEEDRATE_SCALING, inv_duration) );
|
planner.buffer_line(raw, scaled_fr_mm_s, active_extruder, hints);
|
||||||
raw.z = oldz;
|
raw.z = oldz;
|
||||||
|
|
||||||
if (segments == 0) // done with last segment
|
if (segments == 0) // done with last segment
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ void stop();
|
|||||||
|
|
||||||
bool BLTouch::command(const BLTCommand cmd, const millis_t &ms) {
|
bool BLTouch::command(const BLTCommand cmd, const millis_t &ms) {
|
||||||
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("BLTouch Command :", cmd);
|
if (DEBUGGING(LEVELING)) SERIAL_ECHOLNPGM("BLTouch Command :", cmd);
|
||||||
MOVE_SERVO(Z_PROBE_SERVO_NR, cmd);
|
servo[Z_PROBE_SERVO_NR].move(cmd);
|
||||||
safe_delay(_MAX(ms, (uint32_t)BLTOUCH_DELAY)); // BLTOUCH_DELAY is also the *minimum* delay
|
safe_delay(_MAX(ms, (uint32_t)BLTOUCH_DELAY)); // BLTOUCH_DELAY is also the *minimum* delay
|
||||||
return triggered();
|
return triggered();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,6 +72,22 @@ void ControllerFan::update() {
|
|||||||
? settings.active_speed : settings.idle_speed
|
? settings.active_speed : settings.idle_speed
|
||||||
);
|
);
|
||||||
|
|
||||||
|
speed = CALC_FAN_SPEED(speed);
|
||||||
|
|
||||||
|
#if FAN_KICKSTART_TIME
|
||||||
|
static millis_t fan_kick_end = 0;
|
||||||
|
if (speed > FAN_OFF_PWM) {
|
||||||
|
if (!fan_kick_end) {
|
||||||
|
fan_kick_end = ms + FAN_KICKSTART_TIME; // May be longer based on slow update interval for controller fn check. Sets minimum
|
||||||
|
speed = FAN_KICKSTART_POWER;
|
||||||
|
}
|
||||||
|
else if (PENDING(ms, fan_kick_end))
|
||||||
|
speed = FAN_KICKSTART_POWER;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
fan_kick_end = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(FAN_SOFT_PWM)
|
#if ENABLED(FAN_SOFT_PWM)
|
||||||
thermalManager.soft_pwm_controller_speed = speed;
|
thermalManager.soft_pwm_controller_speed = speed;
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include "dac_dac084s085.h"
|
#include "dac_dac084s085.h"
|
||||||
|
|
||||||
#include "../../MarlinCore.h"
|
#include "../../MarlinCore.h"
|
||||||
#include "../../module/stepper.h"
|
|
||||||
#include "../../HAL/shared/Delay.h"
|
#include "../../HAL/shared/Delay.h"
|
||||||
|
|
||||||
dac084s085::dac084s085() { }
|
dac084s085::dac084s085() { }
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#if HAS_MOTOR_CURRENT_DAC
|
#if HAS_MOTOR_CURRENT_DAC
|
||||||
|
|
||||||
#include "stepper_dac.h"
|
#include "stepper_dac.h"
|
||||||
#include "../../MarlinCore.h" // for SP_X_LBL...
|
|
||||||
|
|
||||||
bool dac_present = false;
|
bool dac_present = false;
|
||||||
constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
|
constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
|
||||||
|
|||||||
@@ -143,14 +143,16 @@ namespace DirectStepping {
|
|||||||
// special case for 8-bit, check if rolled back to 0
|
// special case for 8-bit, check if rolled back to 0
|
||||||
if (Cfg::DIRECTIONAL || !write_page_size) { // full 256 bytes
|
if (Cfg::DIRECTIONAL || !write_page_size) { // full 256 bytes
|
||||||
if (write_byte_idx) return true;
|
if (write_byte_idx) return true;
|
||||||
} else {
|
|
||||||
if (write_byte_idx < write_page_size) return true;
|
|
||||||
}
|
}
|
||||||
} else if (Cfg::DIRECTIONAL) {
|
else if (write_byte_idx < write_page_size)
|
||||||
if (write_byte_idx != Cfg::PAGE_SIZE) return true;
|
return true;
|
||||||
} else {
|
|
||||||
if (write_byte_idx < write_page_size) return true;
|
|
||||||
}
|
}
|
||||||
|
else if (Cfg::DIRECTIONAL) {
|
||||||
|
if (write_byte_idx != Cfg::PAGE_SIZE)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (write_byte_idx < write_page_size)
|
||||||
|
return true;
|
||||||
|
|
||||||
state = State::CHECKSUM;
|
state = State::CHECKSUM;
|
||||||
return true;
|
return true;
|
||||||
@@ -161,11 +163,10 @@ namespace DirectStepping {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case State::UNFAIL:
|
case State::UNFAIL:
|
||||||
if (c == 0) {
|
if (c == 0)
|
||||||
set_page_state(write_page_idx, PageState::FREE);
|
set_page_state(write_page_idx, PageState::FREE);
|
||||||
} else {
|
else
|
||||||
fatal_error = true;
|
fatal_error = true;
|
||||||
}
|
|
||||||
state = State::MONITOR;
|
state = State::MONITOR;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,9 @@
|
|||||||
// Static data members
|
// Static data members
|
||||||
bool EmergencyParser::killed_by_M112, // = false
|
bool EmergencyParser::killed_by_M112, // = false
|
||||||
EmergencyParser::quickstop_by_M410,
|
EmergencyParser::quickstop_by_M410,
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
EmergencyParser::sd_abort_by_M524,
|
||||||
|
#endif
|
||||||
EmergencyParser::enabled;
|
EmergencyParser::enabled;
|
||||||
|
|
||||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ class EmergencyParser {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Currently looking for: M108, M112, M410, M876 S[0-9], S000, P000, R000
|
// Currently looking for: M108, M112, M410, M524, M876 S[0-9], S000, P000, R000
|
||||||
enum State : uint8_t {
|
enum State : uint8_t {
|
||||||
EP_RESET,
|
EP_RESET,
|
||||||
EP_N,
|
EP_N,
|
||||||
@@ -58,6 +58,9 @@ public:
|
|||||||
EP_M10, EP_M108,
|
EP_M10, EP_M108,
|
||||||
EP_M11, EP_M112,
|
EP_M11, EP_M112,
|
||||||
EP_M4, EP_M41, EP_M410,
|
EP_M4, EP_M41, EP_M410,
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
EP_M5, EP_M52, EP_M524,
|
||||||
|
#endif
|
||||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN,
|
EP_M8, EP_M87, EP_M876, EP_M876S, EP_M876SN,
|
||||||
#endif
|
#endif
|
||||||
@@ -76,6 +79,10 @@ public:
|
|||||||
static bool killed_by_M112;
|
static bool killed_by_M112;
|
||||||
static bool quickstop_by_M410;
|
static bool quickstop_by_M410;
|
||||||
|
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
static bool sd_abort_by_M524;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
static uint8_t M876_reason;
|
static uint8_t M876_reason;
|
||||||
#endif
|
#endif
|
||||||
@@ -145,6 +152,9 @@ public:
|
|||||||
case ' ': break;
|
case ' ': break;
|
||||||
case '1': state = EP_M1; break;
|
case '1': state = EP_M1; break;
|
||||||
case '4': state = EP_M4; break;
|
case '4': state = EP_M4; break;
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
case '5': state = EP_M5; break;
|
||||||
|
#endif
|
||||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
case '8': state = EP_M8; break;
|
case '8': state = EP_M8; break;
|
||||||
#endif
|
#endif
|
||||||
@@ -165,6 +175,11 @@ public:
|
|||||||
case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break;
|
case EP_M4: state = (c == '1') ? EP_M41 : EP_IGNORE; break;
|
||||||
case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;
|
case EP_M41: state = (c == '0') ? EP_M410 : EP_IGNORE; break;
|
||||||
|
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
case EP_M5: state = (c == '2') ? EP_M52 : EP_IGNORE; break;
|
||||||
|
case EP_M52: state = (c == '4') ? EP_M524 : EP_IGNORE; break;
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
|
|
||||||
case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break;
|
case EP_M8: state = (c == '7') ? EP_M87 : EP_IGNORE; break;
|
||||||
@@ -200,6 +215,9 @@ public:
|
|||||||
case EP_M108: wait_for_user = wait_for_heatup = false; break;
|
case EP_M108: wait_for_user = wait_for_heatup = false; break;
|
||||||
case EP_M112: killed_by_M112 = true; break;
|
case EP_M112: killed_by_M112 = true; break;
|
||||||
case EP_M410: quickstop_by_M410 = true; break;
|
case EP_M410: quickstop_by_M410 = true; break;
|
||||||
|
#if ENABLED(SDSUPPORT)
|
||||||
|
case EP_M524: sd_abort_by_M524 = true; break;
|
||||||
|
#endif
|
||||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||||
case EP_M876SN: hostui.handle_response(M876_reason); break;
|
case EP_M876SN: hostui.handle_response(M876_reason); break;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ FWRetract fwretract; // Single instance - this calls the constructor
|
|||||||
|
|
||||||
#include "../module/motion.h"
|
#include "../module/motion.h"
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
#include "../module/stepper.h"
|
|
||||||
|
|
||||||
#include "../gcode/gcode.h"
|
#include "../gcode/gcode.h"
|
||||||
|
|
||||||
|
|||||||
@@ -172,8 +172,9 @@ Joystick joystick;
|
|||||||
current_position += move_dist;
|
current_position += move_dist;
|
||||||
apply_motion_limits(current_position);
|
apply_motion_limits(current_position);
|
||||||
const float length = sqrt(hypot2);
|
const float length = sqrt(hypot2);
|
||||||
|
PlannerHints hints(length);
|
||||||
injecting_now = true;
|
injecting_now = true;
|
||||||
planner.buffer_line(current_position, length / seg_time, active_extruder, length);
|
planner.buffer_line(current_position, length / seg_time, active_extruder, hints);
|
||||||
injecting_now = false;
|
injecting_now = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,6 +69,44 @@ void LEDLights::setup() {
|
|||||||
#if ENABLED(RGBW_LED)
|
#if ENABLED(RGBW_LED)
|
||||||
if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN);
|
if (PWM_PIN(RGB_LED_W_PIN)) SET_PWM(RGB_LED_W_PIN); else SET_OUTPUT(RGB_LED_W_PIN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(RGB_STARTUP_TEST)
|
||||||
|
int8_t led_pin_count = 0;
|
||||||
|
if (PWM_PIN(RGB_LED_R_PIN) && PWM_PIN(RGB_LED_G_PIN) && PWM_PIN(RGB_LED_B_PIN)) led_pin_count = 3;
|
||||||
|
#if ENABLED(RGBW_LED)
|
||||||
|
if (PWM_PIN(RGB_LED_W_PIN) && led_pin_count) led_pin_count++;
|
||||||
|
#endif
|
||||||
|
// Startup animation
|
||||||
|
if (led_pin_count) {
|
||||||
|
// blackout
|
||||||
|
if (PWM_PIN(RGB_LED_R_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_R_PIN), 0); else WRITE(RGB_LED_R_PIN, LOW);
|
||||||
|
if (PWM_PIN(RGB_LED_G_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_G_PIN), 0); else WRITE(RGB_LED_G_PIN, LOW);
|
||||||
|
if (PWM_PIN(RGB_LED_B_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_B_PIN), 0); else WRITE(RGB_LED_B_PIN, LOW);
|
||||||
|
#if ENABLED(RGBW_LED)
|
||||||
|
if (PWM_PIN(RGB_LED_W_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_W_PIN), 0);
|
||||||
|
else WRITE(RGB_LED_W_PIN, LOW);
|
||||||
|
#endif
|
||||||
|
delay(200);
|
||||||
|
|
||||||
|
LOOP_L_N(i, led_pin_count) {
|
||||||
|
LOOP_LE_N(b, 200) {
|
||||||
|
const uint16_t led_pwm = b <= 100 ? b : 200 - b;
|
||||||
|
if (i == 0 && PWM_PIN(RGB_LED_R_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_R_PIN), led_pwm); else WRITE(RGB_LED_R_PIN, b < 100 ? HIGH : LOW);
|
||||||
|
if (i == 1 && PWM_PIN(RGB_LED_G_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_G_PIN), led_pwm); else WRITE(RGB_LED_G_PIN, b < 100 ? HIGH : LOW);
|
||||||
|
if (i == 2 && PWM_PIN(RGB_LED_B_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_B_PIN), led_pwm); else WRITE(RGB_LED_B_PIN, b < 100 ? HIGH : LOW);
|
||||||
|
#if ENABLED(RGBW_LED)
|
||||||
|
if (i == 3){
|
||||||
|
if (PWM_PIN(RGB_LED_W_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_W_PIN), led_pwm);
|
||||||
|
else WRITE(RGB_LED_W_PIN, b < 100 ? HIGH : LOW);
|
||||||
|
delay(RGB_STARTUP_TEST_INNER_MS);//More slowing for ending
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
delay(RGB_STARTUP_TEST_INNER_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delay(500);
|
||||||
|
}
|
||||||
|
#endif // RGB_STARTUP_TEST
|
||||||
#endif
|
#endif
|
||||||
TERN_(NEOPIXEL_LED, neo.init());
|
TERN_(NEOPIXEL_LED, neo.init());
|
||||||
TERN_(PCA9533, PCA9533_init());
|
TERN_(PCA9533, PCA9533_init());
|
||||||
|
|||||||
@@ -131,6 +131,13 @@ public:
|
|||||||
// Accessors
|
// Accessors
|
||||||
static uint16_t pixels() { return adaneo1.numPixels() * TERN1(NEOPIXEL2_INSERIES, 2); }
|
static uint16_t pixels() { return adaneo1.numPixels() * TERN1(NEOPIXEL2_INSERIES, 2); }
|
||||||
|
|
||||||
|
static uint32_t pixel_color(const uint16_t n) {
|
||||||
|
#if ENABLED(NEOPIXEL2_INSERIES)
|
||||||
|
if (n >= NEOPIXEL_PIXELS) return adaneo2.getPixelColor(n - (NEOPIXEL_PIXELS));
|
||||||
|
#endif
|
||||||
|
return adaneo1.getPixelColor(n);
|
||||||
|
}
|
||||||
|
|
||||||
static uint8_t brightness() { return adaneo1.getBrightness(); }
|
static uint8_t brightness() { return adaneo1.getBrightness(); }
|
||||||
|
|
||||||
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w)) {
|
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED, uint8_t w)) {
|
||||||
@@ -174,6 +181,7 @@ extern Marlin_NeoPixel neo;
|
|||||||
|
|
||||||
// Accessors
|
// Accessors
|
||||||
static uint16_t pixels() { return adaneo.numPixels();}
|
static uint16_t pixels() { return adaneo.numPixels();}
|
||||||
|
static uint32_t pixel_color(const uint16_t n) { return adaneo.getPixelColor(n); }
|
||||||
static uint8_t brightness() { return adaneo.getBrightness(); }
|
static uint8_t brightness() { return adaneo.getBrightness(); }
|
||||||
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED2, uint8_t w)) {
|
static uint32_t Color(uint8_t r, uint8_t g, uint8_t b OPTARG(HAS_WHITE_LED2, uint8_t w)) {
|
||||||
return adaneo.Color(r, g, b OPTARG(HAS_WHITE_LED2, w));
|
return adaneo.Color(r, g, b OPTARG(HAS_WHITE_LED2, w));
|
||||||
|
|||||||
@@ -44,7 +44,6 @@
|
|||||||
#include "max7219.h"
|
#include "max7219.h"
|
||||||
|
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
#include "../module/stepper.h"
|
|
||||||
#include "../MarlinCore.h"
|
#include "../MarlinCore.h"
|
||||||
#include "../HAL/shared/Delay.h"
|
#include "../HAL/shared/Delay.h"
|
||||||
|
|
||||||
@@ -52,6 +51,7 @@
|
|||||||
#define HAS_SIDE_BY_SIDE 1
|
#define HAS_SIDE_BY_SIDE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define _ROT ((MAX7219_ROTATE + 360) % 360)
|
||||||
#if _ROT == 0 || _ROT == 180
|
#if _ROT == 0 || _ROT == 180
|
||||||
#define MAX7219_X_LEDS TERN(HAS_SIDE_BY_SIDE, 8, MAX7219_LINES)
|
#define MAX7219_X_LEDS TERN(HAS_SIDE_BY_SIDE, 8, MAX7219_LINES)
|
||||||
#define MAX7219_Y_LEDS TERN(HAS_SIDE_BY_SIDE, MAX7219_LINES, 8)
|
#define MAX7219_Y_LEDS TERN(HAS_SIDE_BY_SIDE, MAX7219_LINES, 8)
|
||||||
@@ -62,6 +62,15 @@
|
|||||||
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
|
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MAX7219_DEBUG_PROFILE
|
||||||
|
CodeProfiler::Mode CodeProfiler::mode = ACCUMULATE_AVERAGE;
|
||||||
|
uint8_t CodeProfiler::instance_count = 0;
|
||||||
|
uint32_t CodeProfiler::last_calc_time = micros();
|
||||||
|
uint8_t CodeProfiler::time_fraction = 0;
|
||||||
|
uint32_t CodeProfiler::total_time = 0;
|
||||||
|
uint16_t CodeProfiler::call_count = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
Max7219 max7219;
|
Max7219 max7219;
|
||||||
|
|
||||||
uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
|
uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
|
||||||
@@ -69,7 +78,7 @@ uint8_t Max7219::suspended; // = 0;
|
|||||||
|
|
||||||
#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7))
|
#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7))
|
||||||
|
|
||||||
#if _ROT == 0 || _ROT == 270
|
#if (_ROT == 0 || _ROT == 270) == DISABLED(MAX7219_REVERSE_EACH)
|
||||||
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
|
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
|
||||||
#else
|
#else
|
||||||
#define _LED_BIT(Q) ((Q) & 0x7)
|
#define _LED_BIT(Q) ((Q) & 0x7)
|
||||||
@@ -266,26 +275,27 @@ void Max7219::set(const uint8_t line, const uint8_t bits) {
|
|||||||
#endif // MAX7219_NUMERIC
|
#endif // MAX7219_NUMERIC
|
||||||
|
|
||||||
// Modify a single LED bit and send the changed line
|
// Modify a single LED bit and send the changed line
|
||||||
void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) {
|
void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on, uint8_t * const rcm/*=nullptr*/) {
|
||||||
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_set"), x, y);
|
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_set"), x, y);
|
||||||
if (BIT_7219(x, y) == on) return;
|
if (BIT_7219(x, y) == on) return;
|
||||||
XOR_7219(x, y);
|
XOR_7219(x, y);
|
||||||
refresh_unit_line(LED_IND(x, y));
|
refresh_unit_line(LED_IND(x, y));
|
||||||
|
if (rcm != nullptr) *rcm |= _BV(LED_IND(x, y) & 0x07);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max7219::led_on(const uint8_t x, const uint8_t y) {
|
void Max7219::led_on(const uint8_t x, const uint8_t y, uint8_t * const rcm/*=nullptr*/) {
|
||||||
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_on"), x, y);
|
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_on"), x, y);
|
||||||
led_set(x, y, true);
|
led_set(x, y, true, rcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max7219::led_off(const uint8_t x, const uint8_t y) {
|
void Max7219::led_off(const uint8_t x, const uint8_t y, uint8_t * const rcm/*=nullptr*/) {
|
||||||
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_off"), x, y);
|
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_off"), x, y);
|
||||||
led_set(x, y, false);
|
led_set(x, y, false, rcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max7219::led_toggle(const uint8_t x, const uint8_t y) {
|
void Max7219::led_toggle(const uint8_t x, const uint8_t y, uint8_t * const rcm/*=nullptr*/) {
|
||||||
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_toggle"), x, y);
|
if (x >= MAX7219_X_LEDS || y >= MAX7219_Y_LEDS) return error(F("led_toggle"), x, y);
|
||||||
led_set(x, y, !BIT_7219(x, y));
|
led_set(x, y, !BIT_7219(x, y), rcm);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Max7219::send_row(const uint8_t row) {
|
void Max7219::send_row(const uint8_t row) {
|
||||||
@@ -448,7 +458,7 @@ void Max7219::register_setup() {
|
|||||||
pulse_load(); // Tell the chips to load the clocked out data
|
pulse_load(); // Tell the chips to load the clocked out data
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAX7219_INIT_TEST
|
#if MAX7219_INIT_TEST
|
||||||
|
|
||||||
uint8_t test_mode = 0;
|
uint8_t test_mode = 0;
|
||||||
millis_t next_patt_ms;
|
millis_t next_patt_ms;
|
||||||
@@ -536,13 +546,9 @@ void Max7219::init() {
|
|||||||
|
|
||||||
register_setup();
|
register_setup();
|
||||||
|
|
||||||
LOOP_LE_N(i, 7) { // Empty registers to turn all LEDs off
|
clear();
|
||||||
led_line[i] = 0x00;
|
|
||||||
send(max7219_reg_digit0 + i, 0);
|
|
||||||
pulse_load(); // Tell the chips to load the clocked out data
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef MAX7219_INIT_TEST
|
#if MAX7219_INIT_TEST
|
||||||
start_test_pattern();
|
start_test_pattern();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -554,41 +560,55 @@ void Max7219::init() {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
// Apply changes to update a marker
|
// Apply changes to update a marker
|
||||||
void Max7219::mark16(const uint8_t pos, const uint8_t v1, const uint8_t v2) {
|
void Max7219::mark16(const uint8_t pos, const uint8_t v1, const uint8_t v2, uint8_t * const rcm/*=nullptr*/) {
|
||||||
#if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line.
|
#if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line.
|
||||||
led_off(v1 & 0xF, pos);
|
led_off(v1 & 0xF, pos, rcm);
|
||||||
led_on(v2 & 0xF, pos);
|
led_on(v2 & 0xF, pos, rcm);
|
||||||
#elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column.
|
#elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column.
|
||||||
led_off(pos, v1 & 0xF);
|
led_off(pos, v1 & 0xF, rcm);
|
||||||
led_on(pos, v2 & 0xF);
|
led_on(pos, v2 & 0xF, rcm);
|
||||||
#else // Single 8x8 LED matrix. Use two lines to get 16 LEDs.
|
#else // Single 8x8 LED matrix. Use two lines to get 16 LEDs.
|
||||||
led_off(v1 & 0x7, pos + (v1 >= 8));
|
led_off(v1 & 0x7, pos + (v1 >= 8), rcm);
|
||||||
led_on(v2 & 0x7, pos + (v2 >= 8));
|
led_on(v2 & 0x7, pos + (v2 >= 8), rcm);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply changes to update a tail-to-head range
|
// Apply changes to update a tail-to-head range
|
||||||
void Max7219::range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
|
void Max7219::range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh,
|
||||||
|
const uint8_t nh, uint8_t * const rcm/*=nullptr*/) {
|
||||||
#if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line.
|
#if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line.
|
||||||
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
|
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
|
||||||
led_off(n & 0xF, y);
|
led_off(n & 0xF, y, rcm);
|
||||||
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
|
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
|
||||||
led_on(n & 0xF, y);
|
led_on(n & 0xF, y, rcm);
|
||||||
#elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column.
|
#elif MAX7219_Y_LEDS > 8 // At least 16 LEDs on the Y-Axis. Use a single column.
|
||||||
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
|
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
|
||||||
led_off(y, n & 0xF);
|
led_off(y, n & 0xF, rcm);
|
||||||
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
|
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
|
||||||
led_on(y, n & 0xF);
|
led_on(y, n & 0xF, rcm);
|
||||||
#else // Single 8x8 LED matrix. Use two lines to get 16 LEDs.
|
#else // Single 8x8 LED matrix. Use two lines to get 16 LEDs.
|
||||||
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
|
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
|
||||||
led_off(n & 0x7, y + (n >= 8));
|
led_off(n & 0x7, y + (n >= 8), rcm);
|
||||||
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
|
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
|
||||||
led_on(n & 0x7, y + (n >= 8));
|
led_on(n & 0x7, y + (n >= 8), rcm);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply changes to update a quantity
|
// Apply changes to update a quantity
|
||||||
void Max7219::quantity16(const uint8_t pos, const uint8_t ov, const uint8_t nv) {
|
void Max7219::quantity(const uint8_t pos, const uint8_t ov, const uint8_t nv, uint8_t * const rcm/*=nullptr*/) {
|
||||||
|
for (uint8_t i = _MIN(nv, ov); i < _MAX(nv, ov); i++)
|
||||||
|
led_set(
|
||||||
|
#if MAX7219_X_LEDS >= MAX7219_Y_LEDS
|
||||||
|
i, pos // Single matrix or multiple matrices in Landscape
|
||||||
|
#else
|
||||||
|
pos, i // Multiple matrices in Portrait
|
||||||
|
#endif
|
||||||
|
, nv >= ov
|
||||||
|
, rcm
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Max7219::quantity16(const uint8_t pos, const uint8_t ov, const uint8_t nv, uint8_t * const rcm/*=nullptr*/) {
|
||||||
for (uint8_t i = _MIN(nv, ov); i < _MAX(nv, ov); i++)
|
for (uint8_t i = _MIN(nv, ov); i < _MAX(nv, ov); i++)
|
||||||
led_set(
|
led_set(
|
||||||
#if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line.
|
#if MAX7219_X_LEDS > 8 // At least 16 LEDs on the X-Axis. Use single line.
|
||||||
@@ -599,6 +619,7 @@ void Max7219::quantity16(const uint8_t pos, const uint8_t ov, const uint8_t nv)
|
|||||||
i >> 1, pos + (i & 1)
|
i >> 1, pos + (i & 1)
|
||||||
#endif
|
#endif
|
||||||
, nv >= ov
|
, nv >= ov
|
||||||
|
, rcm
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -636,16 +657,20 @@ void Max7219::idle_tasks() {
|
|||||||
register_setup();
|
register_setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef MAX7219_INIT_TEST
|
#if MAX7219_INIT_TEST
|
||||||
if (test_mode) {
|
if (test_mode) {
|
||||||
run_test_pattern();
|
run_test_pattern();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// suspend updates and record which lines have changed for batching later
|
||||||
|
suspended++;
|
||||||
|
uint8_t row_change_mask = 0x00;
|
||||||
|
|
||||||
#if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
|
#if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
|
||||||
if (do_blink) {
|
if (do_blink) {
|
||||||
led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1);
|
led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1, &row_change_mask);
|
||||||
next_blink = ms + 1000;
|
next_blink = ms + 1000;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -655,7 +680,7 @@ void Max7219::idle_tasks() {
|
|||||||
static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF;
|
static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF;
|
||||||
|
|
||||||
if (last_head_cnt != head || last_tail_cnt != tail) {
|
if (last_head_cnt != head || last_tail_cnt != tail) {
|
||||||
range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
|
range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head, &row_change_mask);
|
||||||
last_head_cnt = head;
|
last_head_cnt = head;
|
||||||
last_tail_cnt = tail;
|
last_tail_cnt = tail;
|
||||||
}
|
}
|
||||||
@@ -665,7 +690,7 @@ void Max7219::idle_tasks() {
|
|||||||
#ifdef MAX7219_DEBUG_PLANNER_HEAD
|
#ifdef MAX7219_DEBUG_PLANNER_HEAD
|
||||||
static int16_t last_head_cnt = 0x1;
|
static int16_t last_head_cnt = 0x1;
|
||||||
if (last_head_cnt != head) {
|
if (last_head_cnt != head) {
|
||||||
mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
|
mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head, &row_change_mask);
|
||||||
last_head_cnt = head;
|
last_head_cnt = head;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -673,7 +698,7 @@ void Max7219::idle_tasks() {
|
|||||||
#ifdef MAX7219_DEBUG_PLANNER_TAIL
|
#ifdef MAX7219_DEBUG_PLANNER_TAIL
|
||||||
static int16_t last_tail_cnt = 0x1;
|
static int16_t last_tail_cnt = 0x1;
|
||||||
if (last_tail_cnt != tail) {
|
if (last_tail_cnt != tail) {
|
||||||
mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
|
mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail, &row_change_mask);
|
||||||
last_tail_cnt = tail;
|
last_tail_cnt = tail;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -684,11 +709,26 @@ void Max7219::idle_tasks() {
|
|||||||
static int16_t last_depth = 0;
|
static int16_t last_depth = 0;
|
||||||
const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF;
|
const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF;
|
||||||
if (current_depth != last_depth) {
|
if (current_depth != last_depth) {
|
||||||
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
|
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth, &row_change_mask);
|
||||||
last_depth = current_depth;
|
last_depth = current_depth;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MAX7219_DEBUG_PROFILE
|
||||||
|
static uint8_t last_time_fraction = 0;
|
||||||
|
const uint8_t current_time_fraction = (uint16_t(CodeProfiler::get_time_fraction()) * MAX7219_NUMBER_UNITS + 8) / 16;
|
||||||
|
if (current_time_fraction != last_time_fraction) {
|
||||||
|
quantity(MAX7219_DEBUG_PROFILE, last_time_fraction, current_time_fraction, &row_change_mask);
|
||||||
|
last_time_fraction = current_time_fraction;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// batch line updates
|
||||||
|
suspended--;
|
||||||
|
if (!suspended)
|
||||||
|
LOOP_L_N(i, 8) if (row_change_mask & _BV(i))
|
||||||
|
refresh_line(i);
|
||||||
|
|
||||||
// After resume() automatically do a refresh()
|
// After resume() automatically do a refresh()
|
||||||
if (suspended == 0x80) {
|
if (suspended == 0x80) {
|
||||||
suspended = 0;
|
suspended = 0;
|
||||||
|
|||||||
@@ -47,7 +47,6 @@
|
|||||||
#ifndef MAX7219_ROTATE
|
#ifndef MAX7219_ROTATE
|
||||||
#define MAX7219_ROTATE 0
|
#define MAX7219_ROTATE 0
|
||||||
#endif
|
#endif
|
||||||
#define _ROT ((MAX7219_ROTATE + 360) % 360)
|
|
||||||
|
|
||||||
#ifndef MAX7219_NUMBER_UNITS
|
#ifndef MAX7219_NUMBER_UNITS
|
||||||
#define MAX7219_NUMBER_UNITS 1
|
#define MAX7219_NUMBER_UNITS 1
|
||||||
@@ -73,6 +72,67 @@
|
|||||||
#define max7219_reg_shutdown 0x0C
|
#define max7219_reg_shutdown 0x0C
|
||||||
#define max7219_reg_displayTest 0x0F
|
#define max7219_reg_displayTest 0x0F
|
||||||
|
|
||||||
|
#ifdef MAX7219_DEBUG_PROFILE
|
||||||
|
// This class sums up the amount of time for which its instances exist.
|
||||||
|
// By default there is one instantiated for the duration of the idle()
|
||||||
|
// function. But an instance can be created in any code block to measure
|
||||||
|
// the time spent from the point of instantiation until the CPU leaves
|
||||||
|
// block. Be careful about having multiple instances of CodeProfiler as
|
||||||
|
// it does not guard against double counting. In general mixing ISR and
|
||||||
|
// non-ISR use will require critical sections but note that mode setting
|
||||||
|
// is atomic so the total or average times can safely be read if you set
|
||||||
|
// mode to FREEZE first.
|
||||||
|
class CodeProfiler {
|
||||||
|
public:
|
||||||
|
enum Mode : uint8_t { ACCUMULATE_AVERAGE, ACCUMULATE_TOTAL, FREEZE };
|
||||||
|
|
||||||
|
private:
|
||||||
|
static Mode mode;
|
||||||
|
static uint8_t instance_count;
|
||||||
|
static uint32_t last_calc_time;
|
||||||
|
static uint32_t total_time;
|
||||||
|
static uint8_t time_fraction;
|
||||||
|
static uint16_t call_count;
|
||||||
|
|
||||||
|
uint32_t start_time;
|
||||||
|
|
||||||
|
public:
|
||||||
|
CodeProfiler() : start_time(micros()) { instance_count++; }
|
||||||
|
~CodeProfiler() {
|
||||||
|
instance_count--;
|
||||||
|
if (mode == FREEZE) return;
|
||||||
|
|
||||||
|
call_count++;
|
||||||
|
|
||||||
|
const uint32_t now = micros();
|
||||||
|
total_time += now - start_time;
|
||||||
|
|
||||||
|
if (mode == ACCUMULATE_TOTAL) return;
|
||||||
|
|
||||||
|
// update time_fraction every hundred milliseconds
|
||||||
|
if (instance_count == 0 && ELAPSED(now, last_calc_time + 100000)) {
|
||||||
|
time_fraction = total_time * 128 / (now - last_calc_time);
|
||||||
|
last_calc_time = now;
|
||||||
|
total_time = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_mode(Mode _mode) { mode = _mode; }
|
||||||
|
static void reset() {
|
||||||
|
time_fraction = 0;
|
||||||
|
last_calc_time = micros();
|
||||||
|
total_time = 0;
|
||||||
|
call_count = 0;
|
||||||
|
}
|
||||||
|
// returns fraction of total time which was measured, scaled from 0 to 128
|
||||||
|
static uint8_t get_time_fraction() { return time_fraction; }
|
||||||
|
// returns total time in microseconds
|
||||||
|
static uint32_t get_total_time() { return total_time; }
|
||||||
|
|
||||||
|
static uint16_t get_call_count() { return call_count; }
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
class Max7219 {
|
class Max7219 {
|
||||||
public:
|
public:
|
||||||
static uint8_t led_line[MAX7219_LINES];
|
static uint8_t led_line[MAX7219_LINES];
|
||||||
@@ -110,10 +170,10 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set a single LED by XY coordinate
|
// Set a single LED by XY coordinate
|
||||||
static void led_set(const uint8_t x, const uint8_t y, const bool on);
|
static void led_set(const uint8_t x, const uint8_t y, const bool on, uint8_t * const rcm=nullptr);
|
||||||
static void led_on(const uint8_t x, const uint8_t y);
|
static void led_on(const uint8_t x, const uint8_t y, uint8_t * const rcm=nullptr);
|
||||||
static void led_off(const uint8_t x, const uint8_t y);
|
static void led_off(const uint8_t x, const uint8_t y, uint8_t * const rcm=nullptr);
|
||||||
static void led_toggle(const uint8_t x, const uint8_t y);
|
static void led_toggle(const uint8_t x, const uint8_t y, uint8_t * const rcm=nullptr);
|
||||||
|
|
||||||
// Set all LEDs in a single column
|
// Set all LEDs in a single column
|
||||||
static void set_column(const uint8_t col, const uint32_t val);
|
static void set_column(const uint8_t col, const uint32_t val);
|
||||||
@@ -147,11 +207,12 @@ private:
|
|||||||
static void set(const uint8_t line, const uint8_t bits);
|
static void set(const uint8_t line, const uint8_t bits);
|
||||||
static void send_row(const uint8_t row);
|
static void send_row(const uint8_t row);
|
||||||
static void send_column(const uint8_t col);
|
static void send_column(const uint8_t col);
|
||||||
static void mark16(const uint8_t y, const uint8_t v1, const uint8_t v2);
|
static void mark16(const uint8_t y, const uint8_t v1, const uint8_t v2, uint8_t * const rcm=nullptr);
|
||||||
static void range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh);
|
static void range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh, uint8_t * const rcm=nullptr);
|
||||||
static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv);
|
static void quantity(const uint8_t y, const uint8_t ov, const uint8_t nv, uint8_t * const rcm=nullptr);
|
||||||
|
static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv, uint8_t * const rcm=nullptr);
|
||||||
|
|
||||||
#ifdef MAX7219_INIT_TEST
|
#if MAX7219_INIT_TEST
|
||||||
static void test_pattern();
|
static void test_pattern();
|
||||||
static void run_test_pattern();
|
static void run_test_pattern();
|
||||||
static void start_test_pattern();
|
static void start_test_pattern();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
* Algorithm & Implementation: Scott Mudge - mail@scottmudge.com
|
* Algorithm & Implementation: Scott Mudge - mail@scottmudge.com
|
||||||
* Date: Dec. 2020
|
* Date: Dec. 2020
|
||||||
*
|
*
|
||||||
* Character Frequencies from ~30 MB of comment-stripped gcode:
|
* Character Frequencies from ~30 MB of comment-stripped G-code:
|
||||||
* '1' -> 4451136 '4' -> 1353273 '\n' -> 1087683 '-' -> 90242
|
* '1' -> 4451136 '4' -> 1353273 '\n' -> 1087683 '-' -> 90242
|
||||||
* '0' -> 4253577 '9' -> 1352147 'G' -> 1075806 'Z' -> 34109
|
* '0' -> 4253577 '9' -> 1352147 'G' -> 1075806 'Z' -> 34109
|
||||||
* ' ' -> 3053297 '3' -> 1262929 'X' -> 975742 'M' -> 11879
|
* ' ' -> 3053297 '3' -> 1262929 'X' -> 975742 'M' -> 11879
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
* Specifically optimized for 3D printing G-Code, this is a zero-cost data compression method
|
* Specifically optimized for 3D printing G-Code, this is a zero-cost data compression method
|
||||||
* which packs ~180-190% more data into the same amount of bytes going to the CNC controller.
|
* which packs ~180-190% more data into the same amount of bytes going to the CNC controller.
|
||||||
* As a majority of G-Code can be represented by a restricted alphabet, I performed histogram
|
* As a majority of G-Code can be represented by a restricted alphabet, I performed histogram
|
||||||
* analysis on a wide variety of 3D printing gcode samples, and found ~93% of all gcode could
|
* analysis on a wide variety of 3D printing G-code samples, and found ~93% of all G-code could
|
||||||
* be represented by the same 15-character alphabet.
|
* be represented by the same 15-character alphabet.
|
||||||
*
|
*
|
||||||
* This allowed me to design a system of packing 2 8-bit characters into a single byte, assuming
|
* This allowed me to design a system of packing 2 8-bit characters into a single byte, assuming
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
*
|
*
|
||||||
* Combined with some logic to allow commingling of full-width characters outside of this 15-
|
* Combined with some logic to allow commingling of full-width characters outside of this 15-
|
||||||
* character alphabet (at the cost of an extra 8-bits per full-width character), and by stripping
|
* character alphabet (at the cost of an extra 8-bits per full-width character), and by stripping
|
||||||
* out unnecessary comments, the end result is gcode which is roughly half the original size.
|
* out unnecessary comments, the end result is G-code which is roughly half the original size.
|
||||||
*
|
*
|
||||||
* Why did I do this? I noticed micro-stuttering and other data-bottleneck issues while printing
|
* Why did I do this? I noticed micro-stuttering and other data-bottleneck issues while printing
|
||||||
* objects with high curvature, especially at high speeds. There is also the issue of the limited
|
* objects with high curvature, especially at high speeds. There is also the issue of the limited
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ When done, the MMU sends
|
|||||||
|
|
||||||
- MMU => 'ok\n'
|
- MMU => 'ok\n'
|
||||||
|
|
||||||
We don't wait for a response here but immediately continue with the next gcode which should
|
We don't wait for a response here but immediately continue with the next G-code which should
|
||||||
be one or more extruder moves to feed the filament into the hotend.
|
be one or more extruder moves to feed the filament into the hotend.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -585,7 +585,7 @@ static void mmu2_not_responding() {
|
|||||||
command(MMU_CMD_T0 + index);
|
command(MMU_CMD_T0 + index);
|
||||||
manage_response(true, true);
|
manage_response(true, true);
|
||||||
mmu_continue_loading();
|
mmu_continue_loading();
|
||||||
command(MMU_CMD_C0);
|
//command(MMU_CMD_C0);
|
||||||
extruder = index;
|
extruder = index;
|
||||||
active_extruder = 0;
|
active_extruder = 0;
|
||||||
|
|
||||||
@@ -653,13 +653,34 @@ static void mmu2_not_responding() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MMU2::mmu_continue_loading() {
|
void MMU2::mmu_continue_loading() {
|
||||||
|
// Try to load the filament a limited number of times
|
||||||
|
bool fil_present = 0;
|
||||||
for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) {
|
for (uint8_t i = 0; i < MMU_LOADING_ATTEMPTS_NR; i++) {
|
||||||
DEBUG_ECHOLNPGM("Additional load attempt #", i);
|
DEBUG_ECHOLNPGM("Load attempt #", i + 1);
|
||||||
if (FILAMENT_PRESENT()) break;
|
|
||||||
|
// Done as soon as filament is present
|
||||||
|
fil_present = FILAMENT_PRESENT();
|
||||||
|
if (fil_present) break;
|
||||||
|
|
||||||
|
// Attempt to load the filament, 1mm at a time, for 3s
|
||||||
command(MMU_CMD_C0);
|
command(MMU_CMD_C0);
|
||||||
|
stepper.enable_extruder();
|
||||||
|
const millis_t expire_ms = millis() + 3000;
|
||||||
|
do {
|
||||||
|
current_position.e += 1;
|
||||||
|
line_to_current_position(MMU_LOAD_FEEDRATE);
|
||||||
|
planner.synchronize();
|
||||||
|
// When (T0 rx->ok) load is ready, but in fact it did not load
|
||||||
|
// successfully or an overload created pressure in the extruder.
|
||||||
|
// Send (C0) to load more and move E_AXIS a little to release pressure.
|
||||||
|
if ((fil_present = FILAMENT_PRESENT())) MMU2_COMMAND("A");
|
||||||
|
} while (!fil_present && PENDING(millis(), expire_ms));
|
||||||
|
stepper.disable_extruder();
|
||||||
manage_response(true, true);
|
manage_response(true, true);
|
||||||
}
|
}
|
||||||
if (!FILAMENT_PRESENT()) {
|
|
||||||
|
// Was the filament still missing in the last check?
|
||||||
|
if (!fil_present) {
|
||||||
DEBUG_ECHOLNPGM("Filament never reached sensor, runout");
|
DEBUG_ECHOLNPGM("Filament never reached sensor, runout");
|
||||||
filament_runout();
|
filament_runout();
|
||||||
}
|
}
|
||||||
@@ -682,7 +703,7 @@ static void mmu2_not_responding() {
|
|||||||
command(MMU_CMD_T0 + index);
|
command(MMU_CMD_T0 + index);
|
||||||
manage_response(true, true);
|
manage_response(true, true);
|
||||||
command(MMU_CMD_C0);
|
command(MMU_CMD_C0);
|
||||||
extruder = index; //filament change is finished
|
extruder = index; // Filament change is finished
|
||||||
active_extruder = 0;
|
active_extruder = 0;
|
||||||
stepper.enable_extruder();
|
stepper.enable_extruder();
|
||||||
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
|
SERIAL_ECHO_MSG(STR_ACTIVE_EXTRUDER, extruder);
|
||||||
@@ -939,7 +960,7 @@ bool MMU2::load_filament_to_nozzle(const uint8_t index) {
|
|||||||
* Load filament to nozzle of multimaterial printer
|
* Load filament to nozzle of multimaterial printer
|
||||||
*
|
*
|
||||||
* This function is used only after T? (user select filament) and M600 (change filament).
|
* This function is used only after T? (user select filament) and M600 (change filament).
|
||||||
* It is not used after T0 .. T4 command (select filament), in such case, gcode is responsible for loading
|
* It is not used after T0 .. T4 command (select filament), in such case, G-code is responsible for loading
|
||||||
* filament to nozzle.
|
* filament to nozzle.
|
||||||
*/
|
*/
|
||||||
void MMU2::load_to_nozzle() {
|
void MMU2::load_to_nozzle() {
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(MMU_EXTRUDER_SENSOR)
|
#if ENABLED(MMU_EXTRUDER_SENSOR)
|
||||||
|
#define MMU_LOAD_FEEDRATE 19.02f // (mm/s)
|
||||||
static void mmu_continue_loading();
|
static void mmu_continue_loading();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -35,10 +35,13 @@
|
|||||||
#include "../gcode/gcode.h"
|
#include "../gcode/gcode.h"
|
||||||
#include "../module/motion.h"
|
#include "../module/motion.h"
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
#include "../module/stepper.h"
|
|
||||||
#include "../module/printcounter.h"
|
#include "../module/printcounter.h"
|
||||||
#include "../module/temperature.h"
|
#include "../module/temperature.h"
|
||||||
|
|
||||||
|
#if HAS_EXTRUDERS
|
||||||
|
#include "../module/stepper.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
#if ENABLED(AUTO_BED_LEVELING_UBL)
|
||||||
#include "bedlevel/bedlevel.h"
|
#include "bedlevel/bedlevel.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -63,7 +66,7 @@
|
|||||||
|
|
||||||
#include "../lcd/marlinui.h"
|
#include "../lcd/marlinui.h"
|
||||||
|
|
||||||
#if HAS_BUZZER
|
#if HAS_SOUND
|
||||||
#include "../libs/buzzer.h"
|
#include "../libs/buzzer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -98,7 +101,7 @@ fil_change_settings_t fc_settings[EXTRUDERS];
|
|||||||
#define _PMSG(L) L##_LCD
|
#define _PMSG(L) L##_LCD
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_BUZZER
|
#if HAS_SOUND
|
||||||
static void impatient_beep(const int8_t max_beep_count, const bool restart=false) {
|
static void impatient_beep(const int8_t max_beep_count, const bool restart=false) {
|
||||||
|
|
||||||
if (TERN0(HAS_MARLINUI_MENU, pause_mode == PAUSE_MODE_PAUSE_PRINT)) return;
|
if (TERN0(HAS_MARLINUI_MENU, pause_mode == PAUSE_MODE_PAUSE_PRINT)) return;
|
||||||
@@ -711,9 +714,13 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
|
|||||||
|
|
||||||
TERN_(HAS_FILAMENT_SENSOR, runout.reset());
|
TERN_(HAS_FILAMENT_SENSOR, runout.reset());
|
||||||
|
|
||||||
TERN(DWIN_LCD_PROUI, DWIN_Print_Resume(), ui.reset_status());
|
#if ENABLED(DWIN_LCD_PROUI)
|
||||||
TERN_(HAS_MARLINUI_MENU, ui.return_to_status());
|
DWIN_Print_Resume();
|
||||||
TERN_(DWIN_LCD_PROUI, HMI_ReturnScreen());
|
HMI_ReturnScreen();
|
||||||
|
#else
|
||||||
|
ui.reset_status();
|
||||||
|
ui.return_to_status();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // ADVANCED_PAUSE_FEATURE
|
#endif // ADVANCED_PAUSE_FEATURE
|
||||||
|
|||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
#include "../module/stepper.h"
|
#include "../module/stepper/indirection.h" // for restore_stepper_drivers
|
||||||
#include "../module/temperature.h"
|
#include "../module/temperature.h"
|
||||||
#include "../MarlinCore.h"
|
#include "../MarlinCore.h"
|
||||||
|
|
||||||
@@ -46,6 +46,7 @@ Power powerManager;
|
|||||||
bool Power::psu_on;
|
bool Power::psu_on;
|
||||||
|
|
||||||
#if ENABLED(AUTO_POWER_CONTROL)
|
#if ENABLED(AUTO_POWER_CONTROL)
|
||||||
|
#include "../module/stepper.h"
|
||||||
#include "../module/temperature.h"
|
#include "../module/temperature.h"
|
||||||
|
|
||||||
#if BOTH(USE_CONTROLLER_FAN, AUTO_POWER_CONTROLLERFAN)
|
#if BOTH(USE_CONTROLLER_FAN, AUTO_POWER_CONTROLLERFAN)
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor
|
|||||||
void PowerMonitor::draw_current() {
|
void PowerMonitor::draw_current() {
|
||||||
const float amps = getAmps();
|
const float amps = getAmps();
|
||||||
lcd_put_u8str(amps < 100 ? ftostr31ns(amps) : ui16tostr4rj((uint16_t)amps));
|
lcd_put_u8str(amps < 100 ? ftostr31ns(amps) : ui16tostr4rj((uint16_t)amps));
|
||||||
lcd_put_wchar('A');
|
lcd_put_lchar('A');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor
|
|||||||
void PowerMonitor::draw_voltage() {
|
void PowerMonitor::draw_voltage() {
|
||||||
const float volts = getVolts();
|
const float volts = getVolts();
|
||||||
lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts));
|
lcd_put_u8str(volts < 100 ? ftostr31ns(volts) : ui16tostr4rj((uint16_t)volts));
|
||||||
lcd_put_wchar('V');
|
lcd_put_lchar('V');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ PowerMonitor power_monitor; // Single instance - this calls the constructor
|
|||||||
void PowerMonitor::draw_power() {
|
void PowerMonitor::draw_power() {
|
||||||
const float power = getPower();
|
const float power = getPower();
|
||||||
lcd_put_u8str(power < 100 ? ftostr31ns(power) : ui16tostr4rj((uint16_t)power));
|
lcd_put_u8str(power < 100 ? ftostr31ns(power) : ui16tostr4rj((uint16_t)power));
|
||||||
lcd_put_wchar('W');
|
lcd_put_lchar('W');
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ struct pm_lpf_t {
|
|||||||
uint32_t filter_buf;
|
uint32_t filter_buf;
|
||||||
float value;
|
float value;
|
||||||
void add_sample(const uint16_t sample) {
|
void add_sample(const uint16_t sample) {
|
||||||
filter_buf = filter_buf - (filter_buf >> K_VALUE) + (uint32_t(sample) << K_SCALE);
|
filter_buf += (uint32_t(sample) << K_SCALE) - (filter_buf >> K_VALUE);
|
||||||
}
|
}
|
||||||
void capture() {
|
void capture() {
|
||||||
value = filter_buf * (SCALE * (1.0f / (1UL << (PM_K_VALUE + PM_K_SCALE))));
|
value = filter_buf * (SCALE * (1.0f / (1UL << (PM_K_VALUE + PM_K_SCALE))));
|
||||||
|
|||||||
@@ -39,17 +39,26 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
SpindleLaser cutter;
|
SpindleLaser cutter;
|
||||||
uint8_t SpindleLaser::power;
|
bool SpindleLaser::enable_state; // Virtual enable state, controls enable pin if present and or apply power if > 0
|
||||||
#if ENABLED(LASER_FEATURE)
|
uint8_t SpindleLaser::power, // Actual power output 0-255 ocr or "0 = off" > 0 = "on"
|
||||||
cutter_test_pulse_t SpindleLaser::testPulse = 50; // Test fire Pulse time ms value.
|
SpindleLaser::last_power_applied; // = 0 // Basic power state tracking
|
||||||
#endif
|
|
||||||
bool SpindleLaser::isReady; // Ready to apply power setting from the UI to OCR
|
|
||||||
cutter_power_t SpindleLaser::menuPower, // Power set via LCD menu in PWM, PERCENT, or RPM
|
|
||||||
SpindleLaser::unitPower; // LCD status power in PWM, PERCENT, or RPM
|
|
||||||
|
|
||||||
#if ENABLED(MARLIN_DEV_MODE)
|
#if ENABLED(LASER_FEATURE)
|
||||||
cutter_frequency_t SpindleLaser::frequency; // PWM frequency setting; range: 2K - 50K
|
cutter_test_pulse_t SpindleLaser::testPulse = 50; // (ms) Test fire pulse default duration
|
||||||
|
uint8_t SpindleLaser::last_block_power; // = 0 // Track power changes for dynamic inline power
|
||||||
|
feedRate_t SpindleLaser::feedrate_mm_m = 1500,
|
||||||
|
SpindleLaser::last_feedrate_mm_m; // = 0 // (mm/min) Track feedrate changes for dynamic power
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
bool SpindleLaser::isReadyForUI = false; // Ready to apply power setting from the UI to OCR
|
||||||
|
CutterMode SpindleLaser::cutter_mode = CUTTER_MODE_STANDARD; // Default is standard mode
|
||||||
|
|
||||||
|
constexpr cutter_cpower_t SpindleLaser::power_floor;
|
||||||
|
cutter_power_t SpindleLaser::menuPower = 0, // Power value via LCD menu in PWM, PERCENT, or RPM based on configured format set by CUTTER_POWER_UNIT.
|
||||||
|
SpindleLaser::unitPower = 0; // Unit power is in PWM, PERCENT, or RPM based on CUTTER_POWER_UNIT.
|
||||||
|
|
||||||
|
cutter_frequency_t SpindleLaser::frequency; // PWM frequency setting; range: 2K - 50K
|
||||||
|
|
||||||
#define SPINDLE_LASER_PWM_OFF TERN(SPINDLE_LASER_PWM_INVERT, 255, 0)
|
#define SPINDLE_LASER_PWM_OFF TERN(SPINDLE_LASER_PWM_INVERT, 255, 0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -57,21 +66,21 @@ cutter_power_t SpindleLaser::menuPower, // Power s
|
|||||||
*/
|
*/
|
||||||
void SpindleLaser::init() {
|
void SpindleLaser::init() {
|
||||||
#if ENABLED(SPINDLE_SERVO)
|
#if ENABLED(SPINDLE_SERVO)
|
||||||
MOVE_SERVO(SPINDLE_SERVO_NR, SPINDLE_SERVO_MIN);
|
servo[SPINDLE_SERVO_NR].move(SPINDLE_SERVO_MIN);
|
||||||
#else
|
#elif PIN_EXISTS(SPINDLE_LASER_ENA)
|
||||||
OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Init spindle to off
|
OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Init spindle to off
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(SPINDLE_CHANGE_DIR)
|
#if ENABLED(SPINDLE_CHANGE_DIR)
|
||||||
OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR); // Init rotation to clockwise (M3)
|
OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR); // Init rotation to clockwise (M3)
|
||||||
#endif
|
#endif
|
||||||
|
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
|
||||||
|
frequency = SPINDLE_LASER_FREQUENCY;
|
||||||
|
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
|
||||||
|
#endif
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
||||||
SET_PWM(SPINDLE_LASER_PWM_PIN);
|
SET_PWM(SPINDLE_LASER_PWM_PIN);
|
||||||
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
|
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Set to lowest speed
|
||||||
#endif
|
#endif
|
||||||
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
|
|
||||||
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_FREQUENCY);
|
|
||||||
TERN_(MARLIN_DEV_MODE, frequency = SPINDLE_LASER_FREQUENCY);
|
|
||||||
#endif
|
|
||||||
#if ENABLED(AIR_EVACUATION)
|
#if ENABLED(AIR_EVACUATION)
|
||||||
OUT_WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); // Init Vacuum/Blower OFF
|
OUT_WRITE(AIR_EVACUATION_PIN, !AIR_EVACUATION_ACTIVE); // Init Vacuum/Blower OFF
|
||||||
#endif
|
#endif
|
||||||
@@ -89,53 +98,62 @@ void SpindleLaser::init() {
|
|||||||
*/
|
*/
|
||||||
void SpindleLaser::_set_ocr(const uint8_t ocr) {
|
void SpindleLaser::_set_ocr(const uint8_t ocr) {
|
||||||
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
|
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
|
||||||
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), TERN(MARLIN_DEV_MODE, frequency, SPINDLE_LASER_FREQUENCY));
|
hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency);
|
||||||
#endif
|
#endif
|
||||||
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
|
hal.set_pwm_duty(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpindleLaser::set_ocr(const uint8_t ocr) {
|
void SpindleLaser::set_ocr(const uint8_t ocr) {
|
||||||
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Cutter ON
|
#if PIN_EXISTS(SPINDLE_LASER_ENA)
|
||||||
|
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_STATE); // Cutter ON
|
||||||
|
#endif
|
||||||
_set_ocr(ocr);
|
_set_ocr(ocr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpindleLaser::ocr_off() {
|
void SpindleLaser::ocr_off() {
|
||||||
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF
|
#if PIN_EXISTS(SPINDLE_LASER_ENA)
|
||||||
|
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE); // Cutter OFF
|
||||||
|
#endif
|
||||||
_set_ocr(0);
|
_set_ocr(0);
|
||||||
}
|
}
|
||||||
#endif // SPINDLE_LASER_USE_PWM
|
#endif // SPINDLE_LASER_USE_PWM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply power for laser/spindle
|
* Apply power for Laser or Spindle
|
||||||
*
|
*
|
||||||
* Apply cutter power value for PWM, Servo, and on/off pin.
|
* Apply cutter power value for PWM, Servo, and on/off pin.
|
||||||
*
|
*
|
||||||
* @param opwr Power value. Range 0 to MAX. When 0 disable spindle/laser.
|
* @param opwr Power value. Range 0 to MAX.
|
||||||
*/
|
*/
|
||||||
void SpindleLaser::apply_power(const uint8_t opwr) {
|
void SpindleLaser::apply_power(const uint8_t opwr) {
|
||||||
static uint8_t last_power_applied = 0;
|
if (enabled() || opwr == 0) { // 0 check allows us to disable where no ENA pin exists
|
||||||
if (opwr == last_power_applied) return;
|
// Test and set the last power used to improve performance
|
||||||
last_power_applied = opwr;
|
if (opwr == last_power_applied) return;
|
||||||
power = opwr;
|
last_power_applied = opwr;
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
// Handle PWM driven or just simple on/off
|
||||||
if (cutter.unitPower == 0 && CUTTER_UNIT_IS(RPM)) {
|
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
||||||
ocr_off();
|
if (CUTTER_UNIT_IS(RPM) && unitPower == 0)
|
||||||
isReady = false;
|
ocr_off();
|
||||||
}
|
else if (ENABLED(CUTTER_POWER_RELATIVE) || enabled() || opwr == 0) {
|
||||||
else if (ENABLED(CUTTER_POWER_RELATIVE) || enabled()) {
|
set_ocr(opwr);
|
||||||
set_ocr(power);
|
isReadyForUI = true;
|
||||||
isReady = true;
|
}
|
||||||
}
|
else
|
||||||
else {
|
ocr_off();
|
||||||
ocr_off();
|
#elif ENABLED(SPINDLE_SERVO)
|
||||||
isReady = false;
|
MOVE_SERVO(SPINDLE_SERVO_NR, power);
|
||||||
}
|
#else
|
||||||
#elif ENABLED(SPINDLE_SERVO)
|
WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
|
||||||
MOVE_SERVO(SPINDLE_SERVO_NR, power);
|
isReadyForUI = true;
|
||||||
#else
|
#endif
|
||||||
WRITE(SPINDLE_LASER_ENA_PIN, enabled() ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
|
}
|
||||||
isReady = true;
|
else {
|
||||||
#endif
|
#if PIN_EXISTS(SPINDLE_LASER_ENA)
|
||||||
|
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_STATE);
|
||||||
|
#endif
|
||||||
|
isReadyForUI = false; // Only used for UI display updates.
|
||||||
|
TERN_(SPINDLE_LASER_USE_PWM, ocr_off());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(SPINDLE_CHANGE_DIR)
|
#if ENABLED(SPINDLE_CHANGE_DIR)
|
||||||
|
|||||||
+164
-177
@@ -34,84 +34,98 @@
|
|||||||
#include "../libs/buzzer.h"
|
#include "../libs/buzzer.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(LASER_POWER_INLINE)
|
// Inline laser power
|
||||||
#include "../module/planner.h"
|
#include "../module/planner.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PCT_TO_PWM(X) ((X) * 255 / 100)
|
#define PCT_TO_PWM(X) ((X) * 255 / 100)
|
||||||
#define PCT_TO_SERVO(X) ((X) * 180 / 100)
|
#define PCT_TO_SERVO(X) ((X) * 180 / 100)
|
||||||
|
|
||||||
|
|
||||||
|
// Laser/Cutter operation mode
|
||||||
|
enum CutterMode : int8_t {
|
||||||
|
CUTTER_MODE_ERROR = -1,
|
||||||
|
CUTTER_MODE_STANDARD, // M3 power is applied directly and waits for planner moves to sync.
|
||||||
|
CUTTER_MODE_CONTINUOUS, // M3 or G1/2/3 move power is controlled within planner blocks, set with 'M3 I', cleared with 'M5 I'.
|
||||||
|
CUTTER_MODE_DYNAMIC // M4 laser power is proportional to the feed rate, set with 'M4 I', cleared with 'M5 I'.
|
||||||
|
};
|
||||||
|
|
||||||
class SpindleLaser {
|
class SpindleLaser {
|
||||||
public:
|
public:
|
||||||
static const inline uint8_t pct_to_ocr(const_float_t pct) { return uint8_t(PCT_TO_PWM(pct)); }
|
static CutterMode cutter_mode;
|
||||||
|
|
||||||
|
static constexpr uint8_t pct_to_ocr(const_float_t pct) { return uint8_t(PCT_TO_PWM(pct)); }
|
||||||
|
|
||||||
// cpower = configured values (e.g., SPEED_POWER_MAX)
|
// cpower = configured values (e.g., SPEED_POWER_MAX)
|
||||||
|
|
||||||
// Convert configured power range to a percentage
|
// Convert configured power range to a percentage
|
||||||
static const inline uint8_t cpwr_to_pct(const cutter_cpower_t cpwr) {
|
static constexpr cutter_cpower_t power_floor = TERN(CUTTER_POWER_RELATIVE, SPEED_POWER_MIN, 0);
|
||||||
constexpr cutter_cpower_t power_floor = TERN(CUTTER_POWER_RELATIVE, SPEED_POWER_MIN, 0),
|
static constexpr uint8_t cpwr_to_pct(const cutter_cpower_t cpwr) {
|
||||||
power_range = SPEED_POWER_MAX - power_floor;
|
return cpwr ? round(100.0f * (cpwr - power_floor) / (SPEED_POWER_MAX - power_floor)) : 0;
|
||||||
return cpwr ? round(100.0f * (cpwr - power_floor) / power_range) : 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a cpower (e.g., SPEED_POWER_STARTUP) to unit power (upwr, upower),
|
// Convert config defines from RPM to %, angle or PWM when in Spindle mode
|
||||||
// which can be PWM, Percent, Servo angle, or RPM (rel/abs).
|
// and convert from PERCENT to PWM when in Laser mode
|
||||||
static const inline cutter_power_t cpwr_to_upwr(const cutter_cpower_t cpwr) { // STARTUP power to Unit power
|
static constexpr cutter_power_t cpwr_to_upwr(const cutter_cpower_t cpwr) { // STARTUP power to Unit power
|
||||||
const cutter_power_t upwr = (
|
return (
|
||||||
#if ENABLED(SPINDLE_FEATURE)
|
#if ENABLED(SPINDLE_FEATURE)
|
||||||
// Spindle configured values are in RPM
|
// Spindle configured define values are in RPM
|
||||||
#if CUTTER_UNIT_IS(RPM)
|
#if CUTTER_UNIT_IS(RPM)
|
||||||
cpwr // to RPM
|
cpwr // to same
|
||||||
#elif CUTTER_UNIT_IS(PERCENT) // to PCT
|
#elif CUTTER_UNIT_IS(PERCENT)
|
||||||
cpwr_to_pct(cpwr)
|
cpwr_to_pct(cpwr) // to Percent
|
||||||
#elif CUTTER_UNIT_IS(SERVO) // to SERVO angle
|
#elif CUTTER_UNIT_IS(SERVO)
|
||||||
PCT_TO_SERVO(cpwr_to_pct(cpwr))
|
PCT_TO_SERVO(cpwr_to_pct(cpwr)) // to SERVO angle
|
||||||
#else // to PWM
|
#else
|
||||||
PCT_TO_PWM(cpwr_to_pct(cpwr))
|
PCT_TO_PWM(cpwr_to_pct(cpwr)) // to PWM
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
// Laser configured values are in PCT
|
// Laser configured define values are in Percent
|
||||||
#if CUTTER_UNIT_IS(PWM255)
|
#if CUTTER_UNIT_IS(PWM255)
|
||||||
PCT_TO_PWM(cpwr)
|
PCT_TO_PWM(cpwr) // to PWM
|
||||||
#else
|
#else
|
||||||
cpwr // to RPM/PCT
|
cpwr // to same
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
return upwr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cutter_power_t mpower_min() { return cpwr_to_upwr(SPEED_POWER_MIN); }
|
static constexpr cutter_power_t mpower_min() { return cpwr_to_upwr(SPEED_POWER_MIN); }
|
||||||
static const cutter_power_t mpower_max() { return cpwr_to_upwr(SPEED_POWER_MAX); }
|
static constexpr cutter_power_t mpower_max() { return cpwr_to_upwr(SPEED_POWER_MAX); }
|
||||||
|
|
||||||
#if ENABLED(LASER_FEATURE)
|
#if ENABLED(LASER_FEATURE)
|
||||||
static cutter_test_pulse_t testPulse; // Test fire Pulse ms value
|
static cutter_test_pulse_t testPulse; // (ms) Test fire pulse duration
|
||||||
|
static uint8_t last_block_power; // Track power changes for dynamic power
|
||||||
|
|
||||||
|
static feedRate_t feedrate_mm_m, last_feedrate_mm_m; // (mm/min) Track feedrate changes for dynamic power
|
||||||
|
static bool laser_feedrate_changed() {
|
||||||
|
const bool changed = last_feedrate_mm_m != feedrate_mm_m;
|
||||||
|
if (changed) last_feedrate_mm_m = feedrate_mm_m;
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static bool isReady; // Ready to apply power setting from the UI to OCR
|
static bool isReadyForUI; // Ready to apply power setting from the UI to OCR
|
||||||
static uint8_t power;
|
static bool enable_state;
|
||||||
|
static uint8_t power,
|
||||||
|
last_power_applied; // Basic power state tracking
|
||||||
|
|
||||||
#if ENABLED(MARLIN_DEV_MODE)
|
static cutter_frequency_t frequency; // Set PWM frequency; range: 2K-50K
|
||||||
static cutter_frequency_t frequency; // Set PWM frequency; range: 2K-50K
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static cutter_power_t menuPower, // Power as set via LCD menu in PWM, Percentage or RPM
|
static cutter_power_t menuPower, // Power as set via LCD menu in PWM, Percentage or RPM
|
||||||
unitPower; // Power as displayed status in PWM, Percentage or RPM
|
unitPower; // Power as displayed status in PWM, Percentage or RPM
|
||||||
|
|
||||||
static void init();
|
static void init();
|
||||||
|
|
||||||
#if ENABLED(MARLIN_DEV_MODE)
|
#if ENABLED(HAL_CAN_SET_PWM_FREQ) && SPINDLE_LASER_FREQUENCY
|
||||||
static void refresh_frequency() { hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); }
|
static void refresh_frequency() { hal.set_pwm_frequency(pin_t(SPINDLE_LASER_PWM_PIN), frequency); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Modifying this function should update everywhere
|
// Modifying this function should update everywhere
|
||||||
static bool enabled(const cutter_power_t opwr) { return opwr > 0; }
|
static bool enabled(const cutter_power_t opwr) { return opwr > 0; }
|
||||||
static bool enabled() { return enabled(power); }
|
static bool enabled() { return enable_state; }
|
||||||
|
|
||||||
static void apply_power(const uint8_t inpow);
|
static void apply_power(const uint8_t inpow);
|
||||||
|
|
||||||
FORCE_INLINE static void refresh() { apply_power(power); }
|
FORCE_INLINE static void refresh() { apply_power(power); }
|
||||||
FORCE_INLINE static void set_power(const uint8_t upwr) { power = upwr; refresh(); }
|
|
||||||
|
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
||||||
|
|
||||||
@@ -122,7 +136,6 @@ public:
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static void set_ocr(const uint8_t ocr);
|
static void set_ocr(const uint8_t ocr);
|
||||||
static void ocr_set_power(const uint8_t ocr) { power = ocr; set_ocr(ocr); }
|
|
||||||
static void ocr_off();
|
static void ocr_off();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,78 +153,76 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Correct power to configured range
|
|
||||||
*/
|
|
||||||
static cutter_power_t power_to_range(const cutter_power_t pwr) {
|
|
||||||
return power_to_range(pwr, _CUTTER_POWER(CUTTER_POWER_UNIT));
|
|
||||||
}
|
|
||||||
|
|
||||||
static cutter_power_t power_to_range(const cutter_power_t pwr, const uint8_t pwrUnit) {
|
|
||||||
static constexpr float
|
|
||||||
min_pct = TERN(CUTTER_POWER_RELATIVE, 0, TERN(SPINDLE_FEATURE, round(100.0f * (SPEED_POWER_MIN) / (SPEED_POWER_MAX)), SPEED_POWER_MIN)),
|
|
||||||
max_pct = TERN(SPINDLE_FEATURE, 100, SPEED_POWER_MAX);
|
|
||||||
if (pwr <= 0) return 0;
|
|
||||||
cutter_power_t upwr;
|
|
||||||
switch (pwrUnit) {
|
|
||||||
case _CUTTER_POWER_PWM255:
|
|
||||||
upwr = cutter_power_t(
|
|
||||||
(pwr < pct_to_ocr(min_pct)) ? pct_to_ocr(min_pct) // Use minimum if set below
|
|
||||||
: (pwr > pct_to_ocr(max_pct)) ? pct_to_ocr(max_pct) // Use maximum if set above
|
|
||||||
: pwr
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case _CUTTER_POWER_PERCENT:
|
|
||||||
upwr = cutter_power_t(
|
|
||||||
(pwr < min_pct) ? min_pct // Use minimum if set below
|
|
||||||
: (pwr > max_pct) ? max_pct // Use maximum if set above
|
|
||||||
: pwr // PCT
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
case _CUTTER_POWER_RPM:
|
|
||||||
upwr = cutter_power_t(
|
|
||||||
(pwr < SPEED_POWER_MIN) ? SPEED_POWER_MIN // Use minimum if set below
|
|
||||||
: (pwr > SPEED_POWER_MAX) ? SPEED_POWER_MAX // Use maximum if set above
|
|
||||||
: pwr // Calculate OCR value
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
return upwr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SPINDLE_LASER_USE_PWM
|
#endif // SPINDLE_LASER_USE_PWM
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable/Disable spindle/laser
|
* Correct power to configured range
|
||||||
* @param enable true = enable; false = disable
|
|
||||||
*/
|
*/
|
||||||
static void set_enabled(const bool enable) {
|
static cutter_power_t power_to_range(const cutter_power_t pwr, const uint8_t pwrUnit=_CUTTER_POWER(CUTTER_POWER_UNIT)) {
|
||||||
uint8_t value = 0;
|
static constexpr float
|
||||||
if (enable) {
|
min_pct = TERN(CUTTER_POWER_RELATIVE, 0, TERN(SPINDLE_FEATURE, round(100.0f * (SPEED_POWER_MIN) / (SPEED_POWER_MAX)), SPEED_POWER_MIN)),
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
max_pct = TERN(SPINDLE_FEATURE, 100, SPEED_POWER_MAX);
|
||||||
if (power)
|
if (pwr <= 0) return 0;
|
||||||
value = power;
|
cutter_power_t upwr;
|
||||||
else if (unitPower)
|
switch (pwrUnit) {
|
||||||
value = upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP));
|
case _CUTTER_POWER_PWM255: { // PWM
|
||||||
#else
|
const uint8_t pmin = pct_to_ocr(min_pct), pmax = pct_to_ocr(max_pct);
|
||||||
value = 255;
|
upwr = cutter_power_t(constrain(pwr, pmin, pmax));
|
||||||
#endif
|
} break;
|
||||||
|
case _CUTTER_POWER_PERCENT: // Percent
|
||||||
|
upwr = cutter_power_t(constrain(pwr, min_pct, max_pct));
|
||||||
|
break;
|
||||||
|
case _CUTTER_POWER_RPM: // Calculate OCR value
|
||||||
|
upwr = cutter_power_t(constrain(pwr, SPEED_POWER_MIN, SPEED_POWER_MAX));
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
}
|
}
|
||||||
set_power(value);
|
return upwr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void disable() { isReady = false; set_enabled(false); }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for spindle to spin up or spin down
|
* Enable Laser or Spindle output.
|
||||||
|
* It's important to prevent changing the power output value during inline cutter operation.
|
||||||
|
* Inline power is adjusted in the planner to support LASER_TRAP_POWER and CUTTER_MODE_DYNAMIC mode.
|
||||||
*
|
*
|
||||||
* @param on true = state to on; false = state to off.
|
* This method accepts one of the following control states:
|
||||||
|
*
|
||||||
|
* - For CUTTER_MODE_STANDARD the cutter power is either full on/off or ocr-based and it will apply
|
||||||
|
* SPEED_POWER_STARTUP if no value is assigned.
|
||||||
|
*
|
||||||
|
* - For CUTTER_MODE_CONTINUOUS inline and power remains where last set and the cutter output enable flag is set.
|
||||||
|
*
|
||||||
|
* - CUTTER_MODE_DYNAMIC is also inline-based and it just sets the enable output flag.
|
||||||
|
*
|
||||||
|
* - For CUTTER_MODE_ERROR set the output enable_state flag directly and set power to 0 for any mode.
|
||||||
|
* This mode allows a global power shutdown action to occur.
|
||||||
*/
|
*/
|
||||||
static void power_delay(const bool on) {
|
static void set_enabled(bool enable) {
|
||||||
#if DISABLED(LASER_POWER_INLINE)
|
switch (cutter_mode) {
|
||||||
safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
|
case CUTTER_MODE_STANDARD:
|
||||||
|
apply_power(enable ? TERN(SPINDLE_LASER_USE_PWM, (power ?: (unitPower ? upower_to_ocr(cpwr_to_upwr(SPEED_POWER_STARTUP)) : 0)), 255) : 0);
|
||||||
|
break;
|
||||||
|
case CUTTER_MODE_CONTINUOUS:
|
||||||
|
TERN_(LASER_FEATURE, set_inline_enabled(enable));
|
||||||
|
break;
|
||||||
|
case CUTTER_MODE_DYNAMIC:
|
||||||
|
TERN_(LASER_FEATURE, set_inline_enabled(enable));
|
||||||
|
break;
|
||||||
|
case CUTTER_MODE_ERROR: // Error mode, no enable and kill power.
|
||||||
|
enable = false;
|
||||||
|
apply_power(0);
|
||||||
|
}
|
||||||
|
#if SPINDLE_LASER_ENA_PIN
|
||||||
|
WRITE(SPINDLE_LASER_ENA_PIN, enable ? SPINDLE_LASER_ACTIVE_STATE : !SPINDLE_LASER_ACTIVE_STATE);
|
||||||
#endif
|
#endif
|
||||||
|
enable_state = enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void disable() { isReadyForUI = false; set_enabled(false); }
|
||||||
|
|
||||||
|
// Wait for spindle/laser to startup or shutdown
|
||||||
|
static void power_delay(const bool on) {
|
||||||
|
safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(SPINDLE_CHANGE_DIR)
|
#if ENABLED(SPINDLE_CHANGE_DIR)
|
||||||
@@ -223,122 +234,98 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(AIR_EVACUATION)
|
#if ENABLED(AIR_EVACUATION)
|
||||||
static void air_evac_enable(); // Turn On Cutter Vacuum or Laser Blower motor
|
static void air_evac_enable(); // Turn On Cutter Vacuum or Laser Blower motor
|
||||||
static void air_evac_disable(); // Turn Off Cutter Vacuum or Laser Blower motor
|
static void air_evac_disable(); // Turn Off Cutter Vacuum or Laser Blower motor
|
||||||
static void air_evac_toggle(); // Toggle Cutter Vacuum or Laser Blower motor
|
static void air_evac_toggle(); // Toggle Cutter Vacuum or Laser Blower motor
|
||||||
static bool air_evac_state() { // Get current state
|
static bool air_evac_state() { // Get current state
|
||||||
return (READ(AIR_EVACUATION_PIN) == AIR_EVACUATION_ACTIVE);
|
return (READ(AIR_EVACUATION_PIN) == AIR_EVACUATION_ACTIVE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(AIR_ASSIST)
|
#if ENABLED(AIR_ASSIST)
|
||||||
static void air_assist_enable(); // Turn on air assist
|
static void air_assist_enable(); // Turn on air assist
|
||||||
static void air_assist_disable(); // Turn off air assist
|
static void air_assist_disable(); // Turn off air assist
|
||||||
static void air_assist_toggle(); // Toggle air assist
|
static void air_assist_toggle(); // Toggle air assist
|
||||||
static bool air_assist_state() { // Get current state
|
static bool air_assist_state() { // Get current state
|
||||||
return (READ(AIR_ASSIST_PIN) == AIR_ASSIST_ACTIVE);
|
return (READ(AIR_ASSIST_PIN) == AIR_ASSIST_ACTIVE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_MARLINUI_MENU
|
#if HAS_MARLINUI_MENU
|
||||||
static void enable_with_dir(const bool reverse) {
|
|
||||||
isReady = true;
|
#if ENABLED(SPINDLE_FEATURE)
|
||||||
const uint8_t ocr = TERN(SPINDLE_LASER_USE_PWM, upower_to_ocr(menuPower), 255);
|
static void enable_with_dir(const bool reverse) {
|
||||||
if (menuPower)
|
isReadyForUI = true;
|
||||||
power = ocr;
|
const uint8_t ocr = TERN(SPINDLE_LASER_USE_PWM, upower_to_ocr(menuPower), 255);
|
||||||
else
|
if (menuPower)
|
||||||
menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP);
|
power = ocr;
|
||||||
unitPower = menuPower;
|
else
|
||||||
set_reverse(reverse);
|
menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP);
|
||||||
set_enabled(true);
|
unitPower = menuPower;
|
||||||
}
|
set_reverse(reverse);
|
||||||
FORCE_INLINE static void enable_forward() { enable_with_dir(false); }
|
set_enabled(true);
|
||||||
FORCE_INLINE static void enable_reverse() { enable_with_dir(true); }
|
}
|
||||||
FORCE_INLINE static void enable_same_dir() { enable_with_dir(is_reverse()); }
|
FORCE_INLINE static void enable_forward() { enable_with_dir(false); }
|
||||||
|
FORCE_INLINE static void enable_reverse() { enable_with_dir(true); }
|
||||||
|
FORCE_INLINE static void enable_same_dir() { enable_with_dir(is_reverse()); }
|
||||||
|
#endif // SPINDLE_FEATURE
|
||||||
|
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
||||||
static void update_from_mpower() {
|
static void update_from_mpower() {
|
||||||
if (isReady) power = upower_to_ocr(menuPower);
|
if (isReadyForUI) power = upower_to_ocr(menuPower);
|
||||||
unitPower = menuPower;
|
unitPower = menuPower;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ENABLED(LASER_FEATURE)
|
#if ENABLED(LASER_FEATURE)
|
||||||
|
// Toggle the laser on/off with menuPower. Apply SPEED_POWER_STARTUP if it was 0 on entry.
|
||||||
|
static void menu_set_enabled(const bool state) {
|
||||||
|
set_enabled(state);
|
||||||
|
if (state) {
|
||||||
|
if (!menuPower) menuPower = cpwr_to_upwr(SPEED_POWER_STARTUP);
|
||||||
|
power = upower_to_ocr(menuPower);
|
||||||
|
apply_power(power);
|
||||||
|
} else
|
||||||
|
apply_power(0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test fire the laser using the testPulse ms duration
|
* Test fire the laser using the testPulse ms duration
|
||||||
* Also fires with any PWM power that was previous set
|
* Also fires with any PWM power that was previous set
|
||||||
* If not set defaults to 80% power
|
* If not set defaults to 80% power
|
||||||
*/
|
*/
|
||||||
static void test_fire_pulse() {
|
static void test_fire_pulse() {
|
||||||
TERN_(HAS_BEEPER, buzzer.tone(30, 3000));
|
BUZZ(30, 3000);
|
||||||
enable_forward(); // Turn Laser on (Spindle speak but same funct)
|
cutter_mode = CUTTER_MODE_STANDARD; // Menu needs standard mode.
|
||||||
delay(testPulse); // Delay for time set by user in pulse ms menu screen.
|
menu_set_enabled(true); // Laser On
|
||||||
disable(); // Turn laser off
|
delay(testPulse); // Delay for time set by user in pulse ms menu screen.
|
||||||
|
menu_set_enabled(false); // Laser Off
|
||||||
}
|
}
|
||||||
#endif
|
#endif // LASER_FEATURE
|
||||||
|
|
||||||
#endif // HAS_MARLINUI_MENU
|
#endif // HAS_MARLINUI_MENU
|
||||||
|
|
||||||
#if ENABLED(LASER_POWER_INLINE)
|
#if ENABLED(LASER_FEATURE)
|
||||||
/**
|
|
||||||
* Inline power adds extra fields to the planner block
|
|
||||||
* to handle laser power and scale to movement speed.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Force disengage planner power control
|
// Dynamic mode rate calculation
|
||||||
static void inline_disable() {
|
static uint8_t calc_dynamic_power() {
|
||||||
isReady = false;
|
if (feedrate_mm_m > 65535) return 255; // Too fast, go always on
|
||||||
unitPower = 0;
|
uint16_t rate = uint16_t(feedrate_mm_m); // 16 bits from the G-code parser float input
|
||||||
planner.laser_inline.status.isPlanned = false;
|
rate >>= 8; // Take the G-code input e.g. F40000 and shift off the lower bits to get an OCR value from 1-255
|
||||||
planner.laser_inline.status.isEnabled = false;
|
return uint8_t(rate);
|
||||||
planner.laser_inline.power = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Inline modes of all other functions; all enable planner inline power control
|
// Inline modes of all other functions; all enable planner inline power control
|
||||||
static void set_inline_enabled(const bool enable) {
|
static void set_inline_enabled(const bool enable) { planner.laser_inline.status.isEnabled = enable; }
|
||||||
if (enable)
|
|
||||||
inline_power(255);
|
|
||||||
else {
|
|
||||||
isReady = false;
|
|
||||||
unitPower = menuPower = 0;
|
|
||||||
planner.laser_inline.status.isPlanned = false;
|
|
||||||
TERN(SPINDLE_LASER_USE_PWM, inline_ocr_power, inline_power)(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the power for subsequent movement blocks
|
// Set the power for subsequent movement blocks
|
||||||
static void inline_power(const cutter_power_t upwr) {
|
static void inline_power(const cutter_power_t cpwr) {
|
||||||
unitPower = menuPower = upwr;
|
TERN(SPINDLE_LASER_USE_PWM, power = planner.laser_inline.power = cpwr, planner.laser_inline.power = cpwr > 0 ? 255 : 0);
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
|
||||||
#if ENABLED(SPEED_POWER_RELATIVE) && !CUTTER_UNIT_IS(RPM) // relative mode does not turn laser off at 0, except for RPM
|
|
||||||
planner.laser_inline.status.isEnabled = true;
|
|
||||||
planner.laser_inline.power = upower_to_ocr(upwr);
|
|
||||||
isReady = true;
|
|
||||||
#else
|
|
||||||
inline_ocr_power(upower_to_ocr(upwr));
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
planner.laser_inline.status.isEnabled = enabled(upwr);
|
|
||||||
planner.laser_inline.power = upwr;
|
|
||||||
isReady = enabled(upwr);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void inline_direction(const bool) { /* never */ }
|
#endif // LASER_FEATURE
|
||||||
|
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
static void kill() { disable(); }
|
||||||
static void inline_ocr_power(const uint8_t ocrpwr) {
|
|
||||||
isReady = ocrpwr > 0;
|
|
||||||
planner.laser_inline.status.isEnabled = ocrpwr > 0;
|
|
||||||
planner.laser_inline.power = ocrpwr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // LASER_POWER_INLINE
|
|
||||||
|
|
||||||
static void kill() {
|
|
||||||
TERN_(LASER_POWER_INLINE, inline_disable());
|
|
||||||
disable();
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern SpindleLaser cutter;
|
extern SpindleLaser cutter;
|
||||||
|
|||||||
@@ -74,12 +74,10 @@ typedef IF<(SPEED_POWER_MAX > 255), uint16_t, uint8_t>::type cutter_cpower_t;
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef uint16_t cutter_frequency_t;
|
||||||
|
|
||||||
#if ENABLED(LASER_FEATURE)
|
#if ENABLED(LASER_FEATURE)
|
||||||
typedef uint16_t cutter_test_pulse_t;
|
typedef uint16_t cutter_test_pulse_t;
|
||||||
#define CUTTER_MENU_PULSE_TYPE uint16_3
|
#define CUTTER_MENU_PULSE_TYPE uint16_3
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(MARLIN_DEV_MODE)
|
|
||||||
typedef uint16_t cutter_frequency_t;
|
|
||||||
#define CUTTER_MENU_FREQUENCY_TYPE uint16_5
|
#define CUTTER_MENU_FREQUENCY_TYPE uint16_5
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -33,17 +33,12 @@
|
|||||||
#include "../gcode/gcode.h"
|
#include "../gcode/gcode.h"
|
||||||
|
|
||||||
#if ENABLED(TMC_DEBUG)
|
#if ENABLED(TMC_DEBUG)
|
||||||
#include "../module/planner.h"
|
|
||||||
#include "../libs/hex_print.h"
|
#include "../libs/hex_print.h"
|
||||||
#if ENABLED(MONITOR_DRIVER_STATUS)
|
#if ENABLED(MONITOR_DRIVER_STATUS)
|
||||||
static uint16_t report_tmc_status_interval; // = 0
|
static uint16_t report_tmc_status_interval; // = 0
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_MARLINUI_MENU
|
|
||||||
#include "../module/stepper.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check for over temperature or short to ground error flags.
|
* Check for over temperature or short to ground error flags.
|
||||||
* Report and log warning of overtemperature condition.
|
* Report and log warning of overtemperature condition.
|
||||||
|
|||||||
@@ -107,7 +107,6 @@
|
|||||||
|
|
||||||
#include "../../MarlinCore.h"
|
#include "../../MarlinCore.h"
|
||||||
#include "../../module/planner.h"
|
#include "../../module/planner.h"
|
||||||
#include "../../module/stepper.h"
|
|
||||||
#include "../../module/motion.h"
|
#include "../../module/motion.h"
|
||||||
#include "../../module/tool_change.h"
|
#include "../../module/tool_change.h"
|
||||||
#include "../../module/temperature.h"
|
#include "../../module/temperature.h"
|
||||||
@@ -306,7 +305,7 @@ typedef struct {
|
|||||||
LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1);
|
LIMIT(e.x, X_MIN_POS + 1, X_MAX_POS - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (position_is_reachable(s.x, s.y) && position_is_reachable(e.x, e.y))
|
if (position_is_reachable(s) && position_is_reachable(e))
|
||||||
print_line_from_here_to_there(s, e);
|
print_line_from_here_to_there(s, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user