Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
136075d3fe | ||
|
42facec7ce | ||
|
e8b5641b27 |
@@ -4,10 +4,10 @@ root = true
|
|||||||
[{*.patch,syntax_test_*}]
|
[{*.patch,syntax_test_*}]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[{*.c,*.cpp,*.h,*.ino}]
|
[{*.c,*.cpp,*.h}]
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
|
|
||||||
[{*.c,*.cpp,*.h,*.ino,Makefile}]
|
[{*.c,*.cpp,*.h,Makefile}]
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
end_of_line = lf
|
end_of_line = lf
|
||||||
|
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -17,5 +17,3 @@
|
|||||||
*.png binary
|
*.png binary
|
||||||
*.jpg binary
|
*.jpg binary
|
||||||
*.fon binary
|
*.fon binary
|
||||||
*.bin binary
|
|
||||||
*.woff binary
|
|
||||||
|
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1,3 +1,3 @@
|
|||||||
github: [thinkyhead]
|
github: [thinkyhead]
|
||||||
patreon: thinkyhead
|
patreon: thinkyhead
|
||||||
custom: ["https://www.thinkyhead.com/donate-to-marlin"]
|
custom: ["http://www.thinkyhead.com/donate-to-marlin"]
|
||||||
|
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
43
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
---
|
||||||
|
name: Bug report
|
||||||
|
about: Report a bug in Marlin
|
||||||
|
title: "[BUG] (short description)"
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md
|
||||||
|
|
||||||
|
Do you want to ask a question? Are you looking for support? Please don't post here. Instead please use one of the support links at https://github.com/MarlinFirmware/Marlin/issues/new/choose
|
||||||
|
|
||||||
|
Before filing an issue be sure to test the "bugfix" branches to see whether the issue has been resolved.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Bug Description
|
||||||
|
|
||||||
|
<!-- Description of the bug -->
|
||||||
|
|
||||||
|
### My Configurations
|
||||||
|
|
||||||
|
**Required:** Please include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files.
|
||||||
|
|
||||||
|
### Steps to Reproduce
|
||||||
|
|
||||||
|
<!-- Please describe the steps needed to reproduce the issue -->
|
||||||
|
|
||||||
|
1. [First Step]
|
||||||
|
2. [Second Step]
|
||||||
|
3. [and so on...]
|
||||||
|
|
||||||
|
**Expected behavior:** [What you expect to happen]
|
||||||
|
|
||||||
|
**Actual behavior:** [What actually happens]
|
||||||
|
|
||||||
|
#### Additional Information
|
||||||
|
|
||||||
|
* Provide pictures or links to videos that clearly demonstrate the issue.
|
||||||
|
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.
|
169
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
169
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,169 +0,0 @@
|
|||||||
name: 🪲 Report a bug
|
|
||||||
description: Create a bug report to help improve Marlin Firmware
|
|
||||||
title: "[BUG] (bug summary)"
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: >
|
|
||||||
Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose).
|
|
||||||
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
**Thank you for reporting a bug in Marlin Firmware!**
|
|
||||||
|
|
||||||
## Before Reporting a Bug
|
|
||||||
|
|
||||||
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
|
|
||||||
|
|
||||||
- Test with the [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see whether the issue still exists.
|
|
||||||
|
|
||||||
## Instructions
|
|
||||||
|
|
||||||
Please follow the instructions below. Failure to do so may result in your issue being closed. See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/2.0.x/.github/contributing.md) for additional guidelines.
|
|
||||||
|
|
||||||
1. Provide a good title starting with [BUG].
|
|
||||||
2. Fill out all sections of this bug report form.
|
|
||||||
3. Always attach configuration files so we can build and test your setup.
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Did you test the latest `bugfix-2.0.x` code?
|
|
||||||
description: >-
|
|
||||||
Always try the latest code to make sure the issue you are reporting is not already fixed. To download
|
|
||||||
the latest code just [click this link](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip).
|
|
||||||
options:
|
|
||||||
- Yes, and the problem still exists.
|
|
||||||
- No, but I will test it now!
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
# Bug Details
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Bug Description
|
|
||||||
description: >-
|
|
||||||
Describe the bug in this section. Tell us what you were trying to do and what
|
|
||||||
happened that you did not expect. Provide a clear and concise description of the
|
|
||||||
problem and include as many details as possible.
|
|
||||||
placeholder: |
|
|
||||||
Marlin doesn't work.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Bug Timeline
|
|
||||||
description: Is this a new bug or an old issue? When did it first start?
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Expected behavior
|
|
||||||
description: >-
|
|
||||||
What did you expect to happen?
|
|
||||||
placeholder: I expected it to move left.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Actual behavior
|
|
||||||
description: What actually happened instead?
|
|
||||||
placeholder: It moved right instead of left.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Steps to Reproduce
|
|
||||||
description: >-
|
|
||||||
Please describe the steps needed to reproduce the issue.
|
|
||||||
placeholder: |
|
|
||||||
1. [First Step] ...
|
|
||||||
2. [Second Step] ...
|
|
||||||
3. [and so on] ...
|
|
||||||
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
# Your Setup
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Version of Marlin Firmware
|
|
||||||
description: "See the About Menu on the LCD or the output of `M115`. NOTE: For older releases we only patch critical bugs."
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Printer model
|
|
||||||
description: Creality Ender 3, Prusa mini, or Kossel Delta?
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Electronics
|
|
||||||
description: Stock electronics, upgrade board, or something else?
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
attributes:
|
|
||||||
label: Add-ons
|
|
||||||
description: Please list any hardware add-ons that could be involved.
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Bed Leveling
|
|
||||||
description: What kind of bed leveling compensation are you using?
|
|
||||||
options:
|
|
||||||
- UBL Bilinear mesh
|
|
||||||
- ABL Bilinear mesh
|
|
||||||
- ABL Linear grid
|
|
||||||
- ABL 3-point
|
|
||||||
- MBL Manual Bed Leveling
|
|
||||||
- No Bed Leveling
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Your Slicer
|
|
||||||
description: Do you use Slic3r, Prusa Slicer, Simplify3D, IdeaMaker...?
|
|
||||||
options:
|
|
||||||
- Slic3r
|
|
||||||
- Simplify3D
|
|
||||||
- Prusa Slicer
|
|
||||||
- IdeaMaker
|
|
||||||
- Cura
|
|
||||||
- Other (explain below)
|
|
||||||
|
|
||||||
- type: dropdown
|
|
||||||
attributes:
|
|
||||||
label: Host Software
|
|
||||||
description: Do you use OctoPrint, Repetier Host, Pronterface...?
|
|
||||||
options:
|
|
||||||
- SD Card (headless)
|
|
||||||
- Repetier Host
|
|
||||||
- OctoPrint
|
|
||||||
- Pronterface
|
|
||||||
- Cura
|
|
||||||
- Same as my slicer
|
|
||||||
- Other (explain below)
|
|
||||||
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: >-
|
|
||||||
## Other things to include
|
|
||||||
|
|
||||||
Please also be sure to include these items to help with troubleshooting:
|
|
||||||
|
|
||||||
* **A ZIP file** containing your `Configuration.h` and `Configuration_adv.h`.
|
|
||||||
(Please don't paste lengthy configuration text here.)
|
|
||||||
* **Log output** from the host. (`M111 S247` for maximum logging.)
|
|
||||||
* **Images or videos** demonstrating the problem, if it helps to make it clear.
|
|
||||||
* **A G-Code file** that exposes the problem, if not affecting _all_ G-code.
|
|
||||||
|
|
||||||
If you've made any other modifications to the firmware, please describe them in detail in the space provided.
|
|
||||||
|
|
||||||
When pasting formatted text into the box below don't forget to put ` ``` ` (on its own line) before and after to make it readable.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Additional information & file uploads
|
|
13
.github/ISSUE_TEMPLATE/config.yml
vendored
13
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,20 +1,17 @@
|
|||||||
blank_issues_enabled: false
|
blank_issues_enabled: false
|
||||||
contact_links:
|
contact_links:
|
||||||
- name: 📖 Marlin Documentation
|
- name: Marlin Documentation
|
||||||
url: http://marlinfw.org/
|
url: http://marlinfw.org/
|
||||||
about: Lots of documentation on installing and using Marlin.
|
about: Lots of documentation on installing and using Marlin.
|
||||||
- name: 👤 MarlinFirmware Facebook group
|
- name: MarlinFirmware Facebook group
|
||||||
url: https://www.facebook.com/groups/1049718498464482
|
url: https://www.facebook.com/groups/1049718498464482
|
||||||
about: Please ask and answer questions here.
|
about: Please ask and answer questions here.
|
||||||
- name: 🕹 Marlin on Discord
|
- name: Marlin on Discord
|
||||||
url: https://discord.gg/n5NJ59y
|
url: https://discord.gg/n5NJ59y
|
||||||
about: Join the Discord server for support and discussion.
|
about: Join the Discord server for support and discussion.
|
||||||
- name: 🔗 Marlin Discussion Forum
|
- name: Marlin Discussion Forum
|
||||||
url: http://forums.reprap.org/list.php?415
|
url: http://forums.reprap.org/list.php?415
|
||||||
about: A searchable web forum hosted by RepRap dot org.
|
about: A searchable web forum hosted by RepRap dot org.
|
||||||
- name: 📺 Marlin Videos on YouTube
|
- name: Marlin Videos on YouTube
|
||||||
url: https://www.youtube.com/results?search_query=marlin+firmware
|
url: https://www.youtube.com/results?search_query=marlin+firmware
|
||||||
about: Tutorials and more from Marlin users all around the world. Great for new users!
|
about: Tutorials and more from Marlin users all around the world. Great for new users!
|
||||||
- name: 💸 Want to donate?
|
|
||||||
url: https://www.thinkyhead.com/donate-to-marlin
|
|
||||||
about: Please take a look at the various options to support Marlin Firmware's development financially!
|
|
||||||
|
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
35
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
---
|
||||||
|
name: Feature request
|
||||||
|
about: Request a Feature
|
||||||
|
title: "[FR] (feature request title)"
|
||||||
|
labels: ''
|
||||||
|
assignees: ''
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md
|
||||||
|
|
||||||
|
Do you want to ask a question? Are you looking for support? Please don't post here. Instead please use one of the support links at https://github.com/MarlinFirmware/Marlin/issues/new/choose
|
||||||
|
|
||||||
|
Before filing an issue be sure to test the "bugfix" branches to see whether the issue has been resolved.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Description
|
||||||
|
|
||||||
|
<!-- Description of the requested feature -->
|
||||||
|
|
||||||
|
### Feature Workflow
|
||||||
|
|
||||||
|
<!-- Please describe the feature's behavior, user interaction, etc. -->
|
||||||
|
|
||||||
|
1. [First Action]
|
||||||
|
2. [Second Action]
|
||||||
|
3. [and so on...]
|
||||||
|
|
||||||
|
#### Additional Information
|
||||||
|
|
||||||
|
* Provide pictures or links that demonstrate a similar feature or concept.
|
||||||
|
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.
|
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,44 +0,0 @@
|
|||||||
name: ✨ Request a feature
|
|
||||||
description: Request a new Marlin Firmware feature
|
|
||||||
title: "[FR] (feature summary)"
|
|
||||||
labels: 'T: Feature Request'
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: >
|
|
||||||
Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose).
|
|
||||||
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: >
|
|
||||||
**Thank you for requesting a new Marlin Firmware feature!**
|
|
||||||
|
|
||||||
## Before Requesting a Feature
|
|
||||||
|
|
||||||
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
|
|
||||||
|
|
||||||
- Check the latest [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see if the feature already exists.
|
|
||||||
|
|
||||||
- Before you proceed with your request, please consider if it is necessary to make it into a firmware feature, or if it may be better suited for a slicer or host feature.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Is your feature request related to a problem? Please describe.
|
|
||||||
description: A clear description of the problem (e.g., "I need X but Marlin can't do it [...]").
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Are you looking for hardware support?
|
|
||||||
description: Tell us the printer, board, or peripheral that needs support.
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Describe the feature you want
|
|
||||||
description: A clear description of the feature and how you think it should work.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Additional context
|
|
||||||
description: Add any other context or screenshots about the feature request here.
|
|
21
.github/contributing.md
vendored
21
.github/contributing.md
vendored
@@ -34,15 +34,16 @@ 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 RepRap forum](http://forums.reprap.org/list.php?415)
|
||||||
* [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/)
|
* [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/)
|
||||||
|
|
||||||
If chat is more your speed, you can join the MarlinFirmware Discord server:
|
If chat is more your speed, you can join the MarlinFirmware Slack team:
|
||||||
|
|
||||||
* Use the link https://discord.gg/n5NJ59y to join up as a General User.
|
* Join the Marlin Slack Team
|
||||||
* Even though our Discord is pretty active, it may take a while for community members to respond — please be patient!
|
* To obtain group access, please [send a request](http://www.thinkyhead.com/contact/9) to @thinkyhead.
|
||||||
* Use the `#general` channel for general questions or discussion about Marlin.
|
* Even though Slack is a chat service, sometimes it takes several hours for community members to respond — please be patient!
|
||||||
* Other channels exist for certain topics or are limited to Patrons. Check the channel list.
|
* Use the `#general` channel for general questions or discussion about Marlin.
|
||||||
|
* Other channels exist for certain topics. Check the channel list.
|
||||||
|
|
||||||
## How Can I Contribute?
|
## How Can I Contribute?
|
||||||
|
|
||||||
@@ -92,7 +93,7 @@ Before creating a suggestion, please check [this list](#before-submitting-a-sugg
|
|||||||
|
|
||||||
#### Before Submitting a Feature Request
|
#### Before Submitting a Feature Request
|
||||||
|
|
||||||
* **Check the [Marlin website](https://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](https://marlinfw.org/docs/configuration/configuration.html).
|
* **Check the [Marlin website](http://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](http://marlinfw.org/docs/configuration/configuration.html).
|
||||||
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
||||||
|
|
||||||
#### How Do I Submit A (Good) Feature Request?
|
#### How Do I Submit A (Good) Feature Request?
|
||||||
@@ -116,12 +117,12 @@ 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-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
|
Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](http://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.
|
||||||
* Include pictures, diagrams, and links to videos in your Pull Request to demonstrate your changes, if needed.
|
* Include pictures, diagrams, and links to videos in your Pull Request to demonstrate your changes, if needed.
|
||||||
* Follow the [Coding Standards](https://marlinfw.org/docs/development/coding_standards.html) posted on our website.
|
* Follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website.
|
||||||
* Document new code with clear and concise comments.
|
* Document new code with clear and concise comments.
|
||||||
* End all files with a newline.
|
* End all files with a newline.
|
||||||
|
|
||||||
@@ -136,7 +137,7 @@ Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x
|
|||||||
|
|
||||||
### C++ Coding Standards
|
### C++ Coding Standards
|
||||||
|
|
||||||
* Please read and follow the [Coding Standards](https://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests.
|
* Please read and follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests.
|
||||||
|
|
||||||
### Documentation
|
### Documentation
|
||||||
|
|
||||||
|
41
.github/issue_template.md
vendored
41
.github/issue_template.md
vendored
@@ -1,35 +1,16 @@
|
|||||||
<!--
|
# NO SUPPORT REQUESTS PLEASE
|
||||||
|
|
||||||
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/.github/code_of_conduct.md
|
Support Requests posted here will be automatically closed!
|
||||||
|
|
||||||
Do you want to ask a question? Are you looking for support? Please don't post here. Instead use one of the following options:
|
This Issue Queue is for Marlin bug reports and development-related issues, and we prefer not to handle user-support questions here. See https://github.com/MarlinFirmware/Marlin/blob/1.1.x/.github/contributing.md#i-dont-want-to-read-this-whole-thing-i-just-have-a-question.
|
||||||
|
|
||||||
- The Marlin Firmware forum at https://reprap.org/forum/list.php?415
|
For best results getting help with configuration and troubleshooting, please use the following resources:
|
||||||
- The MarlinFirmware Facebook Group at https://www.facebook.com/groups/1049718498464482/
|
|
||||||
- The MarlinFirmware Discord Server at https://discord.gg/n5NJ59y.
|
|
||||||
|
|
||||||
Before filing an issue be sure to test the latest "bugfix" branch to see whether the issue is already addressed.
|
- RepRap.org Marlin Forum http://forums.reprap.org/list.php?415
|
||||||
|
- Tom's 3D Forums https://discuss.toms3d.org/
|
||||||
|
- Facebook Group "Marlin Firmware" https://www.facebook.com/groups/1049718498464482/
|
||||||
|
- 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
|
||||||
|
- Marlin Discord server. Join link: https://discord.gg/n5NJ59y
|
||||||
|
|
||||||
-->
|
After seeking help from the community, if the consensus points to to a bug in Marlin, then you should post a Bug Report at https://github.com/MarlinFirmware/Marlin/issues/new/choose).
|
||||||
|
|
||||||
### Description
|
|
||||||
|
|
||||||
<!-- Description of the bug or requested feature -->
|
|
||||||
|
|
||||||
### Steps to Reproduce
|
|
||||||
|
|
||||||
<!-- If this is a Bug Report, please describe the steps needed to reproduce the issue -->
|
|
||||||
|
|
||||||
1. [First Step]
|
|
||||||
2. [Second Step]
|
|
||||||
3. [and so on...]
|
|
||||||
|
|
||||||
**Expected behavior:** [What you expect to happen]
|
|
||||||
|
|
||||||
**Actual behavior:** [What actually happens]
|
|
||||||
|
|
||||||
#### Additional Information
|
|
||||||
|
|
||||||
* Include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files.
|
|
||||||
* Provide pictures or links to videos that clearly demonstrate the issue.
|
|
||||||
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.
|
|
||||||
|
40
.github/lock.yml
vendored
40
.github/lock.yml
vendored
@@ -1,40 +0,0 @@
|
|||||||
#
|
|
||||||
# Configuration for Lock Threads - https://github.com/dessant/lock-threads-app
|
|
||||||
#
|
|
||||||
|
|
||||||
# Number of days of inactivity before a closed issue or pull request is locked
|
|
||||||
daysUntilLock: 60
|
|
||||||
|
|
||||||
# Skip issues and pull requests created before a given timestamp. Timestamp must
|
|
||||||
# follow ISO 8601 (`YYYY-MM-DD`). Set to `false` to disable
|
|
||||||
skipCreatedBefore: false
|
|
||||||
|
|
||||||
# Issues and pull requests with these labels will be ignored. Set to `[]` to disable
|
|
||||||
exemptLabels: [ 'no-locking' ]
|
|
||||||
|
|
||||||
# Label to add before locking, such as `outdated`. Set to `false` to disable
|
|
||||||
lockLabel: false
|
|
||||||
|
|
||||||
# Comment to post before locking. Set to `false` to disable
|
|
||||||
lockComment: >
|
|
||||||
This thread has been automatically locked since there has not been
|
|
||||||
any recent activity after it was closed. Please open a new issue for
|
|
||||||
related bugs.
|
|
||||||
|
|
||||||
# Assign `resolved` as the reason for locking. Set to `false` to disable
|
|
||||||
setLockReason: true
|
|
||||||
|
|
||||||
# Limit to only `issues` or `pulls`
|
|
||||||
# only: issues
|
|
||||||
|
|
||||||
# Optionally, specify configuration settings just for `issues` or `pulls`
|
|
||||||
# issues:
|
|
||||||
# exemptLabels:
|
|
||||||
# - help-wanted
|
|
||||||
# lockLabel: outdated
|
|
||||||
|
|
||||||
# pulls:
|
|
||||||
# daysUntilLock: 30
|
|
||||||
|
|
||||||
# Repository to extend settings from
|
|
||||||
# _extends: repo
|
|
24
.github/pull_request_template.md
vendored
24
.github/pull_request_template.md
vendored
@@ -1,33 +1,19 @@
|
|||||||
<!--
|
### Requirements
|
||||||
|
|
||||||
Submitting a Pull Request
|
* Filling out this template is required. Pull Requests without a clear description may be closed at the maintainers' discretion.
|
||||||
|
|
||||||
- Please fill out all sections of this form. You can delete the helpful comments.
|
|
||||||
- Pull Requests without clear information will take longer and may even be rejected.
|
|
||||||
- We get a high volume of submissions so please be patient during review.
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Description
|
### Description
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
|
|
||||||
Clearly describe the submitted changes with lots of details. Include images where helpful. Initial reviewers may not be familiar with the subject, so be as thorough as possible. You can use MarkDown syntax to improve readability with bullet lists, code blocks, and so on. PREVIEW and fix up formatting before submitting.
|
We must be able to understand your proposed change from this description. If we can't understand what the code will do from this description, the Pull Request may be closed at the maintainers' discretion. Keep in mind that the maintainer reviewing this PR may not be familiar with or have worked with the code recently, so please walk us through the concepts.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
|
|
||||||
### Requirements
|
|
||||||
|
|
||||||
<!-- Does this PR require a specific board, LCD, etc.? -->
|
|
||||||
|
|
||||||
### Benefits
|
### Benefits
|
||||||
|
|
||||||
<!-- What does this PR fix or improve? -->
|
<!-- What does this fix or improve? -->
|
||||||
|
|
||||||
### Configurations
|
|
||||||
|
|
||||||
<!-- Attach Configurations ZIP and any other files needed to test this PR. -->
|
|
||||||
|
|
||||||
### Related Issues
|
### Related Issues
|
||||||
|
|
||||||
<!-- Does this PR fix a bug or fulfill a Feature Request? Link related Issues here. -->
|
<!-- Whether this fixes a bug or fulfills a feature request, please list any related Issues here. -->
|
||||||
|
7
.github/workflows/bad-target.md
vendored
Normal file
7
.github/workflows/bad-target.md
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Thanks for your contribution! Unfortunately we can't accept PRs directed at release branches. We make patches to the bugfix branches and only later do we push them out as releases.
|
||||||
|
|
||||||
|
Please redo this PR starting with the `bugfix-2.0.x` branch and be careful to target `bugfix-2.0.x` when resubmitting the PR.
|
||||||
|
|
||||||
|
It may help to set your fork's default branch to `bugfix-2.0.x`.
|
||||||
|
|
||||||
|
See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions.
|
4
.github/workflows/bump-date.yml
vendored
4
.github/workflows/bump-date.yml
vendored
@@ -11,8 +11,6 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
bump_date:
|
bump_date:
|
||||||
name: Bump Distribution Date
|
|
||||||
if: github.repository == 'MarlinFirmware/Marlin'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
@@ -26,9 +24,9 @@ jobs:
|
|||||||
- name: Bump Distribution Date
|
- name: Bump Distribution Date
|
||||||
run: |
|
run: |
|
||||||
# Inline Bump Script
|
# Inline Bump Script
|
||||||
|
[[ "$GITHUB_REPOSITORY" == "MarlinFirmware/Marlin" ]] || exit 0
|
||||||
DIST=$( date +"%Y-%m-%d" )
|
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/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.name "${GITHUB_ACTOR}" && \
|
||||||
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
|
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
|
||||||
git add . && \
|
git add . && \
|
||||||
|
23
.github/workflows/check-pr.yml
vendored
23
.github/workflows/check-pr.yml
vendored
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# check-pr.yml
|
# comment-pr.yml
|
||||||
# Close PRs directed at release branches
|
# Add a comment to any PR directed to a release branch
|
||||||
#
|
#
|
||||||
|
|
||||||
name: PR Bad Target
|
name: PR Bad Target
|
||||||
@@ -14,19 +14,14 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
bad_target:
|
bad_target:
|
||||||
name: PR Bad Target
|
|
||||||
if: github.repository == 'MarlinFirmware/Marlin'
|
|
||||||
|
|
||||||
|
name: PR Bad Target
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: superbrothers/close-pull-request@v3
|
- uses: actions/checkout@v1
|
||||||
with:
|
- uses: harupy/comment-on-pr@master
|
||||||
comment: >
|
env:
|
||||||
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.
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
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.
|
filename: bad-target.md
|
||||||
|
|
||||||
It may help to set your fork's default branch to `bugfix-2.0.x`.
|
|
||||||
|
|
||||||
See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions.
|
|
||||||
|
39
.github/workflows/clean-closed.yml
vendored
39
.github/workflows/clean-closed.yml
vendored
@@ -1,39 +0,0 @@
|
|||||||
#
|
|
||||||
# clean-closed.yml
|
|
||||||
# Remove obsolete labels when an Issue or PR is closed
|
|
||||||
#
|
|
||||||
|
|
||||||
name: Clean Closed
|
|
||||||
|
|
||||||
on:
|
|
||||||
pull_request:
|
|
||||||
types: [closed]
|
|
||||||
issues:
|
|
||||||
types: [closed]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
remove_label:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
strategy:
|
|
||||||
matrix:
|
|
||||||
label:
|
|
||||||
- "S: Don't Merge"
|
|
||||||
- "S: Hold for 2.1"
|
|
||||||
- "S: Please Merge"
|
|
||||||
- "S: Please Test"
|
|
||||||
- "help wanted"
|
|
||||||
- "Needs: Discussion"
|
|
||||||
- "Needs: Documentation"
|
|
||||||
- "Needs: More Data"
|
|
||||||
- "Needs: Patch"
|
|
||||||
- "Needs: Testing"
|
|
||||||
- "Needs: Work"
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- name: Remove Labels
|
|
||||||
uses: actions-ecosystem/action-remove-labels@v1
|
|
||||||
with:
|
|
||||||
github_token: ${{ github.token }}
|
|
||||||
labels: ${{ matrix.label }}
|
|
28
.github/workflows/close-stale.yml
vendored
28
.github/workflows/close-stale.yml
vendored
@@ -1,28 +0,0 @@
|
|||||||
#
|
|
||||||
# close-stale.yml
|
|
||||||
# Close open issues after a period of inactivity
|
|
||||||
#
|
|
||||||
|
|
||||||
name: Close Stale Issues
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "22 1 * * *"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
stale:
|
|
||||||
name: Close Stale Issues
|
|
||||||
if: github.repository == 'MarlinFirmware/Marlin'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/stale@v3
|
|
||||||
with:
|
|
||||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
stale-issue-message: 'This issue has had no activity in the last 60 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 10 days.'
|
|
||||||
days-before-stale: 60
|
|
||||||
days-before-close: 10
|
|
||||||
stale-issue-label: 'stale-closing-soon'
|
|
||||||
exempt-all-assignees: true
|
|
||||||
exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: Discussion,Needs: Documentation,Needs: More Data,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking'
|
|
32
.github/workflows/lock-closed.yml
vendored
32
.github/workflows/lock-closed.yml
vendored
@@ -1,32 +0,0 @@
|
|||||||
#
|
|
||||||
# lock-closed.yml
|
|
||||||
# Lock closed issues after a period of inactivity
|
|
||||||
#
|
|
||||||
|
|
||||||
name: Lock Closed Issues
|
|
||||||
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: '0 1/13 * * *'
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lock:
|
|
||||||
name: Lock Closed Issues
|
|
||||||
if: github.repository == 'MarlinFirmware/Marlin'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: dessant/lock-threads@v2
|
|
||||||
with:
|
|
||||||
github-token: ${{ github.token }}
|
|
||||||
process-only: 'issues'
|
|
||||||
issue-lock-inactive-days: '60'
|
|
||||||
issue-exclude-created-before: '2017-07-01T00:00:00Z'
|
|
||||||
issue-exclude-labels: 'no-locking'
|
|
||||||
issue-lock-labels: ''
|
|
||||||
issue-lock-comment: >
|
|
||||||
This issue has been automatically locked since there
|
|
||||||
has not been any recent activity after it was closed.
|
|
||||||
Please open a new issue for related bugs.
|
|
||||||
issue-lock-reason: ''
|
|
110
.github/workflows/test-builds.yml
vendored
110
.github/workflows/test-builds.yml
vendored
@@ -9,14 +9,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- bugfix-2.0.x
|
- bugfix-2.0.x
|
||||||
paths-ignore:
|
- dev-2.1.x
|
||||||
- config/**
|
|
||||||
- data/**
|
|
||||||
- docs/**
|
|
||||||
- '**/*.md'
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- bugfix-2.0.x
|
|
||||||
paths-ignore:
|
paths-ignore:
|
||||||
- config/**
|
- config/**
|
||||||
- data/**
|
- data/**
|
||||||
@@ -25,8 +18,6 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
test_builds:
|
test_builds:
|
||||||
name: Run All Tests
|
|
||||||
if: github.repository == 'MarlinFirmware/Marlin'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
@@ -36,110 +27,77 @@ jobs:
|
|||||||
# Base Environments
|
# Base Environments
|
||||||
|
|
||||||
- DUE
|
- DUE
|
||||||
- DUE_archim
|
|
||||||
- esp32
|
- esp32
|
||||||
- linux_native
|
- linux_native
|
||||||
- mega2560
|
- megaatmega2560
|
||||||
- at90usb1286_dfu
|
|
||||||
- teensy31
|
- teensy31
|
||||||
- teensy35
|
- teensy35
|
||||||
- teensy41
|
|
||||||
- SAMD51_grandcentral_m4
|
- SAMD51_grandcentral_m4
|
||||||
|
|
||||||
# Extended AVR Environments
|
# Extended AVR Environments
|
||||||
|
|
||||||
- FYSETC_F6
|
- FYSETC_F6_13
|
||||||
- mega1280
|
- megaatmega1280
|
||||||
- rambo
|
- rambo
|
||||||
- sanguino1284p
|
- sanguino_atmega1284p
|
||||||
- sanguino644p
|
- sanguino_atmega644p
|
||||||
|
|
||||||
# STM32F1 (Maple) Environments
|
# Extended STM32 Environments
|
||||||
|
|
||||||
#- STM32F103RC_btt_maple
|
- STM32F103RC_bigtree
|
||||||
- STM32F103RC_btt_USB_maple
|
- STM32F103RC_bigtree_USB
|
||||||
- STM32F103RC_fysetc_maple
|
- STM32F103RE_bigtree
|
||||||
- STM32F103RC_meeb
|
- STM32F103RE_bigtree_USB
|
||||||
- jgaurora_a5s_a1_maple
|
- STM32F103RC_fysetc
|
||||||
- STM32F103VE_longer_maple
|
- jgaurora_a5s_a1
|
||||||
#- mks_robin_maple
|
|
||||||
- mks_robin_lite_maple
|
|
||||||
- mks_robin_pro_maple
|
|
||||||
#- mks_robin_nano35_maple
|
|
||||||
#- STM32F103RET6_creality_maple
|
|
||||||
- STM32F103VE_ZM3E4V2_USB_maple
|
|
||||||
|
|
||||||
# STM32 (ST) Environments
|
|
||||||
|
|
||||||
- STM32F103RC_btt
|
|
||||||
#- STM32F103RC_btt_USB
|
|
||||||
- STM32F103RE_btt
|
|
||||||
- STM32F103RE_btt_USB
|
|
||||||
- STM32F103RET6_creality
|
|
||||||
- STM32F103VE_longer
|
- STM32F103VE_longer
|
||||||
- STM32F407VE_black
|
- STM32F407VE_black
|
||||||
- STM32F401VE_STEVAL
|
|
||||||
- BIGTREE_BTT002
|
|
||||||
- BIGTREE_SKR_PRO
|
- BIGTREE_SKR_PRO
|
||||||
- BIGTREE_GTR_V1_0
|
|
||||||
- mks_robin
|
- mks_robin
|
||||||
- ARMED
|
- ARMED
|
||||||
- FYSETC_S6
|
- FYSETC_S6
|
||||||
- STM32F070CB_malyan
|
|
||||||
- STM32F070RB_malyan
|
|
||||||
- malyan_M300
|
|
||||||
- FLYF407ZG
|
|
||||||
- rumba32
|
|
||||||
- LERDGEX
|
|
||||||
- LERDGEK
|
|
||||||
- mks_robin_nano35
|
|
||||||
- NUCLEO_F767ZI
|
|
||||||
- REMRAM_V1
|
|
||||||
- BTT_SKR_SE_BX
|
|
||||||
- chitu_f103
|
|
||||||
- Index_Mobo_Rev03
|
|
||||||
|
|
||||||
# Put lengthy tests last
|
# Put lengthy tests last
|
||||||
|
|
||||||
- LPC1768
|
- LPC1768
|
||||||
- LPC1769
|
- LPC1769
|
||||||
|
|
||||||
|
# STM32 with non-STM framework. both broken for now. they should use HAL_STM32 which is working.
|
||||||
|
|
||||||
|
#- STM32F4
|
||||||
|
#- STM32F7
|
||||||
|
|
||||||
# Non-working environment tests
|
# Non-working environment tests
|
||||||
|
|
||||||
|
#- BIGTREE_BTT002
|
||||||
#- at90usb1286_cdc
|
#- at90usb1286_cdc
|
||||||
|
#- at90usb1286_dfu
|
||||||
#- STM32F103CB_malyan
|
#- STM32F103CB_malyan
|
||||||
#- STM32F103RE
|
#- mks_robin_lite
|
||||||
#- mks_robin_mini
|
#- mks_robin_mini
|
||||||
|
#- mks_robin_nano
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Check out the PR
|
|
||||||
uses: actions/checkout@v2
|
|
||||||
|
|
||||||
- name: Cache pip
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ~/.cache/pip
|
|
||||||
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-pip-
|
|
||||||
|
|
||||||
- name: Cache PlatformIO
|
|
||||||
uses: actions/cache@v2
|
|
||||||
with:
|
|
||||||
path: ~/.platformio
|
|
||||||
key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }}
|
|
||||||
|
|
||||||
- name: Select Python 3.7
|
- name: Select Python 3.7
|
||||||
uses: actions/setup-python@v2
|
uses: actions/setup-python@v1
|
||||||
with:
|
with:
|
||||||
python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
|
python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
|
||||||
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
|
||||||
|
|
||||||
- name: Install PlatformIO
|
- name: Install PlatformIO
|
||||||
run: |
|
run: |
|
||||||
pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
|
pip install -U https://github.com/platformio/platformio-core/archive/master.zip
|
||||||
platformio update
|
platformio update
|
||||||
|
|
||||||
|
- name: Check out the PR
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
- name: Run ${{ matrix.test-platform }} Tests
|
- name: Run ${{ matrix.test-platform }} Tests
|
||||||
run: |
|
run: |
|
||||||
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
|
# Inline tests script
|
||||||
|
[[ "$GITHUB_REPOSITORY" == "MarlinFirmware/Marlin" ]] || exit 0
|
||||||
|
chmod +x buildroot/bin/*
|
||||||
|
chmod +x buildroot/share/tests/*
|
||||||
|
export PATH=./buildroot/bin/:./buildroot/share/tests/:${PATH}
|
||||||
|
run_tests . ${{ matrix.test-platform }}
|
||||||
|
22
.github/workflows/unlock-reopened.yml
vendored
22
.github/workflows/unlock-reopened.yml
vendored
@@ -1,22 +0,0 @@
|
|||||||
#
|
|
||||||
# unlock-reopened.yml
|
|
||||||
# Unlock an issue whenever it is re-opened
|
|
||||||
#
|
|
||||||
|
|
||||||
name: "Unlock reopened issue"
|
|
||||||
|
|
||||||
on:
|
|
||||||
issues:
|
|
||||||
types: [reopened]
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
unlock:
|
|
||||||
name: Unlock Reopened
|
|
||||||
if: github.repository == 'MarlinFirmware/Marlin'
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: OSDKDev/unlock-issues@v1.1
|
|
||||||
with:
|
|
||||||
repo-token: "${{ secrets.GITHUB_TOKEN }}"
|
|
71
.gitignore
vendored
71
.gitignore
vendored
@@ -1,6 +1,6 @@
|
|||||||
#
|
#
|
||||||
# Marlin 3D Printer Firmware
|
# Marlin 3D Printer Firmware
|
||||||
# Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
# Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
#
|
#
|
||||||
# Based on Sprinter and grbl.
|
# Based on Sprinter and grbl.
|
||||||
# Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
# Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||||
@@ -21,32 +21,21 @@
|
|||||||
|
|
||||||
# Generated files
|
# Generated files
|
||||||
_Version.h
|
_Version.h
|
||||||
bdf2u8g
|
bdf2u8g.exe
|
||||||
|
genpages.exe
|
||||||
|
marlin_config.json
|
||||||
|
mczip.h
|
||||||
|
language*.csv
|
||||||
|
out-csv/
|
||||||
|
out-language/
|
||||||
|
*.gen
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
#
|
|
||||||
# OS
|
# OS
|
||||||
#
|
|
||||||
applet/
|
applet/
|
||||||
*.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
#
|
# Compiled C++ Object files
|
||||||
# Misc
|
|
||||||
#
|
|
||||||
*~
|
|
||||||
*.orig
|
|
||||||
*.rej
|
|
||||||
*.bak
|
|
||||||
*.idea
|
|
||||||
*.s
|
|
||||||
*.i
|
|
||||||
*.ii
|
|
||||||
*.swp
|
|
||||||
tags
|
|
||||||
|
|
||||||
#
|
|
||||||
# C++
|
|
||||||
#
|
|
||||||
# Compiled Object files
|
|
||||||
*.slo
|
*.slo
|
||||||
*.lo
|
*.lo
|
||||||
*.o
|
*.o
|
||||||
@@ -77,10 +66,7 @@ tags
|
|||||||
*.out
|
*.out
|
||||||
*.app
|
*.app
|
||||||
|
|
||||||
#
|
# Compiled C Object files
|
||||||
# C
|
|
||||||
#
|
|
||||||
# Object files
|
|
||||||
*.o
|
*.o
|
||||||
*.ko
|
*.ko
|
||||||
*.obj
|
*.obj
|
||||||
@@ -137,20 +123,22 @@ __vm/
|
|||||||
vc-fileutils.settings
|
vc-fileutils.settings
|
||||||
|
|
||||||
# Visual Studio Code
|
# Visual Studio Code
|
||||||
.vscode
|
.vscode/*
|
||||||
.vscode/.browse.c_cpp.db*
|
!.vscode/extensions.json
|
||||||
.vscode/c_cpp_properties.json
|
|
||||||
.vscode/launch.json
|
|
||||||
.vscode/*.db
|
|
||||||
|
|
||||||
#Simulation
|
# Simulation files
|
||||||
imgui.ini
|
imgui.ini
|
||||||
eeprom.dat
|
eeprom.dat
|
||||||
|
spi_flash.bin
|
||||||
|
fs.img
|
||||||
|
|
||||||
#cmake
|
# CMake
|
||||||
|
buildroot/share/cmake/*
|
||||||
CMakeLists.txt
|
CMakeLists.txt
|
||||||
|
!buildroot/share/cmake/CMakeLists.txt
|
||||||
src/CMakeLists.txt
|
src/CMakeLists.txt
|
||||||
CMakeListsPrivate.txt
|
CMakeListsPrivate.txt
|
||||||
|
build/
|
||||||
|
|
||||||
# CLion
|
# CLion
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
@@ -168,6 +156,15 @@ __pycache__
|
|||||||
# IOLogger logs
|
# IOLogger logs
|
||||||
*_log.csv
|
*_log.csv
|
||||||
|
|
||||||
# Simulation / Native
|
# Misc.
|
||||||
eeprom.dat
|
*~
|
||||||
imgui.ini
|
*.orig
|
||||||
|
*.rej
|
||||||
|
*.bak
|
||||||
|
*.idea
|
||||||
|
*.i
|
||||||
|
*.ii
|
||||||
|
*.swp
|
||||||
|
tags
|
||||||
|
*.logs
|
||||||
|
*.bak
|
||||||
|
9
LICENSE
9
LICENSE
@@ -3,7 +3,7 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 3, 29 June 2007
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
Copyright (c) 2007 Free Software Foundation, Inc. <https://www.fsf.org/>
|
Copyright (c) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
@@ -647,7 +647,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
@@ -666,11 +666,12 @@ might be different; for a GUI interface, you would use an "about box".
|
|||||||
You should also get your employer (if you work as a programmer) or school,
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
<https://www.gnu.org/licenses/>.
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
The GNU General Public License does not permit incorporating your program
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
may consider it more useful to permit linking proprietary applications with
|
may consider it more useful to permit linking proprietary applications with
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
Public License instead of this License. But first, please read
|
Public License instead of this License. But first, please read
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
||||||
|
|
||||||
|
52
Makefile
52
Makefile
@@ -1,52 +0,0 @@
|
|||||||
help:
|
|
||||||
@echo "Tasks for local development:"
|
|
||||||
@echo "* tests-single-ci: Run a single test from inside the CI"
|
|
||||||
@echo "* tests-single-local: Run a single test locally"
|
|
||||||
@echo "* tests-single-local-docker: Run a single test locally, using docker-compose"
|
|
||||||
@echo "* tests-all-local: Run all tests locally"
|
|
||||||
@echo "* tests-all-local-docker: Run all tests locally, using docker-compose"
|
|
||||||
@echo "* setup-local-docker: Setup local docker-compose"
|
|
||||||
@echo ""
|
|
||||||
@echo "Options for testing:"
|
|
||||||
@echo " TEST_TARGET Set when running tests-single-*, to select the"
|
|
||||||
@echo " test. If you set it to ALL it will run all "
|
|
||||||
@echo " tests, but some of them are broken: use "
|
|
||||||
@echo " tests-all-* instead to run only the ones that "
|
|
||||||
@echo " run on GitHub CI"
|
|
||||||
@echo " ONLY_TEST Limit tests to only those that contain this, or"
|
|
||||||
@echo " the index of the test (1-based)"
|
|
||||||
@echo " VERBOSE_PLATFORMIO If you want the full PIO output, set any value"
|
|
||||||
@echo " GIT_RESET_HARD Used by CI: reset all local changes. WARNING:"
|
|
||||||
@echo " THIS WILL UNDO ANY CHANGES YOU'VE MADE!"
|
|
||||||
.PHONY: help
|
|
||||||
|
|
||||||
tests-single-ci:
|
|
||||||
export GIT_RESET_HARD=true
|
|
||||||
$(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET)
|
|
||||||
.PHONY: tests-single-ci
|
|
||||||
|
|
||||||
tests-single-local:
|
|
||||||
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local" ; return 1; fi
|
|
||||||
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
|
|
||||||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
|
||||||
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
|
|
||||||
.PHONY: tests-single-local
|
|
||||||
|
|
||||||
tests-single-local-docker:
|
|
||||||
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local-docker" ; return 1; fi
|
|
||||||
docker-compose run --rm marlin $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
|
|
||||||
.PHONY: tests-single-local-docker
|
|
||||||
|
|
||||||
tests-all-local:
|
|
||||||
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
|
|
||||||
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
|
|
||||||
&& for TEST_TARGET in $$(./get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
|
|
||||||
.PHONY: tests-all-local
|
|
||||||
|
|
||||||
tests-all-local-docker:
|
|
||||||
docker-compose run --rm marlin $(MAKE) tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
|
|
||||||
.PHONY: tests-all-local-docker
|
|
||||||
|
|
||||||
setup-local-docker:
|
|
||||||
docker-compose build
|
|
||||||
.PHONY: setup-local-docker
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
302
Marlin/Makefile
302
Marlin/Makefile
@@ -14,7 +14,7 @@
|
|||||||
# Detailed instructions for using the makefile:
|
# Detailed instructions for using the makefile:
|
||||||
#
|
#
|
||||||
# 1. Modify the line containing "ARDUINO_INSTALL_DIR" to point to the directory that
|
# 1. Modify the line containing "ARDUINO_INSTALL_DIR" to point to the directory that
|
||||||
# contains the Arduino installation (for example, under macOS, this
|
# contains the Arduino installation (for example, under Mac OS X, this
|
||||||
# might be /Applications/Arduino.app/Contents/Resources/Java).
|
# might be /Applications/Arduino.app/Contents/Resources/Java).
|
||||||
#
|
#
|
||||||
# 2. Modify the line containing "UPLOAD_PORT" to refer to the filename
|
# 2. Modify the line containing "UPLOAD_PORT" to refer to the filename
|
||||||
@@ -22,10 +22,8 @@
|
|||||||
# (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file
|
# (e.g. UPLOAD_PORT = /dev/tty.USB0). If the exact name of this file
|
||||||
# changes, you can use * as a wild card (e.g. UPLOAD_PORT = /dev/tty.usb*).
|
# changes, you can use * as a wild card (e.g. UPLOAD_PORT = /dev/tty.usb*).
|
||||||
#
|
#
|
||||||
# 3. Set the line containing "MCU" to match your board's processor. Set
|
# 3. Set the line containing "MCU" to match your board's processor.
|
||||||
# "PROG_MCU" as the AVR part name corresponding to "MCU". You can use the
|
# Older one's are atmega8 based, newer ones like Arduino Mini, Bluetooth
|
||||||
# following command to get a list of correspondences: `avrdude -c alf -p x`
|
|
||||||
# Older boards are atmega8 based, newer ones like Arduino Mini, Bluetooth
|
|
||||||
# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
|
# or Diecimila have the atmega168. If you're using a LilyPad Arduino,
|
||||||
# change F_CPU to 8000000. If you are using Gen7 electronics, you
|
# change F_CPU to 8000000. If you are using Gen7 electronics, you
|
||||||
# probably need to use 20000000. Either way, you must regenerate
|
# probably need to use 20000000. Either way, you must regenerate
|
||||||
@@ -36,18 +34,18 @@
|
|||||||
# 5. Type "make upload", reset your Arduino board, and press enter to
|
# 5. Type "make upload", reset your Arduino board, and press enter to
|
||||||
# upload your program to the Arduino board.
|
# upload your program to the Arduino board.
|
||||||
#
|
#
|
||||||
# Note that all settings at the top of this file can be overridden from
|
# Note that all settings at the top of this file can be overriden from
|
||||||
# the command line with, for example, "make HARDWARE_MOTHERBOARD=71"
|
# the command line with, for example, "make HARDWARE_MOTHERBOARD=71"
|
||||||
#
|
#
|
||||||
# To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use...
|
# To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use...
|
||||||
#
|
#
|
||||||
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
|
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
|
||||||
# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino
|
# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino
|
||||||
#
|
#
|
||||||
# To compile and upload simply add "upload" to the end of the line...
|
# To compile and upload simply add "upload" to the end of the line...
|
||||||
#
|
#
|
||||||
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
|
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
|
||||||
# HARDWARE_MOTHERBOARD=1200 ARDUINO_INSTALL_DIR=/root/arduino upload
|
# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino upload
|
||||||
#
|
#
|
||||||
# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or
|
# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or
|
||||||
# start upload manually (using stk500) like so:
|
# start upload manually (using stk500) like so:
|
||||||
@@ -59,26 +57,7 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# This defines the board to compile for (see boards.h for your board's ID)
|
# This defines the board to compile for (see boards.h for your board's ID)
|
||||||
HARDWARE_MOTHERBOARD ?= 1020
|
HARDWARE_MOTHERBOARD ?= 11
|
||||||
|
|
||||||
ifeq ($(OS),Windows_NT)
|
|
||||||
# Windows
|
|
||||||
ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino
|
|
||||||
ARDUINO_USER_DIR ?= ${HOME}/Arduino
|
|
||||||
else
|
|
||||||
UNAME_S := $(shell uname -s)
|
|
||||||
ifeq ($(UNAME_S),Linux)
|
|
||||||
# Linux
|
|
||||||
ARDUINO_INSTALL_DIR ?= /usr/share/arduino
|
|
||||||
ARDUINO_USER_DIR ?= ${HOME}/Arduino
|
|
||||||
endif
|
|
||||||
ifeq ($(UNAME_S),Darwin)
|
|
||||||
# Darwin (macOS)
|
|
||||||
ARDUINO_INSTALL_DIR ?= /Applications/Arduino.app/Contents/Java
|
|
||||||
ARDUINO_USER_DIR ?= ${HOME}/Documents/Arduino
|
|
||||||
AVR_TOOLS_PATH ?= /Applications/Arduino.app/Contents/Java/hardware/tools/avr/bin/
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
# Arduino source install directory, and version number
|
# Arduino source install directory, and version number
|
||||||
# On most linuxes this will be /usr/share/arduino
|
# On most linuxes this will be /usr/share/arduino
|
||||||
@@ -88,44 +67,38 @@ ARDUINO_VERSION ?= 106
|
|||||||
# The installed Libraries are in the User folder
|
# The installed Libraries are in the User folder
|
||||||
ARDUINO_USER_DIR ?= ${HOME}/Arduino
|
ARDUINO_USER_DIR ?= ${HOME}/Arduino
|
||||||
|
|
||||||
# You can optionally set a path to the avr-gcc tools.
|
# You can optionally set a path to the avr-gcc tools. Requires a trailing slash. (ex: /usr/local/avr-gcc/bin)
|
||||||
# Requires a trailing slash. For example, /usr/local/avr-gcc/bin/
|
|
||||||
AVR_TOOLS_PATH ?=
|
AVR_TOOLS_PATH ?=
|
||||||
|
|
||||||
# Programmer configuration
|
#Programmer configuration
|
||||||
UPLOAD_RATE ?= 57600
|
UPLOAD_RATE ?= 57600
|
||||||
AVRDUDE_PROGRAMMER ?= arduino
|
AVRDUDE_PROGRAMMER ?= arduino
|
||||||
# On most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
|
# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
|
||||||
UPLOAD_PORT ?= /dev/ttyUSB0
|
UPLOAD_PORT ?= /dev/ttyUSB0
|
||||||
|
|
||||||
# Directory used to build files in, contains all the build files, from object
|
#Directory used to build files in, contains all the build files, from object files to the final hex file
|
||||||
# files to the final hex file on linux it is best to put an absolute path
|
#on linux it is best to put an absolute path like /home/username/tmp .
|
||||||
# like /home/username/tmp .
|
|
||||||
BUILD_DIR ?= applet
|
BUILD_DIR ?= applet
|
||||||
|
|
||||||
# This defines whether Liquid_TWI2 support will be built
|
# This defines whether Liquid_TWI2 support will be built
|
||||||
LIQUID_TWI2 ?= 0
|
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 U8GLIB is needed (may require RELOC_WORKAROUND)
|
||||||
# Disabling this (and SPEAKER) saves approximately 350 bytes of memory.
|
U8GLIB ?= 1
|
||||||
TONE ?= 1
|
|
||||||
|
|
||||||
# This defines if U8GLIB is needed (may require RELOC_WORKAROUND)
|
# this defines whether to include the Trinamic TMCStepper library
|
||||||
U8GLIB ?= 0
|
TMC ?= 1
|
||||||
|
|
||||||
# This defines whether to include the Trinamic TMCStepper library
|
# this defines whether to include the AdaFruit NeoPixel library
|
||||||
TMC ?= 0
|
|
||||||
|
|
||||||
# This defines whether to include the AdaFruit NeoPixel library
|
|
||||||
NEOPIXEL ?= 0
|
NEOPIXEL ?= 0
|
||||||
|
|
||||||
############
|
############
|
||||||
# Try to automatically determine whether RELOC_WORKAROUND is needed based
|
# Try to automatically determine whether RELOC_WORKAROUND is needed based
|
||||||
# on GCC versions:
|
# on GCC versions:
|
||||||
# https://www.avrfreaks.net/comment/1789106#comment-1789106
|
# http://www.avrfreaks.net/comment/1789106#comment-1789106
|
||||||
|
|
||||||
CC_MAJ:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC__ | cut -f3 -d\ )
|
CC_MAJ:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC__ | cut -f3 -d\ )
|
||||||
CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ )
|
CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ )
|
||||||
@@ -197,115 +170,103 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1100)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1101)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1101)
|
||||||
# Velleman K8400 Controller (derived from 3Drag Controller)
|
# Velleman K8400 Controller (derived from 3Drag Controller)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1102)
|
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
|
# 2PrintBeta BAM&DICE with STK drivers
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1105)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1103)
|
||||||
# 2PrintBeta BAM&DICE Due with STK drivers
|
# 2PrintBeta BAM&DICE Due with STK drivers
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1104)
|
||||||
# MKS BASE v1.0
|
# MKS BASE v1.0
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1105)
|
||||||
# MKS v1.4 with A4982 stepper drivers
|
# MKS v1.4 with A4982 stepper drivers
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
|
||||||
# MKS v1.5 with Allegro A4982 stepper drivers
|
# MKS v1.5 with Allegro A4982 stepper drivers
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
|
||||||
# MKS v1.6 with Allegro A4982 stepper drivers
|
# MKS v1.6 with Allegro A4982 stepper drivers
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
|
||||||
|
|
||||||
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
|
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
|
||||||
# MKS GEN v1.3 or 1.4
|
# MKS GEN v1.3 or 1.4
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
|
||||||
# MKS GEN L
|
# MKS GEN L
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
|
||||||
# zrib V2.0 control board (Chinese RAMPS replica)
|
# zrib V2.0 control board (Chinese knock off RAMPS replica)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
|
||||||
# BigTreeTech or BIQU KFB2.0
|
# BigTreeTech or BIQU KFB2.0
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
|
||||||
# Felix 2.0+ Electronics Board (RAMPS like)
|
# Felix 2.0+ Electronics Board (RAMPS like)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
|
||||||
# Invent-A-Part RigidBoard
|
# Invent-A-Part RigidBoard
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
|
||||||
# Invent-A-Part RigidBoard V2
|
# Invent-A-Part RigidBoard V2
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
|
||||||
# Sainsmart 2-in-1 board
|
# Sainsmart 2-in-1 board
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
|
||||||
# Ultimaker
|
# Ultimaker
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
|
||||||
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
|
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
|
||||||
MCU ?= atmega1280
|
MCU ?= atmega1280
|
||||||
PROG_MCU ?= m1280
|
|
||||||
|
|
||||||
# Azteeg X3
|
# Azteeg X3
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
|
||||||
# Azteeg X3 Pro
|
# Azteeg X3 Pro
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
|
||||||
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
|
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
|
||||||
# Rumba
|
# Rumba
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
|
||||||
# Raise3D Rumba
|
# Raise3D Rumba
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
|
||||||
# Rapide Lite RL200 Rumba
|
# Rapide Lite RL200 Rumba
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
|
||||||
# Formbot T-Rex 2 Plus
|
# Formbot T-Rex 2 Plus
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
|
||||||
# Formbot T-Rex 3
|
# Formbot T-Rex 3
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
|
||||||
# Formbot Raptor
|
# Formbot Raptor
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
|
||||||
# Formbot Raptor 2
|
# Formbot Raptor 2
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
|
||||||
# bq ZUM Mega 3D
|
# bq ZUM Mega 3D
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
|
||||||
# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
|
# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
|
||||||
# TriGorilla Anycubic version 1.3 based on RAMPS EFB
|
# TriGorilla Anycubic version 1.3 based on RAMPS EFB
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
|
||||||
# TriGorilla Anycubic version 1.4 based on RAMPS EFB
|
# TriGorilla Anycubic version 1.4 based on RAMPS EFB
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
|
||||||
# TriGorilla Anycubic version 1.4 Rev 1.1
|
# TriGorilla Anycubic version 1.4 Rev 1.1
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
|
||||||
# Creality: Ender-4, CR-8
|
# Creality: Ender-4, CR-8
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
|
||||||
# Creality: CR10S, CR20, CR-X
|
# Creality: CR10S, CR20, CR-X
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
|
||||||
# Dagoma F5
|
# Dagoma F5
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
|
||||||
# FYSETC F6 1.3
|
# FYSETC F6 1.3
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
|
||||||
# FYSETC F6 1.5
|
# FYSETC F6 1.5
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
|
||||||
# Duplicator i3 Plus
|
# Duplicator i3 Plus
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
|
||||||
# VORON
|
# VORON
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
|
||||||
# TRONXY V3 1.0
|
# TRONXY V3 1.0
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
|
||||||
# Z-Bolt X Series
|
# Z-Bolt X Series
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
|
||||||
# TT OSCAR
|
# TT OSCAR
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
|
||||||
# Overlord/Overlord Pro
|
# Overlord/Overlord Pro
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
|
||||||
# ADIMLab Gantry v1
|
# ADIMLab Gantry v1
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
|
||||||
# ADIMLab Gantry v2
|
# ADIMLab Gantry v2
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
|
||||||
# BIQU Tango V1
|
# BIQU Tango V1
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
|
||||||
# MKS GEN L V2
|
# MKS GEN L V2
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
|
||||||
# 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
|
||||||
@@ -323,8 +284,6 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1203)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
|
||||||
# abee Scoovo X9H
|
# abee Scoovo X9H
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
|
||||||
# Rambo ThinkerV2
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1206)
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Other ATmega1280, ATmega2560
|
# Other ATmega1280, ATmega2560
|
||||||
@@ -380,11 +339,9 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1320)
|
|||||||
# Minitronics v1.0/1.1
|
# Minitronics v1.0/1.1
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1400)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1400)
|
||||||
MCU ?= atmega1281
|
MCU ?= atmega1281
|
||||||
PROG_MCU ?= m1281
|
|
||||||
# Silvergate v1.0
|
# Silvergate v1.0
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1401)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1401)
|
||||||
MCU ?= atmega1281
|
MCU ?= atmega1281
|
||||||
PROG_MCU ?= m1281
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Sanguinololu and Derivatives - ATmega644P, ATmega1284P
|
# Sanguinololu and Derivatives - ATmega644P, ATmega1284P
|
||||||
@@ -394,57 +351,42 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1401)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1500)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1500)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Sanguinololu 1.2 and above
|
# Sanguinololu 1.2 and above
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1501)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1501)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Melzi
|
# Melzi
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1502)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1502)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
# Melzi with ATmega1284 (MaKr3d version)
|
||||||
# Melzi V2.0
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1503)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1503)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
# Melzi Creality3D board (for CR-10 etc)
|
||||||
# Melzi with ATmega1284 (MaKr3d version)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1504)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1504)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
# Melzi Malyan M150 board
|
||||||
# Melzi Creality3D board (for CR-10 etc)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1505)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1505)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
# Tronxy X5S
|
||||||
# Melzi Malyan M150 board
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1506)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1506)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
# STB V1.1
|
||||||
# Tronxy X5S
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1507)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1507)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
# Azteeg X1
|
||||||
# STB V1.1
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1508)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1508)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
# Anet 1.0 (Melzi clone)
|
||||||
# Azteeg X1
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1509)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1509)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
|
||||||
# Anet 1.0 (Melzi clone)
|
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1510)
|
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
|
||||||
MCU ?= atmega1284p
|
|
||||||
PROG_MCU ?= m1284p
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Other ATmega644P, ATmega644, ATmega1284P
|
# Other ATmega644P, ATmega644, ATmega1284P
|
||||||
@@ -454,61 +396,50 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1510)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1600)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1600)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Gen3+
|
# Gen3+
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1601)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1601)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Gen6
|
# Gen6
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1602)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1602)
|
||||||
HARDWARE_VARIANT ?= Gen6
|
HARDWARE_VARIANT ?= Gen6
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Gen6 deluxe
|
# Gen6 deluxe
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1603)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1603)
|
||||||
HARDWARE_VARIANT ?= Gen6
|
HARDWARE_VARIANT ?= Gen6
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Gen7 custom (Alfons3 Version)
|
# Gen7 custom (Alfons3 Version)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1604)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1604)
|
||||||
HARDWARE_VARIANT ?= Gen7
|
HARDWARE_VARIANT ?= Gen7
|
||||||
MCU ?= atmega644
|
MCU ?= atmega644
|
||||||
PROG_MCU ?= m644
|
|
||||||
F_CPU ?= 20000000
|
F_CPU ?= 20000000
|
||||||
# Gen7 v1.1, v1.2
|
# Gen7 v1.1, v1.2
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1605)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1605)
|
||||||
HARDWARE_VARIANT ?= Gen7
|
HARDWARE_VARIANT ?= Gen7
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
F_CPU ?= 20000000
|
F_CPU ?= 20000000
|
||||||
# Gen7 v1.3
|
# Gen7 v1.3
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1606)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1606)
|
||||||
HARDWARE_VARIANT ?= Gen7
|
HARDWARE_VARIANT ?= Gen7
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
F_CPU ?= 20000000
|
F_CPU ?= 20000000
|
||||||
# Gen7 v1.4
|
# Gen7 v1.4
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1607)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1607)
|
||||||
HARDWARE_VARIANT ?= Gen7
|
HARDWARE_VARIANT ?= Gen7
|
||||||
MCU ?= atmega1284p
|
MCU ?= atmega1284p
|
||||||
PROG_MCU ?= m1284p
|
|
||||||
F_CPU ?= 20000000
|
F_CPU ?= 20000000
|
||||||
# Alpha OMCA board
|
# Alpha OMCA board
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1608)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1608)
|
||||||
HARDWARE_VARIANT ?= SanguinoA
|
HARDWARE_VARIANT ?= SanguinoA
|
||||||
MCU ?= atmega644
|
MCU ?= atmega644
|
||||||
PROG_MCU ?= m644
|
|
||||||
# Final OMCA board
|
# Final OMCA board
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1609)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1609)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
# Sethi 3D_1
|
# Sethi 3D_1
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1610)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1610)
|
||||||
HARDWARE_VARIANT ?= Sanguino
|
HARDWARE_VARIANT ?= Sanguino
|
||||||
MCU ?= atmega644p
|
MCU ?= atmega644p
|
||||||
PROG_MCU ?= m644p
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Teensyduino - AT90USB1286, AT90USB1286P
|
# Teensyduino - AT90USB1286, AT90USB1286P
|
||||||
@@ -518,60 +449,51 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1610)
|
|||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1700)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1700)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
# Printrboard (AT90USB1286)
|
# Printrboard (AT90USB1286)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1701)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1701)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
# Printrboard Revision F (AT90USB1286)
|
# Printrboard Revision F (AT90USB1286)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1702)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1702)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
# Brainwave (AT90USB646)
|
# Brainwave (AT90USB646)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1703)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1703)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb646
|
MCU ?= at90usb646
|
||||||
PROG_MCU ?= usb646
|
|
||||||
# Brainwave Pro (AT90USB1286)
|
# Brainwave Pro (AT90USB1286)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1704)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1704)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
# SAV Mk-I (AT90USB1286)
|
# SAV Mk-I (AT90USB1286)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1705)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1705)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
# Teensy++2.0 (AT90USB1286)
|
# Teensy++2.0 (AT90USB1286)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1706)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1706)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
# 5DPrint D8 Driver Board
|
# 5DPrint D8 Driver Board
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),1707)
|
else ifeq ($(HARDWARE_MOTHERBOARD),1707)
|
||||||
HARDWARE_VARIANT ?= Teensy
|
HARDWARE_VARIANT ?= Teensy
|
||||||
MCU ?= at90usb1286
|
MCU ?= at90usb1286
|
||||||
PROG_MCU ?= usb1286
|
|
||||||
|
|
||||||
# UltiMachine Archim1 (with DRV8825 drivers)
|
# UltiMachine Archim1 (with DRV8825 drivers)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),3023)
|
else ifeq ($(HARDWARE_MOTHERBOARD),3023)
|
||||||
HARDWARE_VARIANT ?= archim
|
HARDWARE_VARIANT ?= archim
|
||||||
MCPU = cortex-m3
|
MCPU = cortex-m3
|
||||||
F_CPU = 84000000
|
F_CPU = 84000000L
|
||||||
IS_MCU = 0
|
IS_MCU = 0
|
||||||
# UltiMachine Archim2 (with TMC2130 drivers)
|
# UltiMachine Archim2 (with TMC2130 drivers)
|
||||||
else ifeq ($(HARDWARE_MOTHERBOARD),3024)
|
else ifeq ($(HARDWARE_MOTHERBOARD),3024)
|
||||||
HARDWARE_VARIANT ?= archim
|
HARDWARE_VARIANT ?= archim
|
||||||
MCPU = cortex-m3
|
MCPU = cortex-m3
|
||||||
F_CPU = 84000000
|
F_CPU = 84000000L
|
||||||
IS_MCU = 0
|
IS_MCU = 0
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
|
# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
|
||||||
# if you are setting this to something other than 16MHz
|
# if you are setting this to something other than 16MHz
|
||||||
# Do not put the UL suffix, it's done later on.
|
|
||||||
# Set to 16Mhz if not yet set.
|
# Set to 16Mhz if not yet set.
|
||||||
F_CPU ?= 16000000
|
F_CPU ?= 16000000
|
||||||
|
|
||||||
@@ -581,8 +503,7 @@ IS_MCU ?= 1
|
|||||||
ifeq ($(IS_MCU),1)
|
ifeq ($(IS_MCU),1)
|
||||||
# Set to arduino, ATmega2560 if not yet set.
|
# Set to arduino, ATmega2560 if not yet set.
|
||||||
HARDWARE_VARIANT ?= arduino
|
HARDWARE_VARIANT ?= arduino
|
||||||
MCU ?= atmega2560
|
MCU ?= atmega2560
|
||||||
PROG_MCU ?= m2560
|
|
||||||
|
|
||||||
TOOL_PREFIX = avr
|
TOOL_PREFIX = avr
|
||||||
MCU_FLAGS = -mmcu=$(MCU)
|
MCU_FLAGS = -mmcu=$(MCU)
|
||||||
@@ -613,36 +534,27 @@ VPATH += $(BUILD_DIR)
|
|||||||
VPATH += $(HARDWARE_SRC)
|
VPATH += $(HARDWARE_SRC)
|
||||||
|
|
||||||
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino))
|
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino))
|
||||||
# Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8)
|
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/LiquidCrystal/src
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
|
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/libraries/SPI
|
||||||
# New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
|
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(IS_MCU),1)
|
ifeq ($(IS_MCU),1)
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
|
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
|
||||||
|
|
||||||
# Old libraries (avr-core 1.6.21 < / Arduino < 1.6.8)
|
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
|
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial
|
|
||||||
# New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
|
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
|
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src
|
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src
|
||||||
endif
|
endif
|
||||||
|
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
|
||||||
|
|
||||||
ifeq ($(LIQUID_TWI2), 1)
|
ifeq ($(LIQUID_TWI2), 1)
|
||||||
WIRE = 1
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
|
||||||
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidTWI2
|
||||||
endif
|
endif
|
||||||
ifeq ($(WIRE), 1)
|
ifeq ($(WIRE), 1)
|
||||||
# Old libraries (avr-core 1.6.21 / Arduino < 1.6.8)
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/utility
|
|
||||||
# New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
|
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src
|
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src/utility
|
|
||||||
endif
|
endif
|
||||||
ifeq ($(NEOPIXEL), 1)
|
ifeq ($(NEOPIXEL), 1)
|
||||||
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
|
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
|
||||||
@@ -714,23 +626,13 @@ ifeq ($(WIRE), 1)
|
|||||||
LIB_CXXSRC += Wire.cpp
|
LIB_CXXSRC += Wire.cpp
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(TONE), 1)
|
|
||||||
LIB_CXXSRC += Tone.cpp
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(U8GLIB), 1)
|
ifeq ($(U8GLIB), 1)
|
||||||
LIB_CXXSRC += U8glib.cpp
|
LIB_CXXSRC += U8glib.cpp
|
||||||
LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c \
|
LIB_SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c
|
||||||
u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c \
|
|
||||||
u8g_font_6x13.c u8g_font_04b_03.c u8g_font_5x8.c
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(TMC), 1)
|
ifeq ($(TMC), 1)
|
||||||
LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp \
|
LIB_CXXSRC += TMCStepper.cpp COOLCONF.cpp DRV_STATUS.cpp IHOLD_IRUN.cpp CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp
|
||||||
CHOPCONF.cpp GCONF.cpp PWMCONF.cpp DRV_CONF.cpp DRVCONF.cpp DRVCTRL.cpp \
|
|
||||||
DRVSTATUS.cpp ENCMODE.cpp RAMP_STAT.cpp SGCSCONF.cpp SHORT_CONF.cpp \
|
|
||||||
SMARTEN.cpp SW_MODE.cpp SW_SPI.cpp TMC2130Stepper.cpp TMC2208Stepper.cpp \
|
|
||||||
TMC2209Stepper.cpp TMC2660Stepper.cpp TMC5130Stepper.cpp TMC5160Stepper.cpp
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(RELOC_WORKAROUND), 1)
|
ifeq ($(RELOC_WORKAROUND), 1)
|
||||||
@@ -772,23 +674,17 @@ REMOVE = rm -f
|
|||||||
MV = mv -f
|
MV = mv -f
|
||||||
|
|
||||||
# Place -D or -U options here
|
# Place -D or -U options here
|
||||||
CDEFS = -DF_CPU=$(F_CPU)UL ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION)
|
CDEFS = -DF_CPU=$(F_CPU) ${addprefix -D , $(DEFINES)} -DARDUINO=$(ARDUINO_VERSION)
|
||||||
CXXDEFS = $(CDEFS)
|
CXXDEFS = $(CDEFS)
|
||||||
|
|
||||||
ifeq ($(HARDWARE_VARIANT), Teensy)
|
ifeq ($(HARDWARE_VARIANT), Teensy)
|
||||||
CDEFS += -DUSB_SERIAL
|
CDEFS += -DUSB_SERIAL
|
||||||
LIB_SRC += usb.c pins_teensy.c
|
LIB_SRC += usb.c pins_teensy.c
|
||||||
LIB_CXXSRC += usb_api.cpp
|
LIB_CXXSRC += usb_api.cpp
|
||||||
|
|
||||||
else ifeq ($(HARDWARE_VARIANT), archim)
|
else ifeq ($(HARDWARE_VARIANT), archim)
|
||||||
CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__
|
CDEFS += -DARDUINO_SAM_ARCHIM -DARDUINO_ARCH_SAM -D__SAM3X8E__ -DUSB_VID=0x27b1 -DUSB_PID=0x0001 -DUSBCON '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT="Archim"'
|
||||||
CDEFS += -DUSB_VID=0x27B1 -DUSB_PID=0x0001 -DUSBCON
|
LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp PluggableUSB.cpp USBCore.cpp
|
||||||
CDEFS += '-DUSB_MANUFACTURER="UltiMachine"' '-DUSB_PRODUCT_STRING="Archim"'
|
|
||||||
|
|
||||||
LIB_CXXSRC += variant.cpp IPAddress.cpp Reset.cpp RingBuffer.cpp Stream.cpp \
|
|
||||||
UARTClass.cpp USARTClass.cpp abi.cpp new.cpp watchdog.cpp CDC.cpp \
|
|
||||||
PluggableUSB.cpp USBCore.cpp
|
|
||||||
|
|
||||||
LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c
|
LIB_SRC += cortex_handlers.c iar_calls_sam3.c syscalls_sam3.c dtostrf.c itoa.c
|
||||||
|
|
||||||
ifeq ($(U8GLIB), 1)
|
ifeq ($(U8GLIB), 1)
|
||||||
@@ -814,20 +710,16 @@ CTUNING = -fsigned-char -funsigned-bitfields -fno-exceptions \
|
|||||||
ifneq ($(HARDWARE_MOTHERBOARD),)
|
ifneq ($(HARDWARE_MOTHERBOARD),)
|
||||||
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
|
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
|
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
|
||||||
CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti
|
CXXEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics -fno-rtti
|
||||||
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) $(CTUNING) $(CSTANDARD)
|
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CEXTRA) $(CTUNING) $(CSTANDARD)
|
||||||
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD)
|
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) $(CXXEXTRA) $(CTUNING) $(CXXSTANDARD)
|
||||||
ASFLAGS := $(CDEFS)
|
ASFLAGS := $(CDEFS)
|
||||||
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
|
||||||
|
|
||||||
ifeq ($(HARDWARE_VARIANT), archim)
|
ifeq ($(HARDWARE_VARIANT), archim)
|
||||||
LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align
|
LD_PREFIX = -Wl,--gc-sections,-Map,Marlin.ino.map,--cref,--check-sections,--entry=Reset_Handler,--unresolved-symbols=report-all,--warn-common,--warn-section-align
|
||||||
LD_SUFFIX = $(LDLIBS)
|
LD_SUFFIX = $(LDLIBS)
|
||||||
|
LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
|
||||||
LDFLAGS = -lm -T$(LDSCRIPT) -u _sbrk -u link -u _close -u _fstat -u _isatty
|
|
||||||
LDFLAGS += -u _lseek -u _read -u _write -u _exit -u kill -u _getpid
|
|
||||||
else
|
else
|
||||||
LD_PREFIX = -Wl,--gc-sections,--relax
|
LD_PREFIX = -Wl,--gc-sections,--relax
|
||||||
LDFLAGS = -lm
|
LDFLAGS = -lm
|
||||||
@@ -843,7 +735,7 @@ else
|
|||||||
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
|
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
|
||||||
endif
|
endif
|
||||||
AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
|
AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
|
||||||
-p$(PROG_MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
|
-p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \
|
||||||
-b$(UPLOAD_RATE)
|
-b$(UPLOAD_RATE)
|
||||||
|
|
||||||
# Since Marlin 2.0, the source files may be distributed into several
|
# Since Marlin 2.0, the source files may be distributed into several
|
||||||
@@ -944,7 +836,7 @@ extcoff: $(TARGET).elf
|
|||||||
|
|
||||||
.elf.eep:
|
.elf.eep:
|
||||||
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
|
||||||
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
--change-section-lma .eeprom=0 -O $(FORMAT) $< $@
|
||||||
|
|
||||||
# Create extended listing file from ELF output file.
|
# Create extended listing file from ELF output file.
|
||||||
.elf.lss:
|
.elf.lss:
|
||||||
@@ -958,7 +850,7 @@ extcoff: $(TARGET).elf
|
|||||||
|
|
||||||
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
|
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
|
||||||
$(Pecho) " CXX $@"
|
$(Pecho) " CXX $@"
|
||||||
$P $(CXX) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
|
$P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
|
||||||
|
|
||||||
# Object files that were found in "src" will be stored in $(BUILD_DIR)
|
# Object files that were found in "src" will be stored in $(BUILD_DIR)
|
||||||
# in directories that mirror the structure of "src"
|
# in directories that mirror the structure of "src"
|
||||||
@@ -993,5 +885,5 @@ clean:
|
|||||||
|
|
||||||
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
|
.PHONY: all build elf hex eep lss sym program coff extcoff clean depend sizebefore sizeafter
|
||||||
|
|
||||||
# Automatically include the dependency files created by gcc
|
# Automaticaly include the dependency files created by gcc
|
||||||
-include ${patsubst %.o, %.d, ${OBJ}}
|
-include ${patsubst %.o, %.d, ${OBJ}}
|
||||||
|
@@ -1,8 +1,9 @@
|
|||||||
/*==============================================================================
|
/*
|
||||||
|
================================================================================
|
||||||
|
|
||||||
Marlin Firmware
|
Marlin Firmware
|
||||||
|
|
||||||
(c) 2011-2020 MarlinFirmware
|
(c) 2011-2019 MarlinFirmware
|
||||||
Portions of Marlin are (c) by their respective authors.
|
Portions of Marlin are (c) by their respective authors.
|
||||||
All code complies with GPLv2 and/or GPLv3
|
All code complies with GPLv2 and/or GPLv3
|
||||||
|
|
||||||
@@ -11,33 +12,30 @@
|
|||||||
Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware.
|
Greetings! Thank you for choosing Marlin 2 as your 3D printer firmware.
|
||||||
|
|
||||||
To configure Marlin you must edit Configuration.h and Configuration_adv.h
|
To configure Marlin you must edit Configuration.h and Configuration_adv.h
|
||||||
located in the root 'Marlin' folder. Check our Configurations repository to
|
located in the root 'Marlin' folder. Check the config/examples folder to see if
|
||||||
see if there's a more suitable starting-point for your specific hardware.
|
there's a more suitable starting-point for your specific hardware.
|
||||||
|
|
||||||
Before diving in, we recommend the following essential links:
|
Before diving in, we recommend the following essential links:
|
||||||
|
|
||||||
Marlin Firmware Official Website
|
Marlin Firmware Official Website
|
||||||
|
|
||||||
- https://marlinfw.org/
|
- http://marlinfw.org/
|
||||||
The official Marlin Firmware website contains the most up-to-date
|
The official Marlin Firmware website contains the most up-to-date
|
||||||
documentation. Contributions are always welcome!
|
documentation. Contributions are always welcome!
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
|
|
||||||
- https://github.com/MarlinFirmware/Configurations
|
|
||||||
Example configurations for several printer models.
|
|
||||||
|
|
||||||
- https://www.youtube.com/watch?v=3gwWVFtdg-4
|
- https://www.youtube.com/watch?v=3gwWVFtdg-4
|
||||||
A good 20-minute overview of Marlin configuration by Tom Sanladerer.
|
A good 20-minute overview of Marlin configuration by Tom Sanladerer.
|
||||||
(Applies to Marlin 1.0.x, so Jerk and Acceleration should be halved.)
|
(Applies to Marlin 1.0.x, so Jerk and Acceleration should be halved.)
|
||||||
Also... https://www.google.com/search?tbs=vid%3A1&q=configure+marlin
|
Also... https://www.google.com/search?tbs=vid%3A1&q=configure+marlin
|
||||||
|
|
||||||
- https://marlinfw.org/docs/configuration/configuration.html
|
- http://marlinfw.org/docs/configuration/configuration.html
|
||||||
Marlin's configuration options are explained in more detail here.
|
Marlin's configuration options are explained in more detail here.
|
||||||
|
|
||||||
Getting Help
|
Getting Help
|
||||||
|
|
||||||
- https://reprap.org/forum/list.php?415
|
- http://forums.reprap.org/list.php?415
|
||||||
The Marlin Discussion Forum is a great place to get help from other Marlin
|
The Marlin Discussion Forum is a great place to get help from other Marlin
|
||||||
users who may have experienced similar issues to your own.
|
users who may have experienced similar issues to your own.
|
||||||
|
|
||||||
@@ -47,11 +45,9 @@ Getting Help
|
|||||||
|
|
||||||
Contributing
|
Contributing
|
||||||
|
|
||||||
- https://marlinfw.org/docs/development/contributing.html
|
- http://marlinfw.org/docs/development/contributing.html
|
||||||
If you'd like to contribute to Marlin, read this first!
|
If you'd like to contribute to Marlin, read this first!
|
||||||
|
|
||||||
- https://marlinfw.org/docs/development/coding_standards.html
|
- http://marlinfw.org/docs/development/coding_standards.html
|
||||||
Before submitting code get to know the Coding Standards.
|
Before submitting code get to know the Coding Standards.
|
||||||
|
*/
|
||||||
|
|
||||||
------------------------------------------------------------------------------*/
|
|
||||||
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -28,20 +28,20 @@
|
|||||||
/**
|
/**
|
||||||
* Marlin release version identifier
|
* Marlin release version identifier
|
||||||
*/
|
*/
|
||||||
//#define SHORT_BUILD_VERSION "2.0.9.2"
|
//#define SHORT_BUILD_VERSION "2.0.4.5"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verbose version identifier which should contain a reference to the location
|
* Verbose version identifier which should contain a reference to the location
|
||||||
* from where the binary was downloaded or the source code was compiled.
|
* from where the binary was downloaded or the source code was compiled.
|
||||||
*/
|
*/
|
||||||
//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION
|
//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " (Github)"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
|
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
|
||||||
* 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 "2021-09-03"
|
//#define STRING_DISTRIBUTION_DATE "2023-07-19"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
@@ -54,7 +54,7 @@
|
|||||||
* has a distinct Github fork— the Source Code URL should just be the main
|
* has a distinct Github fork— the Source Code URL should just be the main
|
||||||
* Marlin repository.
|
* Marlin repository.
|
||||||
*/
|
*/
|
||||||
//#define SOURCE_CODE_URL "github.com/MarlinFirmware/Marlin"
|
//#define SOURCE_CODE_URL "https://github.com/MarlinFirmware/Marlin"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default generic printer UUID.
|
* Default generic printer UUID.
|
||||||
@@ -65,12 +65,12 @@
|
|||||||
* The WEBSITE_URL is the location where users can get more information such as
|
* The WEBSITE_URL is the location where users can get more information such as
|
||||||
* documentation about a specific Marlin release.
|
* documentation about a specific Marlin release.
|
||||||
*/
|
*/
|
||||||
//#define WEBSITE_URL "marlinfw.org"
|
//#define WEBSITE_URL "http://marlinfw.org"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the vendor info the serial USB interface, if changable
|
* Set the vendor info the serial USB interface, if changable
|
||||||
* Currently only supported by DUE platform
|
* Currently only supported by DUE platform
|
||||||
*/
|
*/
|
||||||
//#define USB_DEVICE_VENDOR_ID 0x0000
|
//#define USB_DEVICE_VENDOR_ID 0x0000
|
||||||
//#define USB_DEVICE_PRODUCT_ID 0x0000
|
//#define USB_DEVICE_PRODUCT_ID 0x0000
|
||||||
//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL
|
//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL
|
||||||
|
@@ -33,4 +33,4 @@ PlatformIO will find your libraries automatically, configure preprocessor's
|
|||||||
include paths and build them.
|
include paths and build them.
|
||||||
|
|
||||||
More information about PlatformIO Library Dependency Finder
|
More information about PlatformIO Library Dependency Finder
|
||||||
- https://docs.platformio.org/page/librarymanager/ldf.html
|
- http://docs.platformio.org/page/librarymanager/ldf.html
|
||||||
|
@@ -1,230 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "../shared/Marduino.h"
|
|
||||||
#include "../shared/HAL_SPI.h"
|
|
||||||
#include "fastio.h"
|
|
||||||
#include "watchdog.h"
|
|
||||||
#include "math.h"
|
|
||||||
|
|
||||||
#ifdef USBCON
|
|
||||||
#include <HardwareSerial.h>
|
|
||||||
#else
|
|
||||||
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
|
|
||||||
#include "MarlinSerial.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <util/delay.h>
|
|
||||||
#include <avr/eeprom.h>
|
|
||||||
#include <avr/pgmspace.h>
|
|
||||||
#include <avr/interrupt.h>
|
|
||||||
#include <avr/io.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// Default graphical display delays
|
|
||||||
//
|
|
||||||
#if F_CPU >= 20000000
|
|
||||||
#define CPU_ST7920_DELAY_1 150
|
|
||||||
#define CPU_ST7920_DELAY_2 0
|
|
||||||
#define CPU_ST7920_DELAY_3 150
|
|
||||||
#elif F_CPU == 16000000
|
|
||||||
#define CPU_ST7920_DELAY_1 125
|
|
||||||
#define CPU_ST7920_DELAY_2 0
|
|
||||||
#define CPU_ST7920_DELAY_3 188
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef pgm_read_ptr
|
|
||||||
// Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for
|
|
||||||
// Windows Subsystem for Linux on Windows 10 as of 10/18/2019
|
|
||||||
#define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
|
|
||||||
#define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short))
|
|
||||||
#define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------
|
|
||||||
// Defines
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
// AVR PROGMEM extension for sprintf_P
|
|
||||||
#define S_FMT "%S"
|
|
||||||
|
|
||||||
// AVR PROGMEM extension for string define
|
|
||||||
#define PGMSTR(NAM,STR) const char NAM[] PROGMEM = STR
|
|
||||||
|
|
||||||
#ifndef CRITICAL_SECTION_START
|
|
||||||
#define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli()
|
|
||||||
#define CRITICAL_SECTION_END() SREG = _sreg
|
|
||||||
#endif
|
|
||||||
#define ISRS_ENABLED() TEST(SREG, SREG_I)
|
|
||||||
#define ENABLE_ISRS() sei()
|
|
||||||
#define DISABLE_ISRS() cli()
|
|
||||||
|
|
||||||
// ------------------------
|
|
||||||
// Types
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
typedef int8_t pin_t;
|
|
||||||
|
|
||||||
#define SHARED_SERVOS HAS_SERVOS
|
|
||||||
#define HAL_SERVO_LIB Servo
|
|
||||||
|
|
||||||
// ------------------------
|
|
||||||
// Public Variables
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
//extern uint8_t MCUSR;
|
|
||||||
|
|
||||||
// Serial ports
|
|
||||||
#ifdef USBCON
|
|
||||||
#include "../../core/serial_hook.h"
|
|
||||||
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
|
|
||||||
extern DefaultSerial1 MSerial0;
|
|
||||||
#ifdef BLUETOOTH
|
|
||||||
typedef ForwardSerial1Class< decltype(bluetoothSerial) > BTSerial;
|
|
||||||
extern BTSerial btSerial;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
|
|
||||||
#else
|
|
||||||
#if !WITHIN(SERIAL_PORT, -1, 3)
|
|
||||||
#error "SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
|
|
||||||
#endif
|
|
||||||
#define MYSERIAL1 customizedSerial1
|
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_2
|
|
||||||
#if !WITHIN(SERIAL_PORT_2, -1, 3)
|
|
||||||
#error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial."
|
|
||||||
#endif
|
|
||||||
#define MYSERIAL2 customizedSerial2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_3
|
|
||||||
#if !WITHIN(SERIAL_PORT_3, -1, 3)
|
|
||||||
#error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
|
|
||||||
#endif
|
|
||||||
#define MYSERIAL3 customizedSerial3
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MMU2_SERIAL_PORT
|
|
||||||
#if !WITHIN(MMU2_SERIAL_PORT, -1, 3)
|
|
||||||
#error "MMU2_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
|
|
||||||
#endif
|
|
||||||
#define MMU2_SERIAL mmuSerial
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LCD_SERIAL_PORT
|
|
||||||
#if !WITHIN(LCD_SERIAL_PORT, -1, 3)
|
|
||||||
#error "LCD_SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
|
|
||||||
#endif
|
|
||||||
#define LCD_SERIAL lcdSerial
|
|
||||||
#if HAS_DGUS_LCD
|
|
||||||
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free()
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------
|
|
||||||
// Public functions
|
|
||||||
// ------------------------
|
|
||||||
|
|
||||||
void HAL_init();
|
|
||||||
|
|
||||||
//void cli();
|
|
||||||
|
|
||||||
//void _delay_ms(const int delay);
|
|
||||||
|
|
||||||
inline void HAL_clear_reset_source() { MCUSR = 0; }
|
|
||||||
inline uint8_t HAL_get_reset_source() { return MCUSR; }
|
|
||||||
|
|
||||||
void HAL_reboot();
|
|
||||||
|
|
||||||
#if GCC_VERSION <= 50000
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern "C" int freeMemory();
|
|
||||||
|
|
||||||
#if GCC_VERSION <= 50000
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ADC
|
|
||||||
#ifdef DIDR2
|
|
||||||
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
|
|
||||||
#else
|
|
||||||
#define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void HAL_adc_init() {
|
|
||||||
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
|
|
||||||
DIDR0 = 0;
|
|
||||||
#ifdef DIDR2
|
|
||||||
DIDR2 = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC)
|
|
||||||
#ifdef MUX5
|
|
||||||
#define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
|
|
||||||
#else
|
|
||||||
#define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define HAL_ADC_VREF 5.0
|
|
||||||
#define HAL_ADC_RESOLUTION 10
|
|
||||||
#define HAL_READ_ADC() ADC
|
|
||||||
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
|
|
||||||
|
|
||||||
#define GET_PIN_MAP_PIN(index) index
|
|
||||||
#define GET_PIN_MAP_INDEX(pin) pin
|
|
||||||
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
|
||||||
|
|
||||||
#define HAL_SENSITIVE_PINS 0, 1,
|
|
||||||
|
|
||||||
#ifdef __AVR_AT90USB1286__
|
|
||||||
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// AVR compatibility
|
|
||||||
#define strtof strtod
|
|
||||||
|
|
||||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set_pwm_frequency
|
|
||||||
* Sets the frequency of the timer corresponding to the provided pin
|
|
||||||
* as close as possible to the provided desired frequency. Internally
|
|
||||||
* calculates the required waveform generation mode, prescaler and
|
|
||||||
* resolution values required and sets the timer registers accordingly.
|
|
||||||
* NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
|
|
||||||
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
|
|
||||||
*/
|
|
||||||
void set_pwm_frequency(const pin_t pin, int f_desired);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* set_pwm_duty
|
|
||||||
* Sets the PWM duty cycle of the provided pin to the provided value
|
|
||||||
* Optionally allows inverting the duty cycle [default = false]
|
|
||||||
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
|
||||||
*/
|
|
||||||
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
|
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
using MarlinSPI = SPIClass;
|
|
@@ -1,652 +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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MarlinSerial.cpp - Hardware serial library for Wiring
|
|
||||||
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
|
||||||
*
|
|
||||||
* Modified 23 November 2006 by David A. Mellis
|
|
||||||
* Modified 28 September 2010 by Mark Sproul
|
|
||||||
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
|
|
||||||
* Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
|
|
||||||
* Modified 10 June 2018 by Eduardo José Tagle (See #10991)
|
|
||||||
* Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __AVR__
|
|
||||||
|
|
||||||
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
|
||||||
|
|
||||||
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
|
|
||||||
|
|
||||||
#include "MarlinSerial.h"
|
|
||||||
#include "../../MarlinCore.h"
|
|
||||||
|
|
||||||
#if ENABLED(DIRECT_STEPPING)
|
|
||||||
#include "../../feature/direct_stepping.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_r MarlinSerial<Cfg>::rx_buffer = { 0, 0, { 0 } };
|
|
||||||
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_t MarlinSerial<Cfg>::tx_buffer = { 0 };
|
|
||||||
template<typename Cfg> bool MarlinSerial<Cfg>::_written = false;
|
|
||||||
template<typename Cfg> uint8_t MarlinSerial<Cfg>::xon_xoff_state = MarlinSerial<Cfg>::XON_XOFF_CHAR_SENT | MarlinSerial<Cfg>::XON_CHAR;
|
|
||||||
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_dropped_bytes = 0;
|
|
||||||
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_buffer_overruns = 0;
|
|
||||||
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_framing_errors = 0;
|
|
||||||
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::rx_max_enqueued = 0;
|
|
||||||
|
|
||||||
// A SW memory barrier, to ensure GCC does not overoptimize loops
|
|
||||||
#define sw_barrier() asm volatile("": : :"memory");
|
|
||||||
|
|
||||||
#include "../../feature/e_parser.h"
|
|
||||||
|
|
||||||
// "Atomically" read the RX head index value without disabling interrupts:
|
|
||||||
// This MUST be called with RX interrupts enabled, and CAN'T be called
|
|
||||||
// from the RX ISR itself!
|
|
||||||
template<typename Cfg>
|
|
||||||
FORCE_INLINE typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::atomic_read_rx_head() {
|
|
||||||
if (Cfg::RX_SIZE > 256) {
|
|
||||||
// Keep reading until 2 consecutive reads return the same value,
|
|
||||||
// meaning there was no update in-between caused by an interrupt.
|
|
||||||
// This works because serial RX interrupts happen at a slower rate
|
|
||||||
// than successive reads of a variable, so 2 consecutive reads with
|
|
||||||
// the same value means no interrupt updated it.
|
|
||||||
ring_buffer_pos_t vold, vnew = rx_buffer.head;
|
|
||||||
sw_barrier();
|
|
||||||
do {
|
|
||||||
vold = vnew;
|
|
||||||
vnew = rx_buffer.head;
|
|
||||||
sw_barrier();
|
|
||||||
} while (vold != vnew);
|
|
||||||
return vnew;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// With an 8bit index, reads are always atomic. No need for special handling
|
|
||||||
return rx_buffer.head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
volatile bool MarlinSerial<Cfg>::rx_tail_value_not_stable = false;
|
|
||||||
template<typename Cfg>
|
|
||||||
volatile uint16_t MarlinSerial<Cfg>::rx_tail_value_backup = 0;
|
|
||||||
|
|
||||||
// Set RX tail index, taking into account the RX ISR could interrupt
|
|
||||||
// the write to this variable in the middle - So a backup strategy
|
|
||||||
// is used to ensure reads of the correct values.
|
|
||||||
// -Must NOT be called from the RX ISR -
|
|
||||||
template<typename Cfg>
|
|
||||||
FORCE_INLINE void MarlinSerial<Cfg>::atomic_set_rx_tail(typename MarlinSerial<Cfg>::ring_buffer_pos_t value) {
|
|
||||||
if (Cfg::RX_SIZE > 256) {
|
|
||||||
// Store the new value in the backup
|
|
||||||
rx_tail_value_backup = value;
|
|
||||||
sw_barrier();
|
|
||||||
// Flag we are about to change the true value
|
|
||||||
rx_tail_value_not_stable = true;
|
|
||||||
sw_barrier();
|
|
||||||
// Store the new value
|
|
||||||
rx_buffer.tail = value;
|
|
||||||
sw_barrier();
|
|
||||||
// Signal the new value is completely stored into the value
|
|
||||||
rx_tail_value_not_stable = false;
|
|
||||||
sw_barrier();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
rx_buffer.tail = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the RX tail index, taking into account the read could be
|
|
||||||
// interrupting in the middle of the update of that index value
|
|
||||||
// -Called from the RX ISR -
|
|
||||||
template<typename Cfg>
|
|
||||||
FORCE_INLINE typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::atomic_read_rx_tail() {
|
|
||||||
if (Cfg::RX_SIZE > 256) {
|
|
||||||
// If the true index is being modified, return the backup value
|
|
||||||
if (rx_tail_value_not_stable) return rx_tail_value_backup;
|
|
||||||
}
|
|
||||||
// The true index is stable, return it
|
|
||||||
return rx_buffer.tail;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (called with RX interrupts disabled)
|
|
||||||
template<typename Cfg>
|
|
||||||
FORCE_INLINE void MarlinSerial<Cfg>::store_rxd_char() {
|
|
||||||
|
|
||||||
static EmergencyParser::State emergency_state; // = EP_RESET
|
|
||||||
|
|
||||||
// This must read the R_UCSRA register before reading the received byte to detect error causes
|
|
||||||
if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes;
|
|
||||||
if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns;
|
|
||||||
if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors;
|
|
||||||
|
|
||||||
// Read the character from the USART
|
|
||||||
uint8_t c = R_UDR;
|
|
||||||
|
|
||||||
#if ENABLED(DIRECT_STEPPING)
|
|
||||||
if (page_manager.maybe_store_rxd_char(c)) return;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Get the tail - Nothing can alter its value while this ISR is executing, but there's
|
|
||||||
// a chance that this ISR interrupted the main process while it was updating the index.
|
|
||||||
// The backup mechanism ensures the correct value is always returned.
|
|
||||||
const ring_buffer_pos_t t = atomic_read_rx_tail();
|
|
||||||
|
|
||||||
// Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here
|
|
||||||
ring_buffer_pos_t h = rx_buffer.head;
|
|
||||||
|
|
||||||
// Get the next element
|
|
||||||
ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
|
||||||
|
|
||||||
if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
|
|
||||||
|
|
||||||
// If the character is to be stored at the index just before the tail
|
|
||||||
// (such that the head would advance to the current tail), the RX FIFO is
|
|
||||||
// full, so don't write the character or advance the head.
|
|
||||||
if (i != t) {
|
|
||||||
rx_buffer.buffer[h] = c;
|
|
||||||
h = i;
|
|
||||||
}
|
|
||||||
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
|
|
||||||
--rx_dropped_bytes;
|
|
||||||
|
|
||||||
if (Cfg::MAX_RX_QUEUED) {
|
|
||||||
// Calculate count of bytes stored into the RX buffer
|
|
||||||
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
|
||||||
|
|
||||||
// Keep track of the maximum count of enqueued bytes
|
|
||||||
NOLESS(rx_max_enqueued, rx_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Cfg::XONOFF) {
|
|
||||||
// If the last char that was sent was an XON
|
|
||||||
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
|
|
||||||
|
|
||||||
// Bytes stored into the RX buffer
|
|
||||||
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
|
||||||
|
|
||||||
// If over 12.5% of RX buffer capacity, send XOFF before running out of
|
|
||||||
// RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react
|
|
||||||
// and stop sending bytes. This translates to 13mS propagation time.
|
|
||||||
if (rx_count >= (Cfg::RX_SIZE) / 8) {
|
|
||||||
|
|
||||||
// At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted.
|
|
||||||
// Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens
|
|
||||||
// to be in the middle of trying to disable the RX interrupt in the main program, eventually the
|
|
||||||
// enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure
|
|
||||||
// the sending of the XOFF char is to send it HERE AND NOW.
|
|
||||||
|
|
||||||
// About to send the XOFF char
|
|
||||||
xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
|
|
||||||
|
|
||||||
// Wait until the TX register becomes empty and send it - Here there could be a problem
|
|
||||||
// - While waiting for the TX register to empty, the RX register could receive a new
|
|
||||||
// character. This must also handle that situation!
|
|
||||||
while (!B_UDRE) {
|
|
||||||
|
|
||||||
if (B_RXC) {
|
|
||||||
// A char arrived while waiting for the TX buffer to be empty - Receive and process it!
|
|
||||||
|
|
||||||
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
|
||||||
|
|
||||||
// Read the character from the USART
|
|
||||||
c = R_UDR;
|
|
||||||
|
|
||||||
if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
|
|
||||||
|
|
||||||
// If the character is to be stored at the index just before the tail
|
|
||||||
// (such that the head would advance to the current tail), the FIFO is
|
|
||||||
// full, so don't write the character or advance the head.
|
|
||||||
if (i != t) {
|
|
||||||
rx_buffer.buffer[h] = c;
|
|
||||||
h = i;
|
|
||||||
}
|
|
||||||
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
|
|
||||||
--rx_dropped_bytes;
|
|
||||||
}
|
|
||||||
sw_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
R_UDR = XOFF_CHAR;
|
|
||||||
|
|
||||||
// Clear the TXC bit -- "can be cleared by writing a one to its bit
|
|
||||||
// location". This makes sure flush() won't return until the bytes
|
|
||||||
// actually got written
|
|
||||||
B_TXC = 1;
|
|
||||||
|
|
||||||
// At this point there could be a race condition between the write() function
|
|
||||||
// and this sending of the XOFF char. This interrupt could happen between the
|
|
||||||
// wait to be empty TX buffer loop and the actual write of the character. Since
|
|
||||||
// the TX buffer is full because it's sending the XOFF char, the only way to be
|
|
||||||
// sure the write() function will succeed is to wait for the XOFF char to be
|
|
||||||
// completely sent. Since an extra character could be received during the wait
|
|
||||||
// it must also be handled!
|
|
||||||
while (!B_UDRE) {
|
|
||||||
|
|
||||||
if (B_RXC) {
|
|
||||||
// A char arrived while waiting for the TX buffer to be empty - Receive and process it!
|
|
||||||
|
|
||||||
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
|
||||||
|
|
||||||
// Read the character from the USART
|
|
||||||
c = R_UDR;
|
|
||||||
|
|
||||||
if (Cfg::EMERGENCYPARSER)
|
|
||||||
emergency_parser.update(emergency_state, c);
|
|
||||||
|
|
||||||
// If the character is to be stored at the index just before the tail
|
|
||||||
// (such that the head would advance to the current tail), the FIFO is
|
|
||||||
// full, so don't write the character or advance the head.
|
|
||||||
if (i != t) {
|
|
||||||
rx_buffer.buffer[h] = c;
|
|
||||||
h = i;
|
|
||||||
}
|
|
||||||
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
|
|
||||||
--rx_dropped_bytes;
|
|
||||||
}
|
|
||||||
sw_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point everything is ready. The write() function won't
|
|
||||||
// have any issues writing to the UART TX register if it needs to!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store the new head value - The main loop will retry until the value is stable
|
|
||||||
rx_buffer.head = h;
|
|
||||||
}
|
|
||||||
|
|
||||||
// (called with TX irqs disabled)
|
|
||||||
template<typename Cfg>
|
|
||||||
FORCE_INLINE void MarlinSerial<Cfg>::_tx_udr_empty_irq() {
|
|
||||||
if (Cfg::TX_SIZE > 0) {
|
|
||||||
// Read positions
|
|
||||||
uint8_t t = tx_buffer.tail;
|
|
||||||
const uint8_t h = tx_buffer.head;
|
|
||||||
|
|
||||||
if (Cfg::XONOFF) {
|
|
||||||
// If an XON char is pending to be sent, do it now
|
|
||||||
if (xon_xoff_state == XON_CHAR) {
|
|
||||||
|
|
||||||
// Send the character
|
|
||||||
R_UDR = XON_CHAR;
|
|
||||||
|
|
||||||
// clear the TXC bit -- "can be cleared by writing a one to its bit
|
|
||||||
// location". This makes sure flush() won't return until the bytes
|
|
||||||
// actually got written
|
|
||||||
B_TXC = 1;
|
|
||||||
|
|
||||||
// Remember we sent it.
|
|
||||||
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
|
|
||||||
|
|
||||||
// If nothing else to transmit, just disable TX interrupts.
|
|
||||||
if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If nothing to transmit, just disable TX interrupts. This could
|
|
||||||
// happen as the result of the non atomicity of the disabling of RX
|
|
||||||
// interrupts that could end reenabling TX interrupts as a side effect.
|
|
||||||
if (h == t) {
|
|
||||||
B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// There is something to TX, Send the next byte
|
|
||||||
const uint8_t c = tx_buffer.buffer[t];
|
|
||||||
t = (t + 1) & (Cfg::TX_SIZE - 1);
|
|
||||||
R_UDR = c;
|
|
||||||
tx_buffer.tail = t;
|
|
||||||
|
|
||||||
// Clear the TXC bit (by writing a one to its bit location).
|
|
||||||
// Ensures flush() won't return until the bytes are actually written/
|
|
||||||
B_TXC = 1;
|
|
||||||
|
|
||||||
// Disable interrupts if there is nothing to transmit following this byte
|
|
||||||
if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Public Methods
|
|
||||||
template<typename Cfg>
|
|
||||||
void MarlinSerial<Cfg>::begin(const long baud) {
|
|
||||||
uint16_t baud_setting;
|
|
||||||
bool useU2X = true;
|
|
||||||
|
|
||||||
#if F_CPU == 16000000UL && SERIAL_PORT == 0
|
|
||||||
// Hard-coded exception for compatibility with the bootloader shipped
|
|
||||||
// with the Duemilanove and previous boards, and the firmware on the
|
|
||||||
// 8U2 on the Uno and Mega 2560.
|
|
||||||
if (baud == 57600) useU2X = false;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
R_UCSRA = 0;
|
|
||||||
if (useU2X) {
|
|
||||||
B_U2X = 1;
|
|
||||||
baud_setting = (F_CPU / 4 / baud - 1) / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
baud_setting = (F_CPU / 8 / baud - 1) / 2;
|
|
||||||
|
|
||||||
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
|
|
||||||
R_UBRRH = baud_setting >> 8;
|
|
||||||
R_UBRRL = baud_setting;
|
|
||||||
|
|
||||||
B_RXEN = 1;
|
|
||||||
B_TXEN = 1;
|
|
||||||
B_RXCIE = 1;
|
|
||||||
if (Cfg::TX_SIZE > 0) B_UDRIE = 0;
|
|
||||||
_written = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
void MarlinSerial<Cfg>::end() {
|
|
||||||
B_RXEN = 0;
|
|
||||||
B_TXEN = 0;
|
|
||||||
B_RXCIE = 0;
|
|
||||||
B_UDRIE = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
int MarlinSerial<Cfg>::peek() {
|
|
||||||
const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
|
|
||||||
return h == t ? -1 : rx_buffer.buffer[t];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
int MarlinSerial<Cfg>::read() {
|
|
||||||
const ring_buffer_pos_t h = atomic_read_rx_head();
|
|
||||||
|
|
||||||
// Read the tail. Main thread owns it, so it is safe to directly read it
|
|
||||||
ring_buffer_pos_t t = rx_buffer.tail;
|
|
||||||
|
|
||||||
// If nothing to read, return now
|
|
||||||
if (h == t) return -1;
|
|
||||||
|
|
||||||
// Get the next char
|
|
||||||
const int v = rx_buffer.buffer[t];
|
|
||||||
t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1);
|
|
||||||
|
|
||||||
// Advance tail - Making sure the RX ISR will always get an stable value, even
|
|
||||||
// if it interrupts the writing of the value of that variable in the middle.
|
|
||||||
atomic_set_rx_tail(t);
|
|
||||||
|
|
||||||
if (Cfg::XONOFF) {
|
|
||||||
// If the XOFF char was sent, or about to be sent...
|
|
||||||
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
|
|
||||||
// Get count of bytes in the RX buffer
|
|
||||||
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
|
||||||
if (rx_count < (Cfg::RX_SIZE) / 10) {
|
|
||||||
if (Cfg::TX_SIZE > 0) {
|
|
||||||
// Signal we want an XON character to be sent.
|
|
||||||
xon_xoff_state = XON_CHAR;
|
|
||||||
// Enable TX ISR. Non atomic, but it will eventually enable them
|
|
||||||
B_UDRIE = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If not using TX interrupts, we must send the XON char now
|
|
||||||
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
|
|
||||||
while (!B_UDRE) sw_barrier();
|
|
||||||
R_UDR = XON_CHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::available() {
|
|
||||||
const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
|
|
||||||
return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
void MarlinSerial<Cfg>::flush() {
|
|
||||||
|
|
||||||
// Set the tail to the head:
|
|
||||||
// - Read the RX head index in a safe way. (See atomic_read_rx_head.)
|
|
||||||
// - Set the tail, making sure the RX ISR will always get a stable value, even
|
|
||||||
// if it interrupts the writing of the value of that variable in the middle.
|
|
||||||
atomic_set_rx_tail(atomic_read_rx_head());
|
|
||||||
|
|
||||||
if (Cfg::XONOFF) {
|
|
||||||
// If the XOFF char was sent, or about to be sent...
|
|
||||||
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
|
|
||||||
if (Cfg::TX_SIZE > 0) {
|
|
||||||
// Signal we want an XON character to be sent.
|
|
||||||
xon_xoff_state = XON_CHAR;
|
|
||||||
// Enable TX ISR. Non atomic, but it will eventually enable it.
|
|
||||||
B_UDRIE = 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// If not using TX interrupts, we must send the XON char now
|
|
||||||
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
|
|
||||||
while (!B_UDRE) sw_barrier();
|
|
||||||
R_UDR = XON_CHAR;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
void MarlinSerial<Cfg>::write(const uint8_t c) {
|
|
||||||
if (Cfg::TX_SIZE == 0) {
|
|
||||||
|
|
||||||
_written = true;
|
|
||||||
while (!B_UDRE) sw_barrier();
|
|
||||||
R_UDR = c;
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
_written = true;
|
|
||||||
|
|
||||||
// If the TX interrupts are disabled and the data register
|
|
||||||
// is empty, just write the byte to the data register and
|
|
||||||
// be done. This shortcut helps significantly improve the
|
|
||||||
// effective datarate at high (>500kbit/s) bitrates, where
|
|
||||||
// interrupt overhead becomes a slowdown.
|
|
||||||
// Yes, there is a race condition between the sending of the
|
|
||||||
// XOFF char at the RX ISR, but it is properly handled there
|
|
||||||
if (!B_UDRIE && B_UDRE) {
|
|
||||||
R_UDR = c;
|
|
||||||
|
|
||||||
// clear the TXC bit -- "can be cleared by writing a one to its bit
|
|
||||||
// location". This makes sure flush() won't return until the bytes
|
|
||||||
// actually got written
|
|
||||||
B_TXC = 1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
|
||||||
|
|
||||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
|
||||||
if (!ISRS_ENABLED()) {
|
|
||||||
|
|
||||||
// Make room by polling if it is possible to transmit, and do so!
|
|
||||||
while (i == tx_buffer.tail) {
|
|
||||||
|
|
||||||
// If we can transmit another byte, do it.
|
|
||||||
if (B_UDRE) _tx_udr_empty_irq();
|
|
||||||
|
|
||||||
// Make sure compiler rereads tx_buffer.tail
|
|
||||||
sw_barrier();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Interrupts are enabled, just wait until there is space
|
|
||||||
while (i == tx_buffer.tail) sw_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store new char. head is always safe to move
|
|
||||||
tx_buffer.buffer[tx_buffer.head] = c;
|
|
||||||
tx_buffer.head = i;
|
|
||||||
|
|
||||||
// Enable TX ISR - Non atomic, but it will eventually enable TX ISR
|
|
||||||
B_UDRIE = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Cfg>
|
|
||||||
void MarlinSerial<Cfg>::flushTX() {
|
|
||||||
|
|
||||||
if (Cfg::TX_SIZE == 0) {
|
|
||||||
// No bytes written, no need to flush. This special case is needed since there's
|
|
||||||
// no way to force the TXC (transmit complete) bit to 1 during initialization.
|
|
||||||
if (!_written) return;
|
|
||||||
|
|
||||||
// Wait until everything was transmitted
|
|
||||||
while (!B_TXC) sw_barrier();
|
|
||||||
|
|
||||||
// At this point nothing is queued anymore (DRIE is disabled) and
|
|
||||||
// the hardware finished transmission (TXC is set).
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
|
|
||||||
// No bytes written, no need to flush. This special case is needed since there's
|
|
||||||
// no way to force the TXC (transmit complete) bit to 1 during initialization.
|
|
||||||
if (!_written) return;
|
|
||||||
|
|
||||||
// If global interrupts are disabled (as the result of being called from an ISR)...
|
|
||||||
if (!ISRS_ENABLED()) {
|
|
||||||
|
|
||||||
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
|
|
||||||
while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
|
|
||||||
|
|
||||||
// If there is more space, send an extra character
|
|
||||||
if (B_UDRE) _tx_udr_empty_irq();
|
|
||||||
|
|
||||||
sw_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Wait until everything was transmitted
|
|
||||||
while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier();
|
|
||||||
}
|
|
||||||
|
|
||||||
// At this point nothing is queued anymore (DRIE is disabled) and
|
|
||||||
// the hardware finished transmission (TXC is set).
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hookup ISR handlers
|
|
||||||
ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) {
|
|
||||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::store_rxd_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
|
|
||||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::_tx_udr_empty_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Because of the template definition above, it's required to instantiate the template to have all methods generated
|
|
||||||
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT> >;
|
|
||||||
MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser);
|
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_2
|
|
||||||
|
|
||||||
// Hookup ISR handlers
|
|
||||||
ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _RX_vect)) {
|
|
||||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::store_rxd_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, SERIAL_PORT_2, _UDRE_vect)) {
|
|
||||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::_tx_udr_empty_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> >;
|
|
||||||
MSerialT2 customizedSerial2(MSerialT2::HasEmergencyParser);
|
|
||||||
|
|
||||||
#endif // SERIAL_PORT_2
|
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_3
|
|
||||||
|
|
||||||
// Hookup ISR handlers
|
|
||||||
ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _RX_vect)) {
|
|
||||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_3>>::store_rxd_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, SERIAL_PORT_3, _UDRE_vect)) {
|
|
||||||
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_3>>::_tx_udr_empty_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> >;
|
|
||||||
MSerialT3 customizedSerial3(MSerialT3::HasEmergencyParser);
|
|
||||||
|
|
||||||
#endif // SERIAL_PORT_3
|
|
||||||
|
|
||||||
#ifdef MMU2_SERIAL_PORT
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) {
|
|
||||||
MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>>::store_rxd_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _UDRE_vect)) {
|
|
||||||
MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>>::_tx_udr_empty_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
template class MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> >;
|
|
||||||
MSerialMMU2 mmuSerial(MSerialMMU2::HasEmergencyParser);
|
|
||||||
|
|
||||||
#endif // MMU2_SERIAL_PORT
|
|
||||||
|
|
||||||
#ifdef LCD_SERIAL_PORT
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _RX_vect)) {
|
|
||||||
MarlinSerial<LCDSerialCfg<LCD_SERIAL_PORT>>::store_rxd_char();
|
|
||||||
}
|
|
||||||
|
|
||||||
ISR(SERIAL_REGNAME(USART, LCD_SERIAL_PORT, _UDRE_vect)) {
|
|
||||||
MarlinSerial<LCDSerialCfg<LCD_SERIAL_PORT>>::_tx_udr_empty_irq();
|
|
||||||
}
|
|
||||||
|
|
||||||
template class MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> >;
|
|
||||||
MSerialLCD lcdSerial(MSerialLCD::HasEmergencyParser);
|
|
||||||
|
|
||||||
#if HAS_DGUS_LCD
|
|
||||||
template<typename Cfg>
|
|
||||||
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
|
|
||||||
const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
|
|
||||||
h = tx_buffer.head; // next pos for queue.
|
|
||||||
int ret = t - h - 1;
|
|
||||||
if (ret < 0) ret += Cfg::TX_SIZE + 1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // LCD_SERIAL_PORT
|
|
||||||
|
|
||||||
#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
|
|
||||||
|
|
||||||
// For AT90USB targets use the UART for BT interfacing
|
|
||||||
#if defined(USBCON) && ENABLED(BLUETOOTH)
|
|
||||||
MSerialBT bluetoothSerial(false);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // __AVR__
|
|
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if HAS_SPI_TFT || HAS_FSMC_TFT
|
|
||||||
#error "Sorry! TFT displays are not available for HAL/AVR."
|
|
||||||
#endif
|
|
@@ -1,91 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifdef ARDUINO_ARCH_SAM
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfigPre.h"
|
|
||||||
|
|
||||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
|
||||||
|
|
||||||
#include "../shared/HAL_MinSerial.h"
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
static void TXBegin() {
|
|
||||||
// Disable UART interrupt in NVIC
|
|
||||||
NVIC_DisableIRQ( UART_IRQn );
|
|
||||||
|
|
||||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
|
||||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
|
||||||
__DSB();
|
|
||||||
__ISB();
|
|
||||||
|
|
||||||
// Disable clock
|
|
||||||
pmc_disable_periph_clk( ID_UART );
|
|
||||||
|
|
||||||
// Configure PMC
|
|
||||||
pmc_enable_periph_clk( ID_UART );
|
|
||||||
|
|
||||||
// Disable PDC channel
|
|
||||||
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
|
||||||
|
|
||||||
// Reset and disable receiver and transmitter
|
|
||||||
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
|
|
||||||
|
|
||||||
// Configure mode: 8bit, No parity, 1 bit stop
|
|
||||||
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
|
|
||||||
|
|
||||||
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
|
|
||||||
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
|
|
||||||
|
|
||||||
// Enable receiver and transmitter
|
|
||||||
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A SW memory barrier, to ensure GCC does not overoptimize loops
|
|
||||||
#define sw_barrier() __asm__ volatile("": : :"memory");
|
|
||||||
static void TX(char c) {
|
|
||||||
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
|
|
||||||
UART->UART_THR = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
void install_min_serial() {
|
|
||||||
HAL_min_serial_init = &TXBegin;
|
|
||||||
HAL_min_serial_out = &TX;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DISABLED(DYNAMIC_VECTORTABLE)
|
|
||||||
extern "C" {
|
|
||||||
__attribute__((naked)) void JumpHandler_ASM() {
|
|
||||||
__asm__ __volatile__ (
|
|
||||||
"b CommonHandler_ASM\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
|
|
||||||
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
|
|
||||||
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
|
|
||||||
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
|
|
||||||
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // POSTMORTEM_DEBUGGING
|
|
||||||
#endif // ARDUINO_ARCH_SAM
|
|
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
using MarlinSPI = SPIClass;
|
|
@@ -1,142 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifdef ARDUINO_ARCH_SAM
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE
|
|
||||||
* Copyright (c) 2017 Eduardo José Tagle. All right reserved
|
|
||||||
* Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
|
||||||
|
|
||||||
#if HAS_USB_SERIAL
|
|
||||||
|
|
||||||
#include "MarlinSerialUSB.h"
|
|
||||||
|
|
||||||
// Imports from Atmel USB Stack/CDC implementation
|
|
||||||
extern "C" {
|
|
||||||
bool usb_task_cdc_isenabled();
|
|
||||||
bool usb_task_cdc_dtr_active();
|
|
||||||
bool udi_cdc_is_rx_ready();
|
|
||||||
int udi_cdc_getc();
|
|
||||||
bool udi_cdc_is_tx_ready();
|
|
||||||
int udi_cdc_putc(int value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Pending character
|
|
||||||
static int pending_char = -1;
|
|
||||||
|
|
||||||
// Public Methods
|
|
||||||
void MarlinSerialUSB::begin(const long) {}
|
|
||||||
|
|
||||||
void MarlinSerialUSB::end() {}
|
|
||||||
|
|
||||||
int MarlinSerialUSB::peek() {
|
|
||||||
if (pending_char >= 0)
|
|
||||||
return pending_char;
|
|
||||||
|
|
||||||
// If USB CDC not enumerated or not configured on the PC side
|
|
||||||
if (!usb_task_cdc_isenabled())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// If no bytes sent from the PC
|
|
||||||
if (!udi_cdc_is_rx_ready())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
pending_char = udi_cdc_getc();
|
|
||||||
|
|
||||||
TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast<MSerialT1*>(this)->emergency_state, (char)pending_char));
|
|
||||||
|
|
||||||
return pending_char;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MarlinSerialUSB::read() {
|
|
||||||
if (pending_char >= 0) {
|
|
||||||
int ret = pending_char;
|
|
||||||
pending_char = -1;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If USB CDC not enumerated or not configured on the PC side
|
|
||||||
if (!usb_task_cdc_isenabled())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
// If no bytes sent from the PC
|
|
||||||
if (!udi_cdc_is_rx_ready())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int c = udi_cdc_getc();
|
|
||||||
|
|
||||||
TERN_(EMERGENCY_PARSER, emergency_parser.update(static_cast<MSerialT1*>(this)->emergency_state, (char)c));
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
int MarlinSerialUSB::available() {
|
|
||||||
if (pending_char > 0) return pending_char;
|
|
||||||
return pending_char == 0 ||
|
|
||||||
// or USB CDC enumerated and configured on the PC side and some bytes where sent to us */
|
|
||||||
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
|
|
||||||
}
|
|
||||||
|
|
||||||
void MarlinSerialUSB::flush() { }
|
|
||||||
|
|
||||||
size_t MarlinSerialUSB::write(const uint8_t c) {
|
|
||||||
|
|
||||||
/* Do not even bother sending anything if USB CDC is not enumerated
|
|
||||||
or not configured on the PC side or there is no program on the PC
|
|
||||||
listening to our messages */
|
|
||||||
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Wait until the PC has read the pending to be sent data */
|
|
||||||
while (usb_task_cdc_isenabled() &&
|
|
||||||
usb_task_cdc_dtr_active() &&
|
|
||||||
!udi_cdc_is_tx_ready()) {
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Do not even bother sending anything if USB CDC is not enumerated
|
|
||||||
or not configured on the PC side or there is no program on the PC
|
|
||||||
listening to our messages at this point */
|
|
||||||
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// Fifo full
|
|
||||||
// udi_cdc_signal_overrun();
|
|
||||||
udi_cdc_putc(c);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Preinstantiate
|
|
||||||
#if SERIAL_PORT == -1
|
|
||||||
MSerialT1 customizedSerial1(TERN0(EMERGENCY_PARSER, true));
|
|
||||||
#endif
|
|
||||||
#if SERIAL_PORT_2 == -1
|
|
||||||
MSerialT2 customizedSerial2(TERN0(EMERGENCY_PARSER, true));
|
|
||||||
#endif
|
|
||||||
#if SERIAL_PORT_3 == -1
|
|
||||||
MSerialT3 customizedSerial3(TERN0(EMERGENCY_PARSER, true));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // HAS_USB_SERIAL
|
|
||||||
#endif // ARDUINO_ARCH_SAM
|
|
@@ -1,65 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MarlinSerialUSB_Due.h - Hardware Serial over USB (CDC) library for Arduino DUE
|
|
||||||
* Copyright (c) 2017 Eduardo José Tagle. All right reserved
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
|
||||||
#include "../../core/serial_hook.h"
|
|
||||||
|
|
||||||
#include <WString.h>
|
|
||||||
|
|
||||||
struct MarlinSerialUSB {
|
|
||||||
void begin(const long);
|
|
||||||
void end();
|
|
||||||
int peek();
|
|
||||||
int read();
|
|
||||||
void flush();
|
|
||||||
int available();
|
|
||||||
size_t write(const uint8_t c);
|
|
||||||
|
|
||||||
#if ENABLED(SERIAL_STATS_DROPPED_RX)
|
|
||||||
FORCE_INLINE uint32_t dropped() { return 0; }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
|
|
||||||
FORCE_INLINE int rxMaxEnqueued() { return 0; }
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if SERIAL_PORT == -1
|
|
||||||
typedef Serial1Class<MarlinSerialUSB> MSerialT1;
|
|
||||||
extern MSerialT1 customizedSerial1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SERIAL_PORT_2 == -1
|
|
||||||
typedef Serial1Class<MarlinSerialUSB> MSerialT2;
|
|
||||||
extern MSerialT2 customizedSerial2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if SERIAL_PORT_3 == -1
|
|
||||||
typedef Serial1Class<MarlinSerialUSB> MSerialT3;
|
|
||||||
extern MSerialT3 customizedSerial3;
|
|
||||||
#endif
|
|
@@ -1,206 +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/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The PWM module is only used to generate interrupts at specified times. It
|
|
||||||
* is NOT used to directly toggle pins. The ISR writes to the pin assigned to
|
|
||||||
* that interrupt.
|
|
||||||
*
|
|
||||||
* All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to
|
|
||||||
* not have obvious ripple on the Vref signals.
|
|
||||||
*
|
|
||||||
* The data structures are setup to minimize the computation done by the ISR which
|
|
||||||
* minimizes ISR execution time. Execution times are 0.8 to 1.1 microseconds.
|
|
||||||
*
|
|
||||||
* FIve PWM interrupt sources are used. Channel 0 sets the base period. All Vref
|
|
||||||
* signals are set active when this counter overflows and resets to zero. The compare
|
|
||||||
* values in channels 1-4 are set to give the desired duty cycle for that Vref pin.
|
|
||||||
* When counter 0 matches the compare value then that channel generates an interrupt.
|
|
||||||
* The ISR checks the source of the interrupt and sets the corresponding pin inactive.
|
|
||||||
*
|
|
||||||
* Some jitter in the Vref signal is OK so the interrupt priority is left at its default value.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../../../inc/MarlinConfig.h"
|
|
||||||
|
|
||||||
#if MB(PRINTRBOARD_G2)
|
|
||||||
|
|
||||||
#include "G2_PWM.h"
|
|
||||||
|
|
||||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_X)
|
|
||||||
#define G2_PWM_X 1
|
|
||||||
#else
|
|
||||||
#define G2_PWM_X 0
|
|
||||||
#endif
|
|
||||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Y)
|
|
||||||
#define G2_PWM_Y 1
|
|
||||||
#else
|
|
||||||
#define G2_PWM_Y 0
|
|
||||||
#endif
|
|
||||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
|
|
||||||
#define G2_PWM_Z 1
|
|
||||||
#else
|
|
||||||
#define G2_PWM_Z 0
|
|
||||||
#endif
|
|
||||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_E)
|
|
||||||
#define G2_PWM_E 1
|
|
||||||
#else
|
|
||||||
#define G2_PWM_E 0
|
|
||||||
#endif
|
|
||||||
#define G2_MASK_X(V) (G2_PWM_X * (V))
|
|
||||||
#define G2_MASK_Y(V) (G2_PWM_Y * (V))
|
|
||||||
#define G2_MASK_Z(V) (G2_PWM_Z * (V))
|
|
||||||
#define G2_MASK_E(V) (G2_PWM_E * (V))
|
|
||||||
|
|
||||||
volatile uint32_t *SODR_A = &PIOA->PIO_SODR,
|
|
||||||
*SODR_B = &PIOB->PIO_SODR,
|
|
||||||
*CODR_A = &PIOA->PIO_CODR,
|
|
||||||
*CODR_B = &PIOB->PIO_CODR;
|
|
||||||
|
|
||||||
PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT;
|
|
||||||
|
|
||||||
void Stepper::digipot_init() {
|
|
||||||
|
|
||||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_X)
|
|
||||||
OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins
|
|
||||||
#endif
|
|
||||||
#if PIN_EXISTS(MOTOR_CURRENT_PWM_Y)
|
|
||||||
OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0);
|
|
||||||
#endif
|
|
||||||
#if G2_PWM_Z
|
|
||||||
OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0);
|
|
||||||
#endif
|
|
||||||
#if G2_PWM_E
|
|
||||||
OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define WPKEY (0x50574D << 8) // “PWM” in ASCII
|
|
||||||
#define WPCMD_DIS_SW 0 // command to disable Write Protect SW
|
|
||||||
#define WPRG_ALL (PWM_WPCR_WPRG0 | PWM_WPCR_WPRG1 | PWM_WPCR_WPRG2 | PWM_WPCR_WPRG3 | PWM_WPCR_WPRG4 | PWM_WPCR_WPRG5) // all Write Protect Groups
|
|
||||||
|
|
||||||
#define PWM_CLOCK_F F_CPU / 1000000UL // set clock to 1MHz
|
|
||||||
|
|
||||||
PMC->PMC_PCER1 = PMC_PCER1_PID36; // enable PWM controller clock (disabled on power up)
|
|
||||||
|
|
||||||
PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers
|
|
||||||
PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled
|
|
||||||
PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned
|
|
||||||
if (G2_PWM_X) PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned
|
|
||||||
if (G2_PWM_Y) PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned
|
|
||||||
if (G2_PWM_Z) PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned
|
|
||||||
if (G2_PWM_E) PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned
|
|
||||||
|
|
||||||
PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period
|
|
||||||
|
|
||||||
PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows
|
|
||||||
PWM->PWM_IER2 = PWM_IER2_CMPM0
|
|
||||||
| G2_MASK_X(PWM_IER2_CMPM1)
|
|
||||||
| G2_MASK_Y(PWM_IER2_CMPM2)
|
|
||||||
| G2_MASK_Z(PWM_IER2_CMPM3)
|
|
||||||
| G2_MASK_E(PWM_IER2_CMPM4)
|
|
||||||
; // generate interrupt on compare event
|
|
||||||
|
|
||||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive
|
|
||||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive
|
|
||||||
if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive
|
|
||||||
if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive
|
|
||||||
|
|
||||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event
|
|
||||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event
|
|
||||||
if (G2_PWM_Z) PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event
|
|
||||||
if (G2_PWM_E) PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event
|
|
||||||
|
|
||||||
PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0
|
|
||||||
| G2_MASK_X(PWM_SCM_SYNC1)
|
|
||||||
| G2_MASK_Y(PWM_SCM_SYNC2)
|
|
||||||
| G2_MASK_Z(PWM_SCM_SYNC3)
|
|
||||||
| G2_MASK_E(PWM_SCM_SYNC4)
|
|
||||||
; // sync 1-4 with 0, use mode 0 for updates
|
|
||||||
|
|
||||||
PWM->PWM_ENA = PWM_ENA_CHID0
|
|
||||||
| G2_MASK_X(PWM_ENA_CHID1)
|
|
||||||
| G2_MASK_Y(PWM_ENA_CHID2)
|
|
||||||
| G2_MASK_Z(PWM_ENA_CHID3)
|
|
||||||
| G2_MASK_E(PWM_ENA_CHID4)
|
|
||||||
; // enable channels used by G2
|
|
||||||
|
|
||||||
PWM->PWM_IER1 = PWM_IER1_CHID0
|
|
||||||
| G2_MASK_X(PWM_IER1_CHID1)
|
|
||||||
| G2_MASK_Y(PWM_IER1_CHID2)
|
|
||||||
| G2_MASK_Z(PWM_IER1_CHID3)
|
|
||||||
| G2_MASK_E(PWM_IER1_CHID4)
|
|
||||||
; // enable interrupts for channels used by G2
|
|
||||||
|
|
||||||
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler
|
|
||||||
NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals)
|
|
||||||
}
|
|
||||||
|
|
||||||
void Stepper::set_digipot_current(const uint8_t driver, const int16_t current) {
|
|
||||||
|
|
||||||
if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed
|
|
||||||
|
|
||||||
switch (driver) {
|
|
||||||
case 0:
|
|
||||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y
|
|
||||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current));
|
|
||||||
if (G2_PWM_X) PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event
|
|
||||||
if (G2_PWM_Y) PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event
|
|
||||||
if (G2_PWM_X || G2_PWM_Y) PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (G2_PWM_Z) {
|
|
||||||
PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z
|
|
||||||
PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event
|
|
||||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (G2_PWM_E) {
|
|
||||||
PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E
|
|
||||||
PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event
|
|
||||||
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS;
|
|
||||||
|
|
||||||
void PWM_Handler() {
|
|
||||||
PWM_ISR1_STATUS = PWM->PWM_ISR1;
|
|
||||||
PWM_ISR2_STATUS = PWM->PWM_ISR2;
|
|
||||||
if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt
|
|
||||||
if (G2_PWM_X) *ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active
|
|
||||||
if (G2_PWM_Y) *ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active
|
|
||||||
if (G2_PWM_Z) *ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active
|
|
||||||
if (G2_PWM_E) *ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (G2_PWM_X && (PWM_ISR2_STATUS & PWM_IER2_CMPM1)) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive
|
|
||||||
if (G2_PWM_Y && (PWM_ISR2_STATUS & PWM_IER2_CMPM2)) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive
|
|
||||||
if (G2_PWM_Z && (PWM_ISR2_STATUS & PWM_IER2_CMPM3)) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive
|
|
||||||
if (G2_PWM_E && (PWM_ISR2_STATUS & PWM_IER2_CMPM4)) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // PRINTRBOARD_G2
|
|
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if HAS_SPI_TFT || HAS_FSMC_TFT
|
|
||||||
#error "Sorry! TFT displays are not available for HAL/DUE."
|
|
||||||
#endif
|
|
@@ -1,28 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if USE_FALLBACK_EEPROM
|
|
||||||
#define FLASH_EEPROM_EMULATION
|
|
||||||
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
|
|
||||||
#define USE_SHARED_EEPROM 1
|
|
||||||
#endif
|
|
@@ -1,18 +0,0 @@
|
|||||||
#
|
|
||||||
# Set upload_command
|
|
||||||
#
|
|
||||||
# Windows: bossac.exe
|
|
||||||
# Other: leave unchanged
|
|
||||||
#
|
|
||||||
|
|
||||||
import platform
|
|
||||||
current_OS = platform.system()
|
|
||||||
|
|
||||||
if current_OS == 'Windows':
|
|
||||||
|
|
||||||
Import("env")
|
|
||||||
|
|
||||||
# Use bossac.exe on Windows
|
|
||||||
env.Replace(
|
|
||||||
UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
|
|
||||||
)
|
|
@@ -1,26 +0,0 @@
|
|||||||
/**
|
|
||||||
* Marlin 3D Printer Firmware
|
|
||||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
|
||||||
*
|
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <SPI.h>
|
|
||||||
|
|
||||||
using MarlinSPI = SPIClass;
|
|
@@ -1,59 +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
|
|
||||||
*
|
|
||||||
* Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Description: Tone function for ESP32
|
|
||||||
* Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_ESP32
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
|
||||||
#include "HAL.h"
|
|
||||||
|
|
||||||
static pin_t tone_pin;
|
|
||||||
volatile static int32_t toggles;
|
|
||||||
|
|
||||||
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
|
|
||||||
tone_pin = _pin;
|
|
||||||
toggles = 2 * frequency * duration / 1000;
|
|
||||||
HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
|
|
||||||
}
|
|
||||||
|
|
||||||
void noTone(const pin_t _pin) {
|
|
||||||
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
|
|
||||||
WRITE(_pin, LOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
HAL_TONE_TIMER_ISR() {
|
|
||||||
HAL_timer_isr_prologue(TONE_TIMER_NUM);
|
|
||||||
|
|
||||||
if (toggles) {
|
|
||||||
toggles--;
|
|
||||||
TOGGLE(tone_pin);
|
|
||||||
}
|
|
||||||
else noTone(tone_pin); // turn off interrupt
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // ARDUINO_ARCH_ESP32
|
|
@@ -16,35 +16,19 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "platforms.h"
|
#include "platforms.h"
|
||||||
|
|
||||||
#ifndef GCC_VERSION
|
|
||||||
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include HAL_PATH(.,HAL.h)
|
#include HAL_PATH(.,HAL.h)
|
||||||
|
|
||||||
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
|
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
|
||||||
|
|
||||||
#ifndef I2C_ADDRESS
|
|
||||||
#define I2C_ADDRESS(A) uint8_t(A)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Needed for AVR sprintf_P PROGMEM extension
|
|
||||||
#ifndef S_FMT
|
|
||||||
#define S_FMT "%s"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// String helper
|
|
||||||
#ifndef PGMSTR
|
|
||||||
#define PGMSTR(NAM,STR) const char NAM[] = STR
|
|
||||||
#endif
|
|
||||||
|
|
||||||
inline void watchdog_refresh() {
|
inline void watchdog_refresh() {
|
||||||
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
|
#if ENABLED(USE_WATCHDOG)
|
||||||
|
HAL_watchdog_refresh();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
@@ -16,21 +16,15 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
#include "../../inc/MarlinConfig.h"
|
||||||
#include "HAL.h"
|
#include "HAL.h"
|
||||||
|
|
||||||
#ifdef USBCON
|
|
||||||
DefaultSerial1 MSerial0(false, Serial);
|
|
||||||
#ifdef BLUETOOTH
|
|
||||||
BTSerial btSerial(false, bluetoothSerial);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Public Variables
|
// Public Variables
|
||||||
// ------------------------
|
// ------------------------
|
||||||
@@ -58,15 +52,6 @@ void HAL_init() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_reboot() {
|
|
||||||
#if ENABLED(USE_WATCHDOG)
|
|
||||||
while (1) { /* run out the watchdog */ }
|
|
||||||
#else
|
|
||||||
void (*resetFunc)() = 0; // Declare resetFunc() at address 0
|
|
||||||
resetFunc(); // Jump to address 0
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if ENABLED(SDSUPPORT)
|
#if ENABLED(SDSUPPORT)
|
||||||
|
|
||||||
#include "../../sd/SdFatUtil.h"
|
#include "../../sd/SdFatUtil.h"
|
@@ -14,12 +14,54 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "../shared/Marduino.h"
|
||||||
|
#include "../shared/HAL_SPI.h"
|
||||||
|
#include "fastio.h"
|
||||||
|
#include "watchdog.h"
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
#ifdef USBCON
|
||||||
|
#include <HardwareSerial.h>
|
||||||
|
#else
|
||||||
|
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
|
||||||
|
#include "MarlinSerial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include <avr/pgmspace.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
|
||||||
|
#ifndef pgm_read_ptr
|
||||||
|
// Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for
|
||||||
|
// Windows Subsystem for Linux on Windows 10 as of 10/18/2019
|
||||||
|
#define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
|
||||||
|
#define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short))
|
||||||
|
#define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Defines
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
//#define analogInputToDigitalPin(IO) IO
|
||||||
|
|
||||||
|
#ifndef CRITICAL_SECTION_START
|
||||||
|
#define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli()
|
||||||
|
#define CRITICAL_SECTION_END() SREG = _sreg
|
||||||
|
#endif
|
||||||
|
#define ISRS_ENABLED() TEST(SREG, SREG_I)
|
||||||
|
#define ENABLE_ISRS() sei()
|
||||||
|
#define DISABLE_ISRS() cli()
|
||||||
|
|
||||||
|
// On AVR this is in math.h?
|
||||||
|
//#define square(x) ((x)*(x))
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Types
|
// Types
|
||||||
@@ -28,21 +70,84 @@
|
|||||||
typedef uint16_t hal_timer_t;
|
typedef uint16_t hal_timer_t;
|
||||||
#define HAL_TIMER_TYPE_MAX 0xFFFF
|
#define HAL_TIMER_TYPE_MAX 0xFFFF
|
||||||
|
|
||||||
|
typedef int8_t pin_t;
|
||||||
|
|
||||||
|
#define SHARED_SERVOS HAS_SERVOS
|
||||||
|
#define HAL_SERVO_LIB Servo
|
||||||
|
|
||||||
// ------------------------
|
// ------------------------
|
||||||
// Defines
|
// Public Variables
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
||||||
|
//extern uint8_t MCUSR;
|
||||||
|
|
||||||
|
// Serial ports
|
||||||
|
#ifdef USBCON
|
||||||
|
#if ENABLED(BLUETOOTH)
|
||||||
|
#define MYSERIAL0 bluetoothSerial
|
||||||
|
#else
|
||||||
|
#define MYSERIAL0 Serial
|
||||||
|
#endif
|
||||||
|
#define NUM_SERIAL 1
|
||||||
|
#else
|
||||||
|
#if !WITHIN(SERIAL_PORT, -1, 3)
|
||||||
|
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MYSERIAL0 customizedSerial1
|
||||||
|
|
||||||
|
#ifdef SERIAL_PORT_2
|
||||||
|
#if !WITHIN(SERIAL_PORT_2, -1, 3)
|
||||||
|
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
|
||||||
|
#elif SERIAL_PORT_2 == SERIAL_PORT
|
||||||
|
#error "SERIAL_PORT_2 must be different than SERIAL_PORT. Please update your configuration."
|
||||||
|
#endif
|
||||||
|
#define MYSERIAL1 customizedSerial2
|
||||||
|
#define NUM_SERIAL 2
|
||||||
|
#else
|
||||||
|
#define NUM_SERIAL 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DGUS_SERIAL_PORT
|
||||||
|
#if !WITHIN(DGUS_SERIAL_PORT, -1, 3)
|
||||||
|
#error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
|
||||||
|
#elif DGUS_SERIAL_PORT == SERIAL_PORT
|
||||||
|
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT. Please update your configuration."
|
||||||
|
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
|
||||||
|
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
|
||||||
|
#endif
|
||||||
|
#define DGUS_SERIAL internalDgusSerial
|
||||||
|
|
||||||
|
#define DGUS_SERIAL_GET_TX_BUFFER_FREE DGUS_SERIAL.get_tx_buffer_free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ------------------------
|
||||||
|
// Public functions
|
||||||
|
// ------------------------
|
||||||
|
|
||||||
|
void HAL_init();
|
||||||
|
|
||||||
|
//void cli();
|
||||||
|
|
||||||
|
//void _delay_ms(const int delay);
|
||||||
|
|
||||||
|
inline void HAL_clear_reset_source() { MCUSR = 0; }
|
||||||
|
inline uint8_t HAL_get_reset_source() { return MCUSR; }
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
|
extern "C" {
|
||||||
|
int freeMemory();
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
// timers
|
||||||
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
|
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
|
||||||
|
|
||||||
#ifndef STEP_TIMER_NUM
|
#define STEP_TIMER_NUM 1
|
||||||
#define STEP_TIMER_NUM 1
|
#define TEMP_TIMER_NUM 0
|
||||||
#endif
|
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
||||||
#ifndef PULSE_TIMER_NUM
|
|
||||||
#define PULSE_TIMER_NUM STEP_TIMER_NUM
|
|
||||||
#endif
|
|
||||||
#ifndef TEMP_TIMER_NUM
|
|
||||||
#define TEMP_TIMER_NUM 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
|
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
|
||||||
|
|
||||||
@@ -113,8 +218,6 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
|
|||||||
#define HAL_timer_isr_epilogue(TIMER_NUM)
|
#define HAL_timer_isr_epilogue(TIMER_NUM)
|
||||||
|
|
||||||
/* 18 cycles maximum latency */
|
/* 18 cycles maximum latency */
|
||||||
#ifndef HAL_STEP_TIMER_ISR
|
|
||||||
|
|
||||||
#define HAL_STEP_TIMER_ISR() \
|
#define HAL_STEP_TIMER_ISR() \
|
||||||
extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
extern "C" void TIMER1_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
||||||
extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
extern "C" void TIMER1_COMPA_vect_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
|
||||||
@@ -187,10 +290,6 @@ void TIMER1_COMPA_vect() { \
|
|||||||
} \
|
} \
|
||||||
void TIMER1_COMPA_vect_bottom()
|
void TIMER1_COMPA_vect_bottom()
|
||||||
|
|
||||||
#endif // HAL_STEP_TIMER_ISR
|
|
||||||
|
|
||||||
#ifndef HAL_TEMP_TIMER_ISR
|
|
||||||
|
|
||||||
/* 14 cycles maximum latency */
|
/* 14 cycles maximum latency */
|
||||||
#define HAL_TEMP_TIMER_ISR() \
|
#define HAL_TEMP_TIMER_ISR() \
|
||||||
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
|
||||||
@@ -257,4 +356,60 @@ void TIMER0_COMPB_vect() { \
|
|||||||
} \
|
} \
|
||||||
void TIMER0_COMPB_vect_bottom()
|
void TIMER0_COMPB_vect_bottom()
|
||||||
|
|
||||||
#endif // HAL_TEMP_TIMER_ISR
|
// ADC
|
||||||
|
#ifdef DIDR2
|
||||||
|
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
|
||||||
|
#else
|
||||||
|
#define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
inline void HAL_adc_init() {
|
||||||
|
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
|
||||||
|
DIDR0 = 0;
|
||||||
|
#ifdef DIDR2
|
||||||
|
DIDR2 = 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC)
|
||||||
|
#ifdef MUX5
|
||||||
|
#define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
|
||||||
|
#else
|
||||||
|
#define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define HAL_ADC_RESOLUTION 10
|
||||||
|
#define HAL_READ_ADC() ADC
|
||||||
|
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
|
||||||
|
|
||||||
|
#define GET_PIN_MAP_PIN(index) index
|
||||||
|
#define GET_PIN_MAP_INDEX(pin) pin
|
||||||
|
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
|
||||||
|
|
||||||
|
#define HAL_SENSITIVE_PINS 0, 1
|
||||||
|
|
||||||
|
#ifdef __AVR_AT90USB1286__
|
||||||
|
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// AVR compatibility
|
||||||
|
#define strtof strtod
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_pwm_frequency
|
||||||
|
* Sets the frequency of the timer corresponding to the provided pin
|
||||||
|
* as close as possible to the provided desired frequency. Internally
|
||||||
|
* calculates the required waveform generation mode, prescaler and
|
||||||
|
* resolution values required and sets the timer registers accordingly.
|
||||||
|
* NOTE that the frequency is applied to all pins on the timer (Ex OC3A, OC3B and OC3B)
|
||||||
|
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
|
||||||
|
*/
|
||||||
|
void set_pwm_frequency(const pin_t pin, int f_desired);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set_pwm_duty
|
||||||
|
* Sets the PWM duty cycle of the provided pin to the provided value
|
||||||
|
* Optionally allows inverting the duty cycle [default = false]
|
||||||
|
* Optionally allows changing the maximum size of the provided value to enable finer PWM duty control [default = 255]
|
||||||
|
*/
|
||||||
|
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -34,17 +34,17 @@
|
|||||||
#include "../../inc/MarlinConfig.h"
|
#include "../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
void spiBegin() {
|
void spiBegin() {
|
||||||
OUT_WRITE(SD_SS_PIN, HIGH);
|
OUT_WRITE(SS_PIN, HIGH);
|
||||||
SET_OUTPUT(SD_SCK_PIN);
|
SET_OUTPUT(SCK_PIN);
|
||||||
SET_INPUT(SD_MISO_PIN);
|
SET_INPUT(MISO_PIN);
|
||||||
SET_OUTPUT(SD_MOSI_PIN);
|
SET_OUTPUT(MOSI_PIN);
|
||||||
|
|
||||||
#if DISABLED(SOFTWARE_SPI)
|
#if DISABLED(SOFTWARE_SPI)
|
||||||
// SS must be in output mode even it is not chip select
|
// SS must be in output mode even it is not chip select
|
||||||
//SET_OUTPUT(SD_SS_PIN);
|
//SET_OUTPUT(SS_PIN);
|
||||||
// set SS high - may be chip select for another SPI device
|
// set SS high - may be chip select for another SPI device
|
||||||
//#if SET_SPI_SS_HIGH
|
//#if SET_SPI_SS_HIGH
|
||||||
//WRITE(SD_SS_PIN, HIGH);
|
//WRITE(SS_PIN, HIGH);
|
||||||
//#endif
|
//#endif
|
||||||
// set a default rate
|
// set a default rate
|
||||||
spiInit(1);
|
spiInit(1);
|
||||||
@@ -74,8 +74,7 @@ void spiBegin() {
|
|||||||
#elif defined(PRR0)
|
#elif defined(PRR0)
|
||||||
PRR0
|
PRR0
|
||||||
#endif
|
#endif
|
||||||
, PRSPI
|
, PRSPI);
|
||||||
);
|
|
||||||
|
|
||||||
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
|
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
|
||||||
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
|
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
|
||||||
@@ -89,7 +88,7 @@ void spiBegin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** SPI read data */
|
/** SPI read data */
|
||||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
if (nbyte-- == 0) return;
|
if (nbyte-- == 0) return;
|
||||||
SPDR = 0xFF;
|
SPDR = 0xFF;
|
||||||
for (uint16_t i = 0; i < nbyte; i++) {
|
for (uint16_t i = 0; i < nbyte; i++) {
|
||||||
@@ -108,7 +107,7 @@ void spiBegin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** SPI send block */
|
/** SPI send block */
|
||||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
SPDR = token;
|
SPDR = token;
|
||||||
for (uint16_t i = 0; i < 512; i += 2) {
|
for (uint16_t i = 0; i < 512; i += 2) {
|
||||||
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
|
||||||
@@ -196,19 +195,19 @@ void spiBegin() {
|
|||||||
// no interrupts during byte receive - about 8µs
|
// no interrupts during byte receive - about 8µs
|
||||||
cli();
|
cli();
|
||||||
// output pin high - like sending 0xFF
|
// output pin high - like sending 0xFF
|
||||||
WRITE(SD_MOSI_PIN, HIGH);
|
WRITE(MOSI_PIN, HIGH);
|
||||||
|
|
||||||
LOOP_L_N(i, 8) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
WRITE(SD_SCK_PIN, HIGH);
|
WRITE(SCK_PIN, HIGH);
|
||||||
|
|
||||||
nop; // adjust so SCK is nice
|
nop; // adjust so SCK is nice
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
data <<= 1;
|
data <<= 1;
|
||||||
|
|
||||||
if (READ(SD_MISO_PIN)) data |= 1;
|
if (READ(MISO_PIN)) data |= 1;
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
@@ -216,7 +215,7 @@ void spiBegin() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Soft SPI read data
|
// Soft SPI read data
|
||||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
for (uint16_t i = 0; i < nbyte; i++)
|
for (uint16_t i = 0; i < nbyte; i++)
|
||||||
buf[i] = spiRec();
|
buf[i] = spiRec();
|
||||||
}
|
}
|
||||||
@@ -225,11 +224,11 @@ void spiBegin() {
|
|||||||
void spiSend(uint8_t data) {
|
void spiSend(uint8_t data) {
|
||||||
// no interrupts during byte send - about 8µs
|
// no interrupts during byte send - about 8µs
|
||||||
cli();
|
cli();
|
||||||
LOOP_L_N(i, 8) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
WRITE(SD_MOSI_PIN, data & 0x80);
|
WRITE(MOSI_PIN, data & 0x80);
|
||||||
data <<= 1;
|
data <<= 1;
|
||||||
WRITE(SD_SCK_PIN, HIGH);
|
WRITE(SCK_PIN, HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
nop; // hold SCK high for a few ns
|
nop; // hold SCK high for a few ns
|
||||||
@@ -237,13 +236,13 @@ void spiBegin() {
|
|||||||
nop;
|
nop;
|
||||||
nop;
|
nop;
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
|
|
||||||
sei();
|
sei();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Soft SPI send block
|
// Soft SPI send block
|
||||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
spiSend(token);
|
spiSend(token);
|
||||||
for (uint16_t i = 0; i < 512; i++)
|
for (uint16_t i = 0; i < 512; i++)
|
||||||
spiSend(buf[i]);
|
spiSend(buf[i]);
|
792
Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp
Normal file
792
Marlin/src/HAL/HAL_AVR/MarlinSerial.cpp
Normal file
@@ -0,0 +1,792 @@
|
|||||||
|
/**
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MarlinSerial.cpp - Hardware serial library for Wiring
|
||||||
|
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||||
|
*
|
||||||
|
* Modified 23 November 2006 by David A. Mellis
|
||||||
|
* Modified 28 September 2010 by Mark Sproul
|
||||||
|
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
|
||||||
|
* Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
|
||||||
|
* Modified 10 June 2018 by Eduardo José Tagle (See #10991)
|
||||||
|
* Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __AVR__
|
||||||
|
|
||||||
|
// Disable HardwareSerial.cpp to support chips without a UART (Attiny, etc.)
|
||||||
|
|
||||||
|
#include "../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
|
#if !defined(USBCON) && (defined(UBRRH) || defined(UBRR0H) || defined(UBRR1H) || defined(UBRR2H) || defined(UBRR3H))
|
||||||
|
|
||||||
|
#include "MarlinSerial.h"
|
||||||
|
#include "../../MarlinCore.h"
|
||||||
|
|
||||||
|
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_r MarlinSerial<Cfg>::rx_buffer = { 0, 0, { 0 } };
|
||||||
|
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_t MarlinSerial<Cfg>::tx_buffer = { 0 };
|
||||||
|
template<typename Cfg> bool MarlinSerial<Cfg>::_written = false;
|
||||||
|
template<typename Cfg> uint8_t MarlinSerial<Cfg>::xon_xoff_state = MarlinSerial<Cfg>::XON_XOFF_CHAR_SENT | MarlinSerial<Cfg>::XON_CHAR;
|
||||||
|
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_dropped_bytes = 0;
|
||||||
|
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_buffer_overruns = 0;
|
||||||
|
template<typename Cfg> uint8_t MarlinSerial<Cfg>::rx_framing_errors = 0;
|
||||||
|
template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::rx_max_enqueued = 0;
|
||||||
|
|
||||||
|
// A SW memory barrier, to ensure GCC does not overoptimize loops
|
||||||
|
#define sw_barrier() asm volatile("": : :"memory");
|
||||||
|
|
||||||
|
#include "../../feature/emergency_parser.h"
|
||||||
|
|
||||||
|
// "Atomically" read the RX head index value without disabling interrupts:
|
||||||
|
// This MUST be called with RX interrupts enabled, and CAN'T be called
|
||||||
|
// from the RX ISR itself!
|
||||||
|
template<typename Cfg>
|
||||||
|
FORCE_INLINE typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::atomic_read_rx_head() {
|
||||||
|
if (Cfg::RX_SIZE > 256) {
|
||||||
|
// Keep reading until 2 consecutive reads return the same value,
|
||||||
|
// meaning there was no update in-between caused by an interrupt.
|
||||||
|
// This works because serial RX interrupts happen at a slower rate
|
||||||
|
// than successive reads of a variable, so 2 consecutive reads with
|
||||||
|
// the same value means no interrupt updated it.
|
||||||
|
ring_buffer_pos_t vold, vnew = rx_buffer.head;
|
||||||
|
sw_barrier();
|
||||||
|
do {
|
||||||
|
vold = vnew;
|
||||||
|
vnew = rx_buffer.head;
|
||||||
|
sw_barrier();
|
||||||
|
} while (vold != vnew);
|
||||||
|
return vnew;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// With an 8bit index, reads are always atomic. No need for special handling
|
||||||
|
return rx_buffer.head;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
volatile bool MarlinSerial<Cfg>::rx_tail_value_not_stable = false;
|
||||||
|
template<typename Cfg>
|
||||||
|
volatile uint16_t MarlinSerial<Cfg>::rx_tail_value_backup = 0;
|
||||||
|
|
||||||
|
// Set RX tail index, taking into account the RX ISR could interrupt
|
||||||
|
// the write to this variable in the middle - So a backup strategy
|
||||||
|
// is used to ensure reads of the correct values.
|
||||||
|
// -Must NOT be called from the RX ISR -
|
||||||
|
template<typename Cfg>
|
||||||
|
FORCE_INLINE void MarlinSerial<Cfg>::atomic_set_rx_tail(typename MarlinSerial<Cfg>::ring_buffer_pos_t value) {
|
||||||
|
if (Cfg::RX_SIZE > 256) {
|
||||||
|
// Store the new value in the backup
|
||||||
|
rx_tail_value_backup = value;
|
||||||
|
sw_barrier();
|
||||||
|
// Flag we are about to change the true value
|
||||||
|
rx_tail_value_not_stable = true;
|
||||||
|
sw_barrier();
|
||||||
|
// Store the new value
|
||||||
|
rx_buffer.tail = value;
|
||||||
|
sw_barrier();
|
||||||
|
// Signal the new value is completely stored into the value
|
||||||
|
rx_tail_value_not_stable = false;
|
||||||
|
sw_barrier();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
rx_buffer.tail = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the RX tail index, taking into account the read could be
|
||||||
|
// interrupting in the middle of the update of that index value
|
||||||
|
// -Called from the RX ISR -
|
||||||
|
template<typename Cfg>
|
||||||
|
FORCE_INLINE typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::atomic_read_rx_tail() {
|
||||||
|
if (Cfg::RX_SIZE > 256) {
|
||||||
|
// If the true index is being modified, return the backup value
|
||||||
|
if (rx_tail_value_not_stable) return rx_tail_value_backup;
|
||||||
|
}
|
||||||
|
// The true index is stable, return it
|
||||||
|
return rx_buffer.tail;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (called with RX interrupts disabled)
|
||||||
|
template<typename Cfg>
|
||||||
|
FORCE_INLINE void MarlinSerial<Cfg>::store_rxd_char() {
|
||||||
|
|
||||||
|
static EmergencyParser::State emergency_state; // = EP_RESET
|
||||||
|
|
||||||
|
// Get the tail - Nothing can alter its value while this ISR is executing, but there's
|
||||||
|
// a chance that this ISR interrupted the main process while it was updating the index.
|
||||||
|
// The backup mechanism ensures the correct value is always returned.
|
||||||
|
const ring_buffer_pos_t t = atomic_read_rx_tail();
|
||||||
|
|
||||||
|
// Get the head pointer - This ISR is the only one that modifies its value, so it's safe to read here
|
||||||
|
ring_buffer_pos_t h = rx_buffer.head;
|
||||||
|
|
||||||
|
// Get the next element
|
||||||
|
ring_buffer_pos_t i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
||||||
|
|
||||||
|
// This must read the R_UCSRA register before reading the received byte to detect error causes
|
||||||
|
if (Cfg::DROPPED_RX && B_DOR && !++rx_dropped_bytes) --rx_dropped_bytes;
|
||||||
|
if (Cfg::RX_OVERRUNS && B_DOR && !++rx_buffer_overruns) --rx_buffer_overruns;
|
||||||
|
if (Cfg::RX_FRAMING_ERRORS && B_FE && !++rx_framing_errors) --rx_framing_errors;
|
||||||
|
|
||||||
|
// Read the character from the USART
|
||||||
|
uint8_t c = R_UDR;
|
||||||
|
|
||||||
|
if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
|
||||||
|
|
||||||
|
// If the character is to be stored at the index just before the tail
|
||||||
|
// (such that the head would advance to the current tail), the RX FIFO is
|
||||||
|
// full, so don't write the character or advance the head.
|
||||||
|
if (i != t) {
|
||||||
|
rx_buffer.buffer[h] = c;
|
||||||
|
h = i;
|
||||||
|
}
|
||||||
|
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
|
||||||
|
--rx_dropped_bytes;
|
||||||
|
|
||||||
|
if (Cfg::MAX_RX_QUEUED) {
|
||||||
|
// Calculate count of bytes stored into the RX buffer
|
||||||
|
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
||||||
|
|
||||||
|
// Keep track of the maximum count of enqueued bytes
|
||||||
|
NOLESS(rx_max_enqueued, rx_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Cfg::XONOFF) {
|
||||||
|
// If the last char that was sent was an XON
|
||||||
|
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XON_CHAR) {
|
||||||
|
|
||||||
|
// Bytes stored into the RX buffer
|
||||||
|
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
||||||
|
|
||||||
|
// If over 12.5% of RX buffer capacity, send XOFF before running out of
|
||||||
|
// RX buffer space .. 325 bytes @ 250kbits/s needed to let the host react
|
||||||
|
// and stop sending bytes. This translates to 13mS propagation time.
|
||||||
|
if (rx_count >= (Cfg::RX_SIZE) / 8) {
|
||||||
|
|
||||||
|
// At this point, definitely no TX interrupt was executing, since the TX ISR can't be preempted.
|
||||||
|
// Don't enable the TX interrupt here as a means to trigger the XOFF char, because if it happens
|
||||||
|
// to be in the middle of trying to disable the RX interrupt in the main program, eventually the
|
||||||
|
// enabling of the TX interrupt could be undone. The ONLY reliable thing this can do to ensure
|
||||||
|
// the sending of the XOFF char is to send it HERE AND NOW.
|
||||||
|
|
||||||
|
// About to send the XOFF char
|
||||||
|
xon_xoff_state = XOFF_CHAR | XON_XOFF_CHAR_SENT;
|
||||||
|
|
||||||
|
// Wait until the TX register becomes empty and send it - Here there could be a problem
|
||||||
|
// - While waiting for the TX register to empty, the RX register could receive a new
|
||||||
|
// character. This must also handle that situation!
|
||||||
|
while (!B_UDRE) {
|
||||||
|
|
||||||
|
if (B_RXC) {
|
||||||
|
// A char arrived while waiting for the TX buffer to be empty - Receive and process it!
|
||||||
|
|
||||||
|
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
||||||
|
|
||||||
|
// Read the character from the USART
|
||||||
|
c = R_UDR;
|
||||||
|
|
||||||
|
if (Cfg::EMERGENCYPARSER) emergency_parser.update(emergency_state, c);
|
||||||
|
|
||||||
|
// If the character is to be stored at the index just before the tail
|
||||||
|
// (such that the head would advance to the current tail), the FIFO is
|
||||||
|
// full, so don't write the character or advance the head.
|
||||||
|
if (i != t) {
|
||||||
|
rx_buffer.buffer[h] = c;
|
||||||
|
h = i;
|
||||||
|
}
|
||||||
|
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
|
||||||
|
--rx_dropped_bytes;
|
||||||
|
}
|
||||||
|
sw_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
R_UDR = XOFF_CHAR;
|
||||||
|
|
||||||
|
// Clear the TXC bit -- "can be cleared by writing a one to its bit
|
||||||
|
// location". This makes sure flush() won't return until the bytes
|
||||||
|
// actually got written
|
||||||
|
B_TXC = 1;
|
||||||
|
|
||||||
|
// At this point there could be a race condition between the write() function
|
||||||
|
// and this sending of the XOFF char. This interrupt could happen between the
|
||||||
|
// wait to be empty TX buffer loop and the actual write of the character. Since
|
||||||
|
// the TX buffer is full because it's sending the XOFF char, the only way to be
|
||||||
|
// sure the write() function will succeed is to wait for the XOFF char to be
|
||||||
|
// completely sent. Since an extra character could be received during the wait
|
||||||
|
// it must also be handled!
|
||||||
|
while (!B_UDRE) {
|
||||||
|
|
||||||
|
if (B_RXC) {
|
||||||
|
// A char arrived while waiting for the TX buffer to be empty - Receive and process it!
|
||||||
|
|
||||||
|
i = (ring_buffer_pos_t)(h + 1) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
||||||
|
|
||||||
|
// Read the character from the USART
|
||||||
|
c = R_UDR;
|
||||||
|
|
||||||
|
if (Cfg::EMERGENCYPARSER)
|
||||||
|
emergency_parser.update(emergency_state, c);
|
||||||
|
|
||||||
|
// If the character is to be stored at the index just before the tail
|
||||||
|
// (such that the head would advance to the current tail), the FIFO is
|
||||||
|
// full, so don't write the character or advance the head.
|
||||||
|
if (i != t) {
|
||||||
|
rx_buffer.buffer[h] = c;
|
||||||
|
h = i;
|
||||||
|
}
|
||||||
|
else if (Cfg::DROPPED_RX && !++rx_dropped_bytes)
|
||||||
|
--rx_dropped_bytes;
|
||||||
|
}
|
||||||
|
sw_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point everything is ready. The write() function won't
|
||||||
|
// have any issues writing to the UART TX register if it needs to!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store the new head value - The main loop will retry until the value is stable
|
||||||
|
rx_buffer.head = h;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (called with TX irqs disabled)
|
||||||
|
template<typename Cfg>
|
||||||
|
FORCE_INLINE void MarlinSerial<Cfg>::_tx_udr_empty_irq() {
|
||||||
|
if (Cfg::TX_SIZE > 0) {
|
||||||
|
// Read positions
|
||||||
|
uint8_t t = tx_buffer.tail;
|
||||||
|
const uint8_t h = tx_buffer.head;
|
||||||
|
|
||||||
|
if (Cfg::XONOFF) {
|
||||||
|
// If an XON char is pending to be sent, do it now
|
||||||
|
if (xon_xoff_state == XON_CHAR) {
|
||||||
|
|
||||||
|
// Send the character
|
||||||
|
R_UDR = XON_CHAR;
|
||||||
|
|
||||||
|
// clear the TXC bit -- "can be cleared by writing a one to its bit
|
||||||
|
// location". This makes sure flush() won't return until the bytes
|
||||||
|
// actually got written
|
||||||
|
B_TXC = 1;
|
||||||
|
|
||||||
|
// Remember we sent it.
|
||||||
|
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
|
||||||
|
|
||||||
|
// If nothing else to transmit, just disable TX interrupts.
|
||||||
|
if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If nothing to transmit, just disable TX interrupts. This could
|
||||||
|
// happen as the result of the non atomicity of the disabling of RX
|
||||||
|
// interrupts that could end reenabling TX interrupts as a side effect.
|
||||||
|
if (h == t) {
|
||||||
|
B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// There is something to TX, Send the next byte
|
||||||
|
const uint8_t c = tx_buffer.buffer[t];
|
||||||
|
t = (t + 1) & (Cfg::TX_SIZE - 1);
|
||||||
|
R_UDR = c;
|
||||||
|
tx_buffer.tail = t;
|
||||||
|
|
||||||
|
// Clear the TXC bit (by writing a one to its bit location).
|
||||||
|
// Ensures flush() won't return until the bytes are actually written/
|
||||||
|
B_TXC = 1;
|
||||||
|
|
||||||
|
// Disable interrupts if there is nothing to transmit following this byte
|
||||||
|
if (h == t) B_UDRIE = 0; // (Non-atomic, could be reenabled by the main program, but eventually this will succeed)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Public Methods
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::begin(const long baud) {
|
||||||
|
uint16_t baud_setting;
|
||||||
|
bool useU2X = true;
|
||||||
|
|
||||||
|
#if F_CPU == 16000000UL && SERIAL_PORT == 0
|
||||||
|
// Hard-coded exception for compatibility with the bootloader shipped
|
||||||
|
// with the Duemilanove and previous boards, and the firmware on the
|
||||||
|
// 8U2 on the Uno and Mega 2560.
|
||||||
|
if (baud == 57600) useU2X = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
R_UCSRA = 0;
|
||||||
|
if (useU2X) {
|
||||||
|
B_U2X = 1;
|
||||||
|
baud_setting = (F_CPU / 4 / baud - 1) / 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
baud_setting = (F_CPU / 8 / baud - 1) / 2;
|
||||||
|
|
||||||
|
// assign the baud_setting, a.k.a. ubbr (USART Baud Rate Register)
|
||||||
|
R_UBRRH = baud_setting >> 8;
|
||||||
|
R_UBRRL = baud_setting;
|
||||||
|
|
||||||
|
B_RXEN = 1;
|
||||||
|
B_TXEN = 1;
|
||||||
|
B_RXCIE = 1;
|
||||||
|
if (Cfg::TX_SIZE > 0) B_UDRIE = 0;
|
||||||
|
_written = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::end() {
|
||||||
|
B_RXEN = 0;
|
||||||
|
B_TXEN = 0;
|
||||||
|
B_RXCIE = 0;
|
||||||
|
B_UDRIE = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
int MarlinSerial<Cfg>::peek() {
|
||||||
|
const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
|
||||||
|
return h == t ? -1 : rx_buffer.buffer[t];
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
int MarlinSerial<Cfg>::read() {
|
||||||
|
const ring_buffer_pos_t h = atomic_read_rx_head();
|
||||||
|
|
||||||
|
// Read the tail. Main thread owns it, so it is safe to directly read it
|
||||||
|
ring_buffer_pos_t t = rx_buffer.tail;
|
||||||
|
|
||||||
|
// If nothing to read, return now
|
||||||
|
if (h == t) return -1;
|
||||||
|
|
||||||
|
// Get the next char
|
||||||
|
const int v = rx_buffer.buffer[t];
|
||||||
|
t = (ring_buffer_pos_t)(t + 1) & (Cfg::RX_SIZE - 1);
|
||||||
|
|
||||||
|
// Advance tail - Making sure the RX ISR will always get an stable value, even
|
||||||
|
// if it interrupts the writing of the value of that variable in the middle.
|
||||||
|
atomic_set_rx_tail(t);
|
||||||
|
|
||||||
|
if (Cfg::XONOFF) {
|
||||||
|
// If the XOFF char was sent, or about to be sent...
|
||||||
|
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
|
||||||
|
// Get count of bytes in the RX buffer
|
||||||
|
const ring_buffer_pos_t rx_count = (ring_buffer_pos_t)(h - t) & (ring_buffer_pos_t)(Cfg::RX_SIZE - 1);
|
||||||
|
if (rx_count < (Cfg::RX_SIZE) / 10) {
|
||||||
|
if (Cfg::TX_SIZE > 0) {
|
||||||
|
// Signal we want an XON character to be sent.
|
||||||
|
xon_xoff_state = XON_CHAR;
|
||||||
|
// Enable TX ISR. Non atomic, but it will eventually enable them
|
||||||
|
B_UDRIE = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If not using TX interrupts, we must send the XON char now
|
||||||
|
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
|
||||||
|
while (!B_UDRE) sw_barrier();
|
||||||
|
R_UDR = XON_CHAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::available() {
|
||||||
|
const ring_buffer_pos_t h = atomic_read_rx_head(), t = rx_buffer.tail;
|
||||||
|
return (ring_buffer_pos_t)(Cfg::RX_SIZE + h - t) & (Cfg::RX_SIZE - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::flush() {
|
||||||
|
|
||||||
|
// Set the tail to the head:
|
||||||
|
// - Read the RX head index in a safe way. (See atomic_read_rx_head.)
|
||||||
|
// - Set the tail, making sure the RX ISR will always get a stable value, even
|
||||||
|
// if it interrupts the writing of the value of that variable in the middle.
|
||||||
|
atomic_set_rx_tail(atomic_read_rx_head());
|
||||||
|
|
||||||
|
if (Cfg::XONOFF) {
|
||||||
|
// If the XOFF char was sent, or about to be sent...
|
||||||
|
if ((xon_xoff_state & XON_XOFF_CHAR_MASK) == XOFF_CHAR) {
|
||||||
|
if (Cfg::TX_SIZE > 0) {
|
||||||
|
// Signal we want an XON character to be sent.
|
||||||
|
xon_xoff_state = XON_CHAR;
|
||||||
|
// Enable TX ISR. Non atomic, but it will eventually enable it.
|
||||||
|
B_UDRIE = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// If not using TX interrupts, we must send the XON char now
|
||||||
|
xon_xoff_state = XON_CHAR | XON_XOFF_CHAR_SENT;
|
||||||
|
while (!B_UDRE) sw_barrier();
|
||||||
|
R_UDR = XON_CHAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::write(const uint8_t c) {
|
||||||
|
if (Cfg::TX_SIZE == 0) {
|
||||||
|
|
||||||
|
_written = true;
|
||||||
|
while (!B_UDRE) sw_barrier();
|
||||||
|
R_UDR = c;
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
_written = true;
|
||||||
|
|
||||||
|
// If the TX interrupts are disabled and the data register
|
||||||
|
// is empty, just write the byte to the data register and
|
||||||
|
// be done. This shortcut helps significantly improve the
|
||||||
|
// effective datarate at high (>500kbit/s) bitrates, where
|
||||||
|
// interrupt overhead becomes a slowdown.
|
||||||
|
// Yes, there is a race condition between the sending of the
|
||||||
|
// XOFF char at the RX ISR, but it is properly handled there
|
||||||
|
if (!B_UDRIE && B_UDRE) {
|
||||||
|
R_UDR = c;
|
||||||
|
|
||||||
|
// clear the TXC bit -- "can be cleared by writing a one to its bit
|
||||||
|
// location". This makes sure flush() won't return until the bytes
|
||||||
|
// actually got written
|
||||||
|
B_TXC = 1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
||||||
|
|
||||||
|
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||||
|
if (!ISRS_ENABLED()) {
|
||||||
|
|
||||||
|
// Make room by polling if it is possible to transmit, and do so!
|
||||||
|
while (i == tx_buffer.tail) {
|
||||||
|
|
||||||
|
// If we can transmit another byte, do it.
|
||||||
|
if (B_UDRE) _tx_udr_empty_irq();
|
||||||
|
|
||||||
|
// Make sure compiler rereads tx_buffer.tail
|
||||||
|
sw_barrier();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Interrupts are enabled, just wait until there is space
|
||||||
|
while (i == tx_buffer.tail) sw_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store new char. head is always safe to move
|
||||||
|
tx_buffer.buffer[tx_buffer.head] = c;
|
||||||
|
tx_buffer.head = i;
|
||||||
|
|
||||||
|
// Enable TX ISR - Non atomic, but it will eventually enable TX ISR
|
||||||
|
B_UDRIE = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::flushTX() {
|
||||||
|
|
||||||
|
if (Cfg::TX_SIZE == 0) {
|
||||||
|
// No bytes written, no need to flush. This special case is needed since there's
|
||||||
|
// no way to force the TXC (transmit complete) bit to 1 during initialization.
|
||||||
|
if (!_written) return;
|
||||||
|
|
||||||
|
// Wait until everything was transmitted
|
||||||
|
while (!B_TXC) sw_barrier();
|
||||||
|
|
||||||
|
// At this point nothing is queued anymore (DRIE is disabled) and
|
||||||
|
// the hardware finished transmission (TXC is set).
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
|
||||||
|
// No bytes written, no need to flush. This special case is needed since there's
|
||||||
|
// no way to force the TXC (transmit complete) bit to 1 during initialization.
|
||||||
|
if (!_written) return;
|
||||||
|
|
||||||
|
// If global interrupts are disabled (as the result of being called from an ISR)...
|
||||||
|
if (!ISRS_ENABLED()) {
|
||||||
|
|
||||||
|
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
|
||||||
|
while (tx_buffer.head != tx_buffer.tail || !B_TXC) {
|
||||||
|
|
||||||
|
// If there is more space, send an extra character
|
||||||
|
if (B_UDRE) _tx_udr_empty_irq();
|
||||||
|
|
||||||
|
sw_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Wait until everything was transmitted
|
||||||
|
while (tx_buffer.head != tx_buffer.tail || !B_TXC) sw_barrier();
|
||||||
|
}
|
||||||
|
|
||||||
|
// At this point nothing is queued anymore (DRIE is disabled) and
|
||||||
|
// the hardware finished transmission (TXC is set).
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports from print.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(char c, int base) {
|
||||||
|
print((long)c, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(unsigned char b, int base) {
|
||||||
|
print((unsigned long)b, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(int n, int base) {
|
||||||
|
print((long)n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(unsigned int n, int base) {
|
||||||
|
print((unsigned long)n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(long n, int base) {
|
||||||
|
if (base == 0) write(n);
|
||||||
|
else if (base == 10) {
|
||||||
|
if (n < 0) { print('-'); n = -n; }
|
||||||
|
printNumber(n, 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(unsigned long n, int base) {
|
||||||
|
if (base == 0) write(n);
|
||||||
|
else printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(double n, int digits) {
|
||||||
|
printFloat(n, digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println() {
|
||||||
|
print('\r');
|
||||||
|
print('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(const String& s) {
|
||||||
|
print(s);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(const char c[]) {
|
||||||
|
print(c);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(char c, int base) {
|
||||||
|
print(c, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(unsigned char b, int base) {
|
||||||
|
print(b, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(int n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(unsigned int n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(long n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(unsigned long n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(double n, int digits) {
|
||||||
|
print(n, digits);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Methods
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::printNumber(unsigned long n, uint8_t base) {
|
||||||
|
if (n) {
|
||||||
|
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
|
||||||
|
int8_t i = 0;
|
||||||
|
while (n) {
|
||||||
|
buf[i++] = n % base;
|
||||||
|
n /= base;
|
||||||
|
}
|
||||||
|
while (i--)
|
||||||
|
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::printFloat(double number, uint8_t digits) {
|
||||||
|
// Handle negative numbers
|
||||||
|
if (number < 0.0) {
|
||||||
|
print('-');
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||||
|
double rounding = 0.5;
|
||||||
|
for (uint8_t i = 0; i < digits; ++i) rounding *= 0.1;
|
||||||
|
number += rounding;
|
||||||
|
|
||||||
|
// Extract the integer part of the number and print it
|
||||||
|
unsigned long int_part = (unsigned long)number;
|
||||||
|
double remainder = number - (double)int_part;
|
||||||
|
print(int_part);
|
||||||
|
|
||||||
|
// Print the decimal point, but only if there are digits beyond
|
||||||
|
if (digits) {
|
||||||
|
print('.');
|
||||||
|
// Extract digits from the remainder one at a time
|
||||||
|
while (digits--) {
|
||||||
|
remainder *= 10.0;
|
||||||
|
int toPrint = int(remainder);
|
||||||
|
print(toPrint);
|
||||||
|
remainder -= toPrint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hookup ISR handlers
|
||||||
|
ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)) {
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::store_rxd_char();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)) {
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::_tx_udr_empty_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preinstantiate
|
||||||
|
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>;
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||||
|
|
||||||
|
#ifdef SERIAL_PORT_2
|
||||||
|
|
||||||
|
// Hookup ISR handlers
|
||||||
|
ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_RX_vect)) {
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::store_rxd_char();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(SERIAL_REGNAME(USART,SERIAL_PORT_2,_UDRE_vect)) {
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::_tx_udr_empty_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preinstantiate
|
||||||
|
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>;
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // !USBCON && (UBRRH || UBRR0H || UBRR1H || UBRR2H || UBRR3H)
|
||||||
|
|
||||||
|
#ifdef INTERNAL_SERIAL_PORT
|
||||||
|
|
||||||
|
ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_RX_vect)) {
|
||||||
|
MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>>::store_rxd_char();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(SERIAL_REGNAME(USART,INTERNAL_SERIAL_PORT,_UDRE_vect)) {
|
||||||
|
MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>>::_tx_udr_empty_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preinstantiate
|
||||||
|
template class MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>>;
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>> internalSerial;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DGUS_SERIAL_PORT
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
|
||||||
|
const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
|
||||||
|
h = tx_buffer.head; // next pos for queue.
|
||||||
|
int ret = t - h - 1;
|
||||||
|
if (ret < 0) ret += Cfg::TX_SIZE + 1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_RX_vect)) {
|
||||||
|
MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>>::store_rxd_char();
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(SERIAL_REGNAME(USART,DGUS_SERIAL_PORT,_UDRE_vect)) {
|
||||||
|
MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>>::_tx_udr_empty_irq();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preinstantiate
|
||||||
|
template class MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>>;
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>> internalDgusSerial;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// For AT90USB targets use the UART for BT interfacing
|
||||||
|
#if defined(USBCON) && ENABLED(BLUETOOTH)
|
||||||
|
HardwareSerial bluetoothSerial;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // __AVR__
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -31,10 +31,9 @@
|
|||||||
* Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
|
* Templatized 01 October 2018 by Eduardo José Tagle to allow multiple instances
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <WString.h>
|
#include "../shared/MarlinSerial.h"
|
||||||
|
|
||||||
#include "../../inc/MarlinConfigPre.h"
|
#include <WString.h>
|
||||||
#include "../../core/serial_hook.h"
|
|
||||||
|
|
||||||
#ifndef SERIAL_PORT
|
#ifndef SERIAL_PORT
|
||||||
#define SERIAL_PORT 0
|
#define SERIAL_PORT 0
|
||||||
@@ -49,11 +48,11 @@
|
|||||||
|
|
||||||
// These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
|
// These are macros to build serial port register names for the selected SERIAL_PORT (C preprocessor
|
||||||
// requires two levels of indirection to expand macro values properly)
|
// requires two levels of indirection to expand macro values properly)
|
||||||
#define SERIAL_REGNAME(registerbase,number,suffix) _SERIAL_REGNAME(registerbase,number,suffix)
|
#define SERIAL_REGNAME(registerbase,number,suffix) SERIAL_REGNAME_INTERNAL(registerbase,number,suffix)
|
||||||
#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary
|
#if SERIAL_PORT == 0 && (!defined(UBRR0H) || !defined(UDR0)) // use un-numbered registers if necessary
|
||||||
#define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##suffix
|
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##suffix
|
||||||
#else
|
#else
|
||||||
#define _SERIAL_REGNAME(registerbase,number,suffix) registerbase##number##suffix
|
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Registers used by MarlinSerial class (expanded depending on selected serial port)
|
// Registers used by MarlinSerial class (expanded depending on selected serial port)
|
||||||
@@ -136,6 +135,10 @@
|
|||||||
UART_DECL(3);
|
UART_DECL(3);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define DEC 10
|
||||||
|
#define HEX 16
|
||||||
|
#define OCT 8
|
||||||
|
#define BIN 2
|
||||||
#define BYTE 0
|
#define BYTE 0
|
||||||
|
|
||||||
// Templated type selector
|
// Templated type selector
|
||||||
@@ -199,30 +202,58 @@
|
|||||||
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
|
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
|
||||||
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
|
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
FORCE_INLINE static void store_rxd_char();
|
FORCE_INLINE static void store_rxd_char();
|
||||||
FORCE_INLINE static void _tx_udr_empty_irq();
|
FORCE_INLINE static void _tx_udr_empty_irq();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void begin(const long);
|
MarlinSerial() {};
|
||||||
static void end();
|
static void begin(const long);
|
||||||
static int peek();
|
static void end();
|
||||||
static int read();
|
static int peek();
|
||||||
static void flush();
|
static int read();
|
||||||
static ring_buffer_pos_t available();
|
static void flush();
|
||||||
static void write(const uint8_t c);
|
static ring_buffer_pos_t available();
|
||||||
static void flushTX();
|
static void write(const uint8_t c);
|
||||||
#if HAS_DGUS_LCD
|
static void flushTX();
|
||||||
static ring_buffer_pos_t get_tx_buffer_free();
|
#ifdef DGUS_SERIAL_PORT
|
||||||
#endif
|
static ring_buffer_pos_t get_tx_buffer_free();
|
||||||
|
#endif
|
||||||
|
|
||||||
enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
|
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
|
||||||
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
|
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
|
||||||
|
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
|
||||||
|
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
|
||||||
|
|
||||||
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
|
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
|
||||||
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
|
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
|
||||||
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
|
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
|
||||||
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
|
FORCE_INLINE static void print(const char* str) { write(str); }
|
||||||
|
|
||||||
|
static void print(char, int = BYTE);
|
||||||
|
static void print(unsigned char, int = BYTE);
|
||||||
|
static void print(int, int = DEC);
|
||||||
|
static void print(unsigned int, int = DEC);
|
||||||
|
static void print(long, int = DEC);
|
||||||
|
static void print(unsigned long, int = DEC);
|
||||||
|
static void print(double, int = 2);
|
||||||
|
|
||||||
|
static void println(const String& s);
|
||||||
|
static void println(const char[]);
|
||||||
|
static void println(char, int = BYTE);
|
||||||
|
static void println(unsigned char, int = BYTE);
|
||||||
|
static void println(int, int = DEC);
|
||||||
|
static void println(unsigned int, int = DEC);
|
||||||
|
static void println(long, int = DEC);
|
||||||
|
static void println(unsigned long, int = DEC);
|
||||||
|
static void println(double, int = 2);
|
||||||
|
static void println();
|
||||||
|
operator bool() { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void printNumber(unsigned long, const uint8_t);
|
||||||
|
static void printFloat(double, uint8_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <uint8_t serial>
|
template <uint8_t serial>
|
||||||
@@ -230,68 +261,58 @@
|
|||||||
static constexpr int PORT = serial;
|
static constexpr int PORT = serial;
|
||||||
static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE;
|
static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE;
|
||||||
static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE;
|
static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE;
|
||||||
static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF);
|
static constexpr bool XONOFF = bSERIAL_XON_XOFF;
|
||||||
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
|
static constexpr bool EMERGENCYPARSER = bEMERGENCY_PARSER;
|
||||||
static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX);
|
static constexpr bool DROPPED_RX = bSERIAL_STATS_DROPPED_RX;
|
||||||
static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
|
static constexpr bool RX_OVERRUNS = bSERIAL_STATS_RX_BUFFER_OVERRUNS;
|
||||||
static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
|
static constexpr bool RX_FRAMING_ERRORS = bSERIAL_STATS_RX_FRAMING_ERRORS;
|
||||||
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
|
static constexpr bool MAX_RX_QUEUED = bSERIAL_STATS_MAX_RX_QUEUED;
|
||||||
};
|
};
|
||||||
|
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||||
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT1;
|
|
||||||
extern MSerialT1 customizedSerial1;
|
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_2
|
#ifdef SERIAL_PORT_2
|
||||||
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
|
|
||||||
extern MSerialT2 customizedSerial2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_3
|
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||||
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> > > MSerialT3;
|
|
||||||
extern MSerialT3 customizedSerial3;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // !USBCON
|
#endif // !USBCON
|
||||||
|
|
||||||
#ifdef MMU2_SERIAL_PORT
|
#ifdef INTERNAL_SERIAL_PORT
|
||||||
template <uint8_t serial>
|
template <uint8_t serial>
|
||||||
struct MMU2SerialCfg {
|
struct MarlinInternalSerialCfg {
|
||||||
static constexpr int PORT = serial;
|
static constexpr int PORT = serial;
|
||||||
static constexpr unsigned int RX_SIZE = 32;
|
static constexpr unsigned int RX_SIZE = 32;
|
||||||
static constexpr unsigned int TX_SIZE = 32;
|
static constexpr unsigned int TX_SIZE = 32;
|
||||||
static constexpr bool XONOFF = false;
|
static constexpr bool XONOFF = false;
|
||||||
static constexpr bool EMERGENCYPARSER = false;
|
static constexpr bool EMERGENCYPARSER = false;
|
||||||
static constexpr bool DROPPED_RX = false;
|
static constexpr bool DROPPED_RX = false;
|
||||||
|
static constexpr bool RX_OVERRUNS = false;
|
||||||
static constexpr bool RX_FRAMING_ERRORS = false;
|
static constexpr bool RX_FRAMING_ERRORS = false;
|
||||||
static constexpr bool MAX_RX_QUEUED = false;
|
static constexpr bool MAX_RX_QUEUED = false;
|
||||||
static constexpr bool RX_OVERRUNS = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Serial1Class< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialMMU2;
|
extern MarlinSerial<MarlinInternalSerialCfg<INTERNAL_SERIAL_PORT>> internalSerial;
|
||||||
extern MSerialMMU2 mmuSerial;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef LCD_SERIAL_PORT
|
#ifdef DGUS_SERIAL_PORT
|
||||||
|
|
||||||
template <uint8_t serial>
|
template <uint8_t serial>
|
||||||
struct LCDSerialCfg {
|
struct MarlinInternalSerialCfg {
|
||||||
static constexpr int PORT = serial;
|
static constexpr int PORT = serial;
|
||||||
static constexpr unsigned int RX_SIZE = TERN(HAS_DGUS_LCD, DGUS_RX_BUFFER_SIZE, 64);
|
static constexpr unsigned int RX_SIZE = 128;
|
||||||
static constexpr unsigned int TX_SIZE = TERN(HAS_DGUS_LCD, DGUS_TX_BUFFER_SIZE, 128);
|
static constexpr unsigned int TX_SIZE = 48;
|
||||||
static constexpr bool XONOFF = false;
|
static constexpr bool XONOFF = false;
|
||||||
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
|
static constexpr bool EMERGENCYPARSER = false;
|
||||||
static constexpr bool DROPPED_RX = false;
|
static constexpr bool DROPPED_RX = false;
|
||||||
|
static constexpr bool RX_OVERRUNS = bDGUS_SERIAL_STATS_RX_BUFFER_OVERRUNS;
|
||||||
static constexpr bool RX_FRAMING_ERRORS = false;
|
static constexpr bool RX_FRAMING_ERRORS = false;
|
||||||
static constexpr bool MAX_RX_QUEUED = false;
|
static constexpr bool MAX_RX_QUEUED = false;
|
||||||
static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Serial1Class< MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> > > MSerialLCD;
|
extern MarlinSerial<MarlinInternalSerialCfg<DGUS_SERIAL_PORT>> internalDgusSerial;
|
||||||
extern MSerialLCD lcdSerial;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Use the UART for Bluetooth in AT90USB configurations
|
// Use the UART for Bluetooth in AT90USB configurations
|
||||||
#if defined(USBCON) && ENABLED(BLUETOOTH)
|
#if defined(USBCON) && ENABLED(BLUETOOTH)
|
||||||
typedef Serial1Class<HardwareSerial> MSerialBT;
|
extern HardwareSerial bluetoothSerial;
|
||||||
extern MSerialBT bluetoothSerial;
|
|
||||||
#endif
|
#endif
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -48,6 +48,7 @@
|
|||||||
* readMicroseconds() - Get the last-written servo pulse width in microseconds.
|
* readMicroseconds() - Get the last-written servo pulse width in microseconds.
|
||||||
* attached() - Return true if a servo is attached.
|
* attached() - Return true if a servo is attached.
|
||||||
* detach() - Stop an attached servo from pulsing its i/o pin.
|
* detach() - Stop an attached servo from pulsing its i/o pin.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
@@ -58,6 +59,7 @@
|
|||||||
|
|
||||||
#include <avr/interrupt.h>
|
#include <avr/interrupt.h>
|
||||||
|
|
||||||
|
#include "../shared/Marduino.h"
|
||||||
#include "../shared/servo.h"
|
#include "../shared/servo.h"
|
||||||
#include "../shared/servo_private.h"
|
#include "../shared/servo_private.h"
|
||||||
|
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -59,12 +59,10 @@
|
|||||||
// Say which 16 bit timers can be used and in what order
|
// Say which 16 bit timers can be used and in what order
|
||||||
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#if defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
||||||
//#define _useTimer1
|
//#define _useTimer1
|
||||||
|
#define _useTimer3
|
||||||
#define _useTimer4
|
#define _useTimer4
|
||||||
#if NUM_SERVOS > SERVOS_PER_TIMER
|
#if !HAS_MOTOR_CURRENT_PWM
|
||||||
#define _useTimer3
|
#define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos.
|
||||||
#if !HAS_MOTOR_CURRENT_PWM && SERVOS > 2 * SERVOS_PER_TIMER
|
|
||||||
#define _useTimer5 // Timer 5 is used for motor current PWM and can't be used for servos.
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#elif defined(__AVR_ATmega32U4__)
|
#elif defined(__AVR_ATmega32U4__)
|
||||||
#define _useTimer3
|
#define _useTimer3
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -124,7 +124,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(X_MAX_PIN);
|
_ATTACH(X_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(X_MAX_PIN);
|
pciSetup(X_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -132,7 +132,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(X_MIN_PIN);
|
_ATTACH(X_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(X_MIN_PIN);
|
pciSetup(X_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -140,7 +140,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Y_MAX_PIN);
|
_ATTACH(Y_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(Y_MAX_PIN);
|
pciSetup(Y_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -148,7 +148,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Y_MIN_PIN);
|
_ATTACH(Y_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(Y_MIN_PIN);
|
pciSetup(Y_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -156,7 +156,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z_MAX_PIN);
|
_ATTACH(Z_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(Z_MAX_PIN);
|
pciSetup(Z_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -164,60 +164,15 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z_MIN_PIN);
|
_ATTACH(Z_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(Z_MIN_PIN);
|
pciSetup(Z_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if HAS_I_MAX
|
|
||||||
#if (digitalPinToInterrupt(I_MAX_PIN) != NOT_AN_INTERRUPT)
|
|
||||||
_ATTACH(I_MAX_PIN);
|
|
||||||
#else
|
|
||||||
static_assert(digitalPinHasPCICR(I_MAX_PIN), "I_MAX_PIN is not interrupt-capable");
|
|
||||||
pciSetup(I_MAX_PIN);
|
|
||||||
#endif
|
|
||||||
#elif HAS_I_MIN
|
|
||||||
#if (digitalPinToInterrupt(I_MIN_PIN) != NOT_AN_INTERRUPT)
|
|
||||||
_ATTACH(I_MIN_PIN);
|
|
||||||
#else
|
|
||||||
static_assert(digitalPinHasPCICR(I_MIN_PIN), "I_MIN_PIN is not interrupt-capable");
|
|
||||||
pciSetup(I_MIN_PIN);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if HAS_J_MAX
|
|
||||||
#if (digitalPinToInterrupt(J_MAX_PIN) != NOT_AN_INTERRUPT)
|
|
||||||
_ATTACH(J_MAX_PIN);
|
|
||||||
#else
|
|
||||||
static_assert(digitalPinHasPCICR(J_MAX_PIN), "J_MAX_PIN is not interrupt-capable");
|
|
||||||
pciSetup(J_MAX_PIN);
|
|
||||||
#endif
|
|
||||||
#elif HAS_J_MIN
|
|
||||||
#if (digitalPinToInterrupt(J_MIN_PIN) != NOT_AN_INTERRUPT)
|
|
||||||
_ATTACH(J_MIN_PIN);
|
|
||||||
#else
|
|
||||||
static_assert(digitalPinHasPCICR(J_MIN_PIN), "J_MIN_PIN is not interrupt-capable");
|
|
||||||
pciSetup(J_MIN_PIN);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if HAS_K_MAX
|
|
||||||
#if (digitalPinToInterrupt(K_MAX_PIN) != NOT_AN_INTERRUPT)
|
|
||||||
_ATTACH(K_MAX_PIN);
|
|
||||||
#else
|
|
||||||
static_assert(digitalPinHasPCICR(K_MAX_PIN), "K_MAX_PIN is not interrupt-capable");
|
|
||||||
pciSetup(K_MAX_PIN);
|
|
||||||
#endif
|
|
||||||
#elif HAS_K_MIN
|
|
||||||
#if (digitalPinToInterrupt(K_MIN_PIN) != NOT_AN_INTERRUPT)
|
|
||||||
_ATTACH(K_MIN_PIN);
|
|
||||||
#else
|
|
||||||
static_assert(digitalPinHasPCICR(K_MIN_PIN), "K_MIN_PIN is not interrupt-capable");
|
|
||||||
pciSetup(K_MIN_PIN);
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#if HAS_X2_MAX
|
#if HAS_X2_MAX
|
||||||
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(X2_MAX_PIN);
|
_ATTACH(X2_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(X2_MAX_PIN);
|
pciSetup(X2_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -225,7 +180,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(X2_MIN_PIN);
|
_ATTACH(X2_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(X2_MIN_PIN);
|
pciSetup(X2_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -233,7 +188,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Y2_MAX_PIN);
|
_ATTACH(Y2_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(Y2_MAX_PIN);
|
pciSetup(Y2_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -241,7 +196,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Y2_MIN_PIN);
|
_ATTACH(Y2_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(Y2_MIN_PIN);
|
pciSetup(Y2_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -249,7 +204,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z2_MAX_PIN);
|
_ATTACH(Z2_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(Z2_MAX_PIN);
|
pciSetup(Z2_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -257,7 +212,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z2_MIN_PIN);
|
_ATTACH(Z2_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(Z2_MIN_PIN);
|
pciSetup(Z2_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -265,7 +220,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z3_MAX_PIN);
|
_ATTACH(Z3_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(Z3_MAX_PIN);
|
pciSetup(Z3_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -273,7 +228,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z3_MIN_PIN);
|
_ATTACH(Z3_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(Z3_MIN_PIN);
|
pciSetup(Z3_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -281,7 +236,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z4_MAX_PIN);
|
_ATTACH(Z4_MAX_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable");
|
||||||
pciSetup(Z4_MAX_PIN);
|
pciSetup(Z4_MAX_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -289,7 +244,7 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z4_MIN_PIN);
|
_ATTACH(Z4_MIN_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable");
|
||||||
pciSetup(Z4_MIN_PIN);
|
pciSetup(Z4_MIN_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
@@ -297,9 +252,10 @@ void setup_endstop_interrupts() {
|
|||||||
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
|
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
|
||||||
_ATTACH(Z_MIN_PROBE_PIN);
|
_ATTACH(Z_MIN_PROBE_PIN);
|
||||||
#else
|
#else
|
||||||
static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
|
static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
|
||||||
pciSetup(Z_MIN_PROBE_PIN);
|
pciSetup(Z_MIN_PROBE_PIN);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
|
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
|
||||||
}
|
}
|
@@ -16,14 +16,14 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
|
|
||||||
#include "../../inc/MarlinConfigPre.h"
|
#include "../../inc/MarlinConfigPre.h"
|
||||||
|
|
||||||
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
|
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
|
||||||
|
|
||||||
#include "HAL.h"
|
#include "HAL.h"
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
|
|||||||
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
|
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
|
||||||
|
|
||||||
// loop over prescaler values
|
// loop over prescaler values
|
||||||
LOOP_S_L_N(i, 1, 8) {
|
for (uint8_t i = 1; i < 8; i++) {
|
||||||
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
|
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
|
||||||
if (timer.n == 2) {
|
if (timer.n == 2) {
|
||||||
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
|
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
|
||||||
@@ -185,8 +185,8 @@ void set_pwm_frequency(const pin_t pin, int f_desired) {
|
|||||||
res_temp_phase_correct = rtf / 2;
|
res_temp_phase_correct = rtf / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIMIT(res_temp_fast, 1U, size);
|
LIMIT(res_temp_fast, 1u, size);
|
||||||
LIMIT(res_temp_phase_correct, 1U, size);
|
LIMIT(res_temp_phase_correct, 1u, size);
|
||||||
// Calculate frequencies of test prescaler and resolution values
|
// Calculate frequencies of test prescaler and resolution values
|
||||||
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
|
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
|
||||||
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
|
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
|
||||||
@@ -274,9 +274,9 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
|
|||||||
else
|
else
|
||||||
top = *timer.ICRn; // top = ICRn
|
top = *timer.ICRn; // top = ICRn
|
||||||
|
|
||||||
_SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top) / float(v_size)); // Scale 8/16-bit v to top value
|
_SET_OCRnQ(timer.OCRnQ, timer.q, v * float(top / v_size)); // Scale 8/16-bit v to top value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // NEEDS_HARDWARE_PWM
|
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
|
||||||
#endif // __AVR__
|
#endif // __AVR__
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -234,55 +234,5 @@ uint8_t extDigitalRead(const int8_t pin) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/**
|
|
||||||
* Set Timer 5 PWM frequency in Hz, from 3.8Hz up to ~16MHz
|
|
||||||
* with a minimum resolution of 100 steps.
|
|
||||||
*
|
|
||||||
* DC values -1.0 to 1.0. Negative duty cycle inverts the pulse.
|
|
||||||
*/
|
|
||||||
uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb, const float dcc) {
|
|
||||||
float count = 0;
|
|
||||||
if (hz > 0 && (dca || dcb || dcc)) {
|
|
||||||
count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq.
|
|
||||||
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5KHz (>31)
|
|
||||||
|
|
||||||
if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); }
|
|
||||||
else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); }
|
|
||||||
else if (count >= 255. * 8.) { prescaler = 64; SET_CS(5, PRESCALER_64); }
|
|
||||||
else if (count >= 255.) { prescaler = 8; SET_CS(5, PRESCALER_8); }
|
|
||||||
else { prescaler = 1; SET_CS(5, PRESCALER_1); }
|
|
||||||
|
|
||||||
count /= float(prescaler);
|
|
||||||
const float pwm_top = round(count); // Get the rounded count
|
|
||||||
|
|
||||||
ICR5 = (uint16_t)pwm_top - 1; // Subtract 1 for TOP
|
|
||||||
OCR5A = pwm_top * ABS(dca); // Update and scale DCs
|
|
||||||
OCR5B = pwm_top * ABS(dcb);
|
|
||||||
OCR5C = pwm_top * ABS(dcc);
|
|
||||||
_SET_COM(5, A, dca ? (dca < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL); // Set compare modes
|
|
||||||
_SET_COM(5, B, dcb ? (dcb < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL);
|
|
||||||
_SET_COM(5, C, dcc ? (dcc < 0 ? COM_SET_CLEAR : COM_CLEAR_SET) : COM_NORMAL);
|
|
||||||
|
|
||||||
SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP
|
|
||||||
|
|
||||||
//SERIAL_ECHOLNPGM("Timer 5 Settings:");
|
|
||||||
//SERIAL_ECHOLNPGM(" Prescaler=", prescaler);
|
|
||||||
//SERIAL_ECHOLNPGM(" TOP=", ICR5);
|
|
||||||
//SERIAL_ECHOLNPGM(" OCR5A=", OCR5A);
|
|
||||||
//SERIAL_ECHOLNPGM(" OCR5B=", OCR5B);
|
|
||||||
//SERIAL_ECHOLNPGM(" OCR5C=", OCR5C);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Restore the default for Timer 5
|
|
||||||
SET_WGM(5, PWM_PC_8); // PWM 8-bit (Phase Correct)
|
|
||||||
SET_COMS(5, NORMAL, NORMAL, NORMAL); // Do nothing
|
|
||||||
SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250KHz
|
|
||||||
OCR5A = OCR5B = OCR5C = 0;
|
|
||||||
}
|
|
||||||
return round(count);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // FASTIO_EXT_START
|
#endif // FASTIO_EXT_START
|
||||||
#endif // __AVR__
|
#endif // __AVR__
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -29,17 +29,11 @@
|
|||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
||||||
#if defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__)
|
#define AVR_AT90USB1286_FAMILY (defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1286P__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB646P__) || defined(__AVR_AT90USB647__))
|
||||||
#define AVR_AT90USB1286_FAMILY 1
|
#define AVR_ATmega1284_FAMILY (defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__))
|
||||||
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
|
#define AVR_ATmega2560_FAMILY (defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__))
|
||||||
#define AVR_ATmega1284_FAMILY 1
|
#define AVR_ATmega2561_FAMILY (defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__))
|
||||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
|
#define AVR_ATmega328_FAMILY (defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__))
|
||||||
#define AVR_ATmega2560_FAMILY 1
|
|
||||||
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
|
|
||||||
#define AVR_ATmega2561_FAMILY 1
|
|
||||||
#elif defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
|
|
||||||
#define AVR_ATmega328_FAMILY 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include Ports and Functions
|
* Include Ports and Functions
|
||||||
@@ -63,7 +57,7 @@
|
|||||||
*
|
*
|
||||||
* Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
|
* Now you can simply SET_OUTPUT(PIN); WRITE(PIN, HIGH); WRITE(PIN, LOW);
|
||||||
*
|
*
|
||||||
* Why double up on these macros? see https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _READ(IO) TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN)
|
#define _READ(IO) TEST(DIO ## IO ## _RPORT, DIO ## IO ## _PIN)
|
||||||
@@ -104,9 +98,9 @@
|
|||||||
|
|
||||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||||
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
|
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _WRITE(IO, HIGH); }while(0)
|
||||||
#define SET_INPUT_PULLDOWN SET_INPUT
|
|
||||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||||
#define SET_PWM SET_OUTPUT
|
|
||||||
|
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||||
|
|
||||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||||
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
||||||
@@ -284,8 +278,8 @@ enum ClockSource2 : char {
|
|||||||
* PWM availability macros
|
* PWM availability macros
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Determine which hardware PWMs are already in use
|
// Determine which harware PWMs are already in use
|
||||||
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN || P == COOLER_AUTO_FAN_PIN)
|
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN)
|
||||||
#if PIN_EXISTS(CONTROLLER_FAN)
|
#if PIN_EXISTS(CONTROLLER_FAN)
|
||||||
#define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN)
|
#define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN)
|
||||||
#else
|
#else
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
*
|
*
|
||||||
* Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 | 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100
|
* Hardware Pin : 02 03 06 07 01 05 15 16 17 18 23 24 25 26 64 63 13 12 46 45 44 43 78 77 76 75 74 73 72 71 60 59 58 57 56 55 54 53 50 70 52 51 42 41 40 39 38 37 36 35 22 21 20 19 97 96 95 94 93 92 91 90 89 88 87 86 85 84 83 82 | 04 08 09 10 11 14 27 28 29 30 31 32 33 34 47 48 49 61 62 65 66 67 68 69 79 80 81 98 99 100
|
||||||
* Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 | E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx
|
* Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 | E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx
|
||||||
* Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 73 75 76 77 74 xx xx xx xx xx
|
* Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 72 75 76 77 74 xx xx xx xx xx
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "../fastio.h"
|
#include "../fastio.h"
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -25,6 +25,16 @@
|
|||||||
* Test AVR-specific configuration values for errors at compile-time.
|
* Test AVR-specific configuration values for errors at compile-time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Digipot requirement
|
||||||
|
*/
|
||||||
|
#if ENABLED(DIGIPOT_MCP4018)
|
||||||
|
#if !defined(DIGIPOTS_I2C_SDA_X) || !defined(DIGIPOTS_I2C_SDA_Y) || !defined(DIGIPOTS_I2C_SDA_Z) \
|
||||||
|
|| !defined(DIGIPOTS_I2C_SDA_E0) || !defined(DIGIPOTS_I2C_SDA_E1)
|
||||||
|
#error "DIGIPOT_MCP4018 requires DIGIPOTS_I2C_SDA_* pins to be defined."
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks for FAST PWM
|
* Checks for FAST PWM
|
||||||
*/
|
*/
|
||||||
@@ -35,31 +45,21 @@
|
|||||||
/**
|
/**
|
||||||
* Sanity checks for Spindle / Laser PWM
|
* Sanity checks for Spindle / Laser PWM
|
||||||
*/
|
*/
|
||||||
#if ENABLED(SPINDLE_LASER_USE_PWM)
|
#if ENABLED(SPINDLE_LASER_PWM)
|
||||||
#include "../ServoTimers.h" // Needed to check timer availability (_useTimer3)
|
|
||||||
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
|
#if SPINDLE_LASER_PWM_PIN == 4 || WITHIN(SPINDLE_LASER_PWM_PIN, 11, 13)
|
||||||
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
|
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by a system interrupt."
|
||||||
#elif NUM_SERVOS > 0 && defined(_useTimer3) && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
|
#elif NUM_SERVOS > 0 && (WITHIN(SPINDLE_LASER_PWM_PIN, 2, 3) || SPINDLE_LASER_PWM_PIN == 5)
|
||||||
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
|
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
|
||||||
#endif
|
#endif
|
||||||
#elif defined(SPINDLE_LASER_FREQUENCY)
|
|
||||||
#error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM."
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Trinamic library includes SoftwareSerial.h, leading to a compile error.
|
* The Trinamic library includes SoftwareSerial.h, leading to a compile error.
|
||||||
*/
|
*/
|
||||||
#if BOTH(HAS_TRINAMIC_CONFIG, ENDSTOP_INTERRUPTS_FEATURE)
|
#if HAS_TRINAMIC && ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
|
||||||
#error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
#error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS)
|
#if HAS_TMC_SW_SERIAL && ENABLED(MONITOR_DRIVER_STATUS)
|
||||||
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
|
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Postmortem debugging
|
|
||||||
*/
|
|
||||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
|
||||||
#error "POSTMORTEM_DEBUGGING is not supported on AVR boards."
|
|
||||||
#endif
|
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
@@ -25,28 +25,19 @@
|
|||||||
|
|
||||||
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
|
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
|
||||||
|
|
||||||
/**
|
#include "../shared/persistent_store_api.h"
|
||||||
* PersistentStore for Arduino-style EEPROM interface
|
|
||||||
* with implementations supplied by the framework.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "../shared/eeprom_api.h"
|
bool PersistentStore::access_start() { return true; }
|
||||||
|
|
||||||
#ifndef MARLIN_EEPROM_SIZE
|
|
||||||
#define MARLIN_EEPROM_SIZE size_t(E2END + 1)
|
|
||||||
#endif
|
|
||||||
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
|
|
||||||
bool PersistentStore::access_start() { return true; }
|
|
||||||
bool PersistentStore::access_finish() { return true; }
|
bool PersistentStore::access_finish() { return true; }
|
||||||
|
|
||||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||||
uint16_t written = 0;
|
|
||||||
while (size--) {
|
while (size--) {
|
||||||
uint8_t * const p = (uint8_t * const)pos;
|
uint8_t * const p = (uint8_t * const)pos;
|
||||||
uint8_t v = *value;
|
uint8_t v = *value;
|
||||||
if (v != eeprom_read_byte(p)) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
|
// EEPROM has only ~100,000 write cycles,
|
||||||
|
// so only write bytes that have changed!
|
||||||
|
if (v != eeprom_read_byte(p)) {
|
||||||
eeprom_write_byte(p, v);
|
eeprom_write_byte(p, v);
|
||||||
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
|
|
||||||
if (eeprom_read_byte(p) != v) {
|
if (eeprom_read_byte(p) != v) {
|
||||||
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
|
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
|
||||||
return true;
|
return true;
|
||||||
@@ -55,11 +46,11 @@ bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, ui
|
|||||||
crc16(crc, &v, 1);
|
crc16(crc, &v, 1);
|
||||||
pos++;
|
pos++;
|
||||||
value++;
|
value++;
|
||||||
}
|
};
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
bool PersistentStore::read_data(int &pos, uint8_t* value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||||
do {
|
do {
|
||||||
uint8_t c = eeprom_read_byte((uint8_t*)pos);
|
uint8_t c = eeprom_read_byte((uint8_t*)pos);
|
||||||
if (writing) *value = c;
|
if (writing) *value = c;
|
||||||
@@ -70,5 +61,7 @@ bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t
|
|||||||
return false; // always assume success for AVR's
|
return false; // always assume success for AVR's
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t PersistentStore::capacity() { return E2END + 1; }
|
||||||
|
|
||||||
#endif // EEPROM_SETTINGS || SD_FIRMWARE_UPDATE
|
#endif // EEPROM_SETTINGS || SD_FIRMWARE_UPDATE
|
||||||
#endif // __AVR__
|
#endif // __AVR__
|
@@ -2,9 +2,6 @@
|
|||||||
* Marlin 3D Printer Firmware
|
* Marlin 3D Printer Firmware
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
*
|
*
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
@@ -16,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -29,9 +26,7 @@
|
|||||||
|
|
||||||
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
|
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
|
||||||
|
|
||||||
#if MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14)
|
#define AVR_ATmega2560_FAMILY_PLUS_70 MB(BQ_ZUM_MEGA_3D, MIGHTYBOARD_REVE, MINIRAMBO, SCOOVO_X9H)
|
||||||
#define AVR_ATmega2560_FAMILY_PLUS_70 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if AVR_AT90USB1286_FAMILY
|
#if AVR_AT90USB1286_FAMILY
|
||||||
|
|
||||||
@@ -41,7 +36,7 @@
|
|||||||
// portModeRegister takes a different argument
|
// portModeRegister takes a different argument
|
||||||
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
|
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
|
||||||
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
|
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
|
||||||
#define digitalPinToPort_DEBUG(p) digitalPinToPort(p)
|
#define digitalPinToPort_DEBUG(p) digitalPinToPort_Teensy(p)
|
||||||
#define GET_PINMODE(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin))
|
#define GET_PINMODE(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin))
|
||||||
|
|
||||||
#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70
|
#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70
|
||||||
@@ -75,12 +70,12 @@
|
|||||||
|
|
||||||
void PRINT_ARRAY_NAME(uint8_t x) {
|
void PRINT_ARRAY_NAME(uint8_t x) {
|
||||||
char *name_mem_pointer = (char*)pgm_read_ptr(&pin_array[x].name);
|
char *name_mem_pointer = (char*)pgm_read_ptr(&pin_array[x].name);
|
||||||
LOOP_L_N(y, MAX_NAME_LENGTH) {
|
for (uint8_t y = 0; y < MAX_NAME_LENGTH; y++) {
|
||||||
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)
|
||||||
SERIAL_CHAR(temp_char);
|
SERIAL_CHAR(temp_char);
|
||||||
else {
|
else {
|
||||||
LOOP_L_N(i, MAX_NAME_LENGTH - y) SERIAL_CHAR(' ');
|
for (uint8_t i = 0; i < MAX_NAME_LENGTH - y; i++) SERIAL_CHAR(' ');
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,9 +233,9 @@ static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin");
|
|||||||
|
|
||||||
inline void com_print(const uint8_t N, const uint8_t Z) {
|
inline void com_print(const uint8_t N, const uint8_t Z) {
|
||||||
const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
|
const uint8_t *TCCRA = (uint8_t*)TCCR_A(N);
|
||||||
SERIAL_ECHOPGM(" COM", AS_DIGIT(N));
|
SERIAL_ECHOPGM(" COM");
|
||||||
SERIAL_CHAR(Z);
|
SERIAL_CHAR('0' + N, Z);
|
||||||
SERIAL_ECHOPGM(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
|
SERIAL_ECHOPAIR(": ", int((*TCCRA >> (6 - Z * 2)) & 0x03));
|
||||||
}
|
}
|
||||||
|
|
||||||
void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout
|
void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - WGM bit layout
|
||||||
@@ -250,8 +245,8 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
|
|||||||
uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
|
uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
|
||||||
if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
|
if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
|
||||||
|
|
||||||
SERIAL_ECHOPGM(" TIMER", AS_DIGIT(T));
|
SERIAL_ECHOPGM(" TIMER");
|
||||||
SERIAL_CHAR(L);
|
SERIAL_CHAR(T + '0', L);
|
||||||
SERIAL_ECHO_SP(3);
|
SERIAL_ECHO_SP(3);
|
||||||
|
|
||||||
if (N == 3) {
|
if (N == 3) {
|
||||||
@@ -262,14 +257,22 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
|
|||||||
const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A');
|
const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A');
|
||||||
PWM_PRINT(*OCRVAL16);
|
PWM_PRINT(*OCRVAL16);
|
||||||
}
|
}
|
||||||
SERIAL_ECHOPGM(" WGM: ", WGM);
|
SERIAL_ECHOPAIR(" WGM: ", WGM);
|
||||||
com_print(T,L);
|
com_print(T,L);
|
||||||
SERIAL_ECHOPGM(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
|
SERIAL_ECHOPAIR(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
|
||||||
SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "A: ", *TCCRA);
|
|
||||||
SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "B: ", *TCCRB);
|
SERIAL_ECHOPGM(" TCCR");
|
||||||
|
SERIAL_CHAR(T + '0');
|
||||||
|
SERIAL_ECHOPAIR("A: ", *TCCRA);
|
||||||
|
|
||||||
|
SERIAL_ECHOPGM(" TCCR");
|
||||||
|
SERIAL_CHAR(T + '0');
|
||||||
|
SERIAL_ECHOPAIR("B: ", *TCCRB);
|
||||||
|
|
||||||
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
|
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
|
||||||
SERIAL_ECHOPGM(" TIMSK", AS_DIGIT(T), ": ", *TMSK);
|
SERIAL_ECHOPGM(" TIMSK");
|
||||||
|
SERIAL_CHAR(T + '0');
|
||||||
|
SERIAL_ECHOPAIR(": ", *TMSK);
|
||||||
|
|
||||||
const uint8_t OCIE = L - 'A' + 1;
|
const uint8_t OCIE = L - 'A' + 1;
|
||||||
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
|
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
|
||||||
@@ -396,4 +399,3 @@ static void pwm_details(uint8_t pin) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
|
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
|
||||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
|
|
@@ -2,9 +2,6 @@
|
|||||||
* Marlin 3D Printer Firmware
|
* Marlin 3D Printer Firmware
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
*
|
*
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
@@ -16,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -2,9 +2,6 @@
|
|||||||
* Marlin 3D Printer Firmware
|
* Marlin 3D Printer Firmware
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
*
|
*
|
||||||
* Based on Sprinter and grbl.
|
|
||||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
@@ -16,7 +13,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -25,12 +22,15 @@
|
|||||||
* Structures for 2560 family boards that use more than 70 pins
|
* Structures for 2560 family boards that use more than 70 pins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if MB(BQ_ZUM_MEGA_3D, MINIRAMBO, SCOOVO_X9H, TRIGORILLA_14)
|
#undef NUM_DIGITAL_PINS
|
||||||
#undef NUM_DIGITAL_PINS
|
#if MB(BQ_ZUM_MEGA_3D)
|
||||||
#define NUM_DIGITAL_PINS 85
|
#define NUM_DIGITAL_PINS 85
|
||||||
#elif MB(MIGHTYBOARD_REVE)
|
#elif MB(MIGHTYBOARD_REVE)
|
||||||
#undef NUM_DIGITAL_PINS
|
|
||||||
#define NUM_DIGITAL_PINS 80
|
#define NUM_DIGITAL_PINS 80
|
||||||
|
#elif MB(MINIRAMBO)
|
||||||
|
#define NUM_DIGITAL_PINS 85
|
||||||
|
#elif MB(SCOOVO_X9H)
|
||||||
|
#define NUM_DIGITAL_PINS 85
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PA 1
|
#define PA 1
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -51,15 +51,15 @@
|
|||||||
#define AVR_SS_PIN 16
|
#define AVR_SS_PIN 16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef SD_SCK_PIN
|
#ifndef SCK_PIN
|
||||||
#define SD_SCK_PIN AVR_SCK_PIN
|
#define SCK_PIN AVR_SCK_PIN
|
||||||
#endif
|
#endif
|
||||||
#ifndef SD_MISO_PIN
|
#ifndef MISO_PIN
|
||||||
#define SD_MISO_PIN AVR_MISO_PIN
|
#define MISO_PIN AVR_MISO_PIN
|
||||||
#endif
|
#endif
|
||||||
#ifndef SD_MOSI_PIN
|
#ifndef MOSI_PIN
|
||||||
#define SD_MOSI_PIN AVR_MOSI_PIN
|
#define MOSI_PIN AVR_MOSI_PIN
|
||||||
#endif
|
#endif
|
||||||
#ifndef SD_SS_PIN
|
#ifndef SS_PIN
|
||||||
#define SD_SS_PIN AVR_SS_PIN
|
#define SS_PIN AVR_SS_PIN
|
||||||
#endif
|
#endif
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -57,15 +57,15 @@
|
|||||||
|
|
||||||
#include "../../inc/MarlinConfigPre.h"
|
#include "../../inc/MarlinConfigPre.h"
|
||||||
|
|
||||||
#if HAS_MARLINUI_U8GLIB
|
#if HAS_GRAPHICAL_LCD
|
||||||
|
|
||||||
#include "../shared/Marduino.h"
|
#include "../shared/Marduino.h"
|
||||||
#include "../shared/Delay.h"
|
#include "../shared/Delay.h"
|
||||||
|
|
||||||
#include <U8glib-HAL.h>
|
#include <U8glib.h>
|
||||||
|
|
||||||
static uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
|
uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
|
||||||
static volatile uint8_t *u8g_outData, *u8g_outClock;
|
volatile uint8_t *u8g_outData, *u8g_outClock;
|
||||||
|
|
||||||
static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) {
|
static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) {
|
||||||
u8g_outData = portOutputRegister(digitalPinToPort(dataPin));
|
u8g_outData = portOutputRegister(digitalPinToPort(dataPin));
|
||||||
@@ -88,7 +88,7 @@ void u8g_spiSend_sw_AVR_mode_0(uint8_t val) {
|
|||||||
volatile uint8_t *outData = u8g_outData,
|
volatile uint8_t *outData = u8g_outData,
|
||||||
*outClock = u8g_outClock;
|
*outClock = u8g_outClock;
|
||||||
U8G_ATOMIC_START();
|
U8G_ATOMIC_START();
|
||||||
LOOP_L_N(i, 8) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
if (val & 0x80)
|
if (val & 0x80)
|
||||||
*outData |= bitData;
|
*outData |= bitData;
|
||||||
else
|
else
|
||||||
@@ -108,7 +108,7 @@ void u8g_spiSend_sw_AVR_mode_3(uint8_t val) {
|
|||||||
volatile uint8_t *outData = u8g_outData,
|
volatile uint8_t *outData = u8g_outData,
|
||||||
*outClock = u8g_outClock;
|
*outClock = u8g_outClock;
|
||||||
U8G_ATOMIC_START();
|
U8G_ATOMIC_START();
|
||||||
LOOP_L_N(i, 8) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
*outClock &= bitNotClock;
|
*outClock &= bitNotClock;
|
||||||
if (val & 0x80)
|
if (val & 0x80)
|
||||||
*outData |= bitData;
|
*outData |= bitData;
|
||||||
@@ -189,5 +189,5 @@ uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_MARLINUI_U8GLIB
|
#endif // HAS_GRAPHICAL_LCD
|
||||||
#endif // ARDUINO_ARCH_SAM
|
#endif // ARDUINO_ARCH_SAM
|
@@ -16,9 +16,10 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __AVR__
|
#ifdef __AVR__
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
#include "../../inc/MarlinConfig.h"
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
343
Marlin/src/HAL/HAL_DUE/DebugMonitor.cpp
Normal file
343
Marlin/src/HAL/HAL_DUE/DebugMonitor.cpp
Normal file
@@ -0,0 +1,343 @@
|
|||||||
|
/**
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ARDUINO_ARCH_SAM
|
||||||
|
|
||||||
|
#include "../../core/macros.h"
|
||||||
|
#include "../../core/serial.h"
|
||||||
|
|
||||||
|
#include "../shared/backtrace/unwinder.h"
|
||||||
|
#include "../shared/backtrace/unwmemaccess.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
// Debug monitor that dumps to the Programming port all status when
|
||||||
|
// an exception or WDT timeout happens - And then resets the board
|
||||||
|
|
||||||
|
// All the Monitor routines must run with interrupts disabled and
|
||||||
|
// under an ISR execution context. That is why we cannot reuse the
|
||||||
|
// Serial interrupt routines or any C runtime, as we don't know the
|
||||||
|
// state we are when running them
|
||||||
|
|
||||||
|
// A SW memory barrier, to ensure GCC does not overoptimize loops
|
||||||
|
#define sw_barrier() __asm__ volatile("": : :"memory");
|
||||||
|
|
||||||
|
// (re)initialize UART0 as a monitor output to 250000,n,8,1
|
||||||
|
static void TXBegin() {
|
||||||
|
|
||||||
|
// Disable UART interrupt in NVIC
|
||||||
|
NVIC_DisableIRQ( UART_IRQn );
|
||||||
|
|
||||||
|
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||||
|
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||||
|
__DSB();
|
||||||
|
__ISB();
|
||||||
|
|
||||||
|
// Disable clock
|
||||||
|
pmc_disable_periph_clk( ID_UART );
|
||||||
|
|
||||||
|
// Configure PMC
|
||||||
|
pmc_enable_periph_clk( ID_UART );
|
||||||
|
|
||||||
|
// Disable PDC channel
|
||||||
|
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
|
||||||
|
|
||||||
|
// Reset and disable receiver and transmitter
|
||||||
|
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
|
||||||
|
|
||||||
|
// Configure mode: 8bit, No parity, 1 bit stop
|
||||||
|
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
|
||||||
|
|
||||||
|
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
|
||||||
|
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
|
||||||
|
|
||||||
|
// Enable receiver and transmitter
|
||||||
|
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send character through UART with no interrupts
|
||||||
|
static void TX(char c) {
|
||||||
|
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
|
||||||
|
UART->UART_THR = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send String through UART
|
||||||
|
static void TX(const char* s) {
|
||||||
|
while (*s) TX(*s++);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TXDigit(uint32_t d) {
|
||||||
|
if (d < 10) TX((char)(d+'0'));
|
||||||
|
else if (d < 16) TX((char)(d+'A'-10));
|
||||||
|
else TX('?');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send Hex number thru UART
|
||||||
|
static void TXHex(uint32_t v) {
|
||||||
|
TX("0x");
|
||||||
|
for (uint8_t i = 0; i < 8; i++, v <<= 4)
|
||||||
|
TXDigit((v >> 28) & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send Decimal number thru UART
|
||||||
|
static void TXDec(uint32_t v) {
|
||||||
|
if (!v) {
|
||||||
|
TX('0');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char nbrs[14];
|
||||||
|
char *p = &nbrs[0];
|
||||||
|
while (v != 0) {
|
||||||
|
*p++ = '0' + (v % 10);
|
||||||
|
v /= 10;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
p--;
|
||||||
|
TX(*p);
|
||||||
|
} while (p != &nbrs[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dump a backtrace entry
|
||||||
|
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
|
||||||
|
int* p = (int*)ctx;
|
||||||
|
|
||||||
|
(*p)++;
|
||||||
|
TX('#'); TXDec(*p); TX(" : ");
|
||||||
|
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
|
||||||
|
TX('+'); TXDec(bte->address - bte->function);
|
||||||
|
TX(" PC:");TXHex(bte->address); TX('\n');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef UNW_DEBUG
|
||||||
|
void UnwPrintf(const char* format, ...) {
|
||||||
|
char dest[256];
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, format);
|
||||||
|
vsprintf(dest, format, argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
TX(&dest[0]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Table of function pointers for passing to the unwinder */
|
||||||
|
static const UnwindCallbacks UnwCallbacks = {
|
||||||
|
UnwReportOut,
|
||||||
|
UnwReadW,
|
||||||
|
UnwReadH,
|
||||||
|
UnwReadB
|
||||||
|
#ifdef UNW_DEBUG
|
||||||
|
, UnwPrintf
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HardFaultHandler_C:
|
||||||
|
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
|
||||||
|
* as the parameter. We can then read the values from the stack and place them
|
||||||
|
* into local variables for ease of reading.
|
||||||
|
* We then read the various Fault Status and Address Registers to help decode
|
||||||
|
* cause of the fault.
|
||||||
|
* The function ends with a BKPT instruction to force control back into the debugger
|
||||||
|
*/
|
||||||
|
extern "C"
|
||||||
|
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
|
||||||
|
|
||||||
|
static const char* causestr[] = {
|
||||||
|
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
|
||||||
|
};
|
||||||
|
|
||||||
|
UnwindFrame btf;
|
||||||
|
|
||||||
|
// Dump report to the Programming port (interrupts are DISABLED)
|
||||||
|
TXBegin();
|
||||||
|
TX("\n\n## Software Fault detected ##\n");
|
||||||
|
TX("Cause: "); TX(causestr[cause]); TX('\n');
|
||||||
|
|
||||||
|
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
|
||||||
|
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
|
||||||
|
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
|
||||||
|
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
|
||||||
|
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
|
||||||
|
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
|
||||||
|
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
|
||||||
|
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
|
||||||
|
|
||||||
|
// Configurable Fault Status Register
|
||||||
|
// Consists of MMSR, BFSR and UFSR
|
||||||
|
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
|
||||||
|
|
||||||
|
// Hard Fault Status Register
|
||||||
|
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
|
||||||
|
|
||||||
|
// Debug Fault Status Register
|
||||||
|
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
|
||||||
|
|
||||||
|
// Auxiliary Fault Status Register
|
||||||
|
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
|
||||||
|
|
||||||
|
// Read the Fault Address Registers. These may not contain valid values.
|
||||||
|
// Check BFARVALID/MMARVALID to see if they are valid values
|
||||||
|
// MemManage Fault Address Register
|
||||||
|
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
|
||||||
|
|
||||||
|
// Bus Fault Address Register
|
||||||
|
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
|
||||||
|
|
||||||
|
TX("ExcLR: "); TXHex(lr); TX('\n');
|
||||||
|
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
|
||||||
|
|
||||||
|
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
|
||||||
|
btf.fp = btf.sp;
|
||||||
|
btf.lr = ((unsigned long)sp[5]);
|
||||||
|
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
|
||||||
|
|
||||||
|
// Perform a backtrace
|
||||||
|
TX("\nBacktrace:\n\n");
|
||||||
|
int ctr = 0;
|
||||||
|
UnwindStart(&btf, &UnwCallbacks, &ctr);
|
||||||
|
|
||||||
|
// Disable all NVIC interrupts
|
||||||
|
NVIC->ICER[0] = 0xFFFFFFFF;
|
||||||
|
NVIC->ICER[1] = 0xFFFFFFFF;
|
||||||
|
|
||||||
|
// Relocate VTOR table to default position
|
||||||
|
SCB->VTOR = 0;
|
||||||
|
|
||||||
|
// Disable USB
|
||||||
|
otg_disable();
|
||||||
|
|
||||||
|
// Restart watchdog
|
||||||
|
WDT_Restart(WDT);
|
||||||
|
|
||||||
|
// Reset controller
|
||||||
|
NVIC_SystemReset();
|
||||||
|
for (;;) WDT_Restart(WDT);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void NMI_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#0")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void HardFault_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#1")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void MemManage_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#2")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void BusFault_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#3")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void UsageFault_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#4")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void DebugMon_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#5")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
|
||||||
|
__attribute__((naked)) void WDT_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#6")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((naked)) void RSTC_Handler() {
|
||||||
|
__asm__ __volatile__ (
|
||||||
|
".syntax unified" "\n\t"
|
||||||
|
A("tst lr, #4")
|
||||||
|
A("ite eq")
|
||||||
|
A("mrseq r0, msp")
|
||||||
|
A("mrsne r0, psp")
|
||||||
|
A("mov r1,lr")
|
||||||
|
A("mov r2,#7")
|
||||||
|
A("b HardFault_HandlerC")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // ARDUINO_ARCH_SAM
|
@@ -1,10 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* Marlin 3D Printer Firmware
|
* Marlin 3D Printer Firmware
|
||||||
*
|
|
||||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
*
|
||||||
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
|
* Based on Sprinter and grbl.
|
||||||
* Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
|
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -17,14 +16,9 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#ifdef ARDUINO_ARCH_SAM
|
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
|
||||||
|
|
||||||
#if ENABLED(FLASH_EEPROM_EMULATION)
|
|
||||||
|
|
||||||
/* EEPROM emulation over flash with reduced wear
|
/* EEPROM emulation over flash with reduced wear
|
||||||
*
|
*
|
||||||
@@ -53,14 +47,22 @@
|
|||||||
* per page. We can't emulate EE endurance with FLASH for all
|
* per page. We can't emulate EE endurance with FLASH for all
|
||||||
* bytes, but we can emulate endurance for a given percent of
|
* bytes, but we can emulate endurance for a given percent of
|
||||||
* bytes.
|
* bytes.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#define EE_EMU_DEBUG
|
#ifdef ARDUINO_ARCH_SAM
|
||||||
|
|
||||||
|
#include "../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
|
#if ENABLED(EEPROM_SETTINGS) && NONE(I2C_EEPROM, SPI_EEPROM)
|
||||||
|
|
||||||
|
#include "../shared/Marduino.h"
|
||||||
|
#include "../shared/persistent_store_api.h"
|
||||||
|
|
||||||
#define EEPROMSize 4096
|
#define EEPROMSize 4096
|
||||||
#define PagesPerGroup 128
|
#define PagesPerGroup 128
|
||||||
#define GroupCount 2
|
#define GroupCount 2
|
||||||
#define PageSize 256U
|
#define PageSize 256u
|
||||||
|
|
||||||
/* Flash storage */
|
/* Flash storage */
|
||||||
typedef struct FLASH_SECTOR {
|
typedef struct FLASH_SECTOR {
|
||||||
@@ -132,18 +134,15 @@ static uint8_t buffer[256] = {0}, // The RAM buffer to accumulate writes
|
|||||||
curPage = 0, // Current FLASH page inside the group
|
curPage = 0, // Current FLASH page inside the group
|
||||||
curGroup = 0xFF; // Current FLASH group
|
curGroup = 0xFF; // Current FLASH group
|
||||||
|
|
||||||
#define DEBUG_OUT ENABLED(EE_EMU_DEBUG)
|
//#define EE_EMU_DEBUG
|
||||||
#include "../../core/debug_out.h"
|
#ifdef EE_EMU_DEBUG
|
||||||
|
static void ee_Dump(int page,const void* data) {
|
||||||
|
|
||||||
static void ee_Dump(const int page, const void *data) {
|
const uint8_t* c = (const uint8_t*) data;
|
||||||
|
|
||||||
#ifdef EE_EMU_DEBUG
|
|
||||||
|
|
||||||
const uint8_t *c = (const uint8_t*) data;
|
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
|
|
||||||
sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page);
|
sprintf_P(buffer, PSTR("Page: %d (0x%04x)\n"), page, page);
|
||||||
DEBUG_ECHO(buffer);
|
SERIAL_ECHO(buffer);
|
||||||
|
|
||||||
char* p = &buffer[0];
|
char* p = &buffer[0];
|
||||||
for (int i = 0; i< PageSize; ++i) {
|
for (int i = 0; i< PageSize; ++i) {
|
||||||
@@ -153,16 +152,12 @@ static void ee_Dump(const int page, const void *data) {
|
|||||||
if ((i & 0xF) == 0xF) {
|
if ((i & 0xF) == 0xF) {
|
||||||
*p++ = '\n';
|
*p++ = '\n';
|
||||||
*p = 0;
|
*p = 0;
|
||||||
DEBUG_ECHO(buffer);
|
SERIAL_ECHO(buffer);
|
||||||
p = &buffer[0];
|
p = &buffer[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#else
|
#endif
|
||||||
UNUSED(page);
|
|
||||||
UNUSED(data);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Flash Writing Protection Key */
|
/* Flash Writing Protection Key */
|
||||||
#define FWP_KEY 0x5Au
|
#define FWP_KEY 0x5Au
|
||||||
@@ -175,16 +170,17 @@ static void ee_Dump(const int page, const void *data) {
|
|||||||
#define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
|
#define EEFC_ERROR_FLAGS (EEFC_FSR_FLOCKE | EEFC_FSR_FCMDE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the contents of the specified page (no previous erase)
|
* Writes the contents of the specified page (no previous erase)
|
||||||
* @param page (page #)
|
* @param page (page #)
|
||||||
* @param data (pointer to the data buffer)
|
* @param data (pointer to the data buffer)
|
||||||
*/
|
*/
|
||||||
__attribute__ ((long_call, section (".ramfunc")))
|
__attribute__ ((long_call, section (".ramfunc")))
|
||||||
static bool ee_PageWrite(uint16_t page, const void *data) {
|
static bool ee_PageWrite(uint16_t page,const void* data) {
|
||||||
|
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint32_t addrflash = uint32_t(getFlashStorage(page));
|
uint32_t addrflash = ((uint32_t)getFlashStorage(page));
|
||||||
|
|
||||||
// Read the flash contents
|
// Read the flash contents
|
||||||
uint32_t pageContents[PageSize>>2];
|
uint32_t pageContents[PageSize>>2];
|
||||||
@@ -199,11 +195,13 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
|||||||
for (i = 0; i <PageSize >> 2; i++)
|
for (i = 0; i <PageSize >> 2; i++)
|
||||||
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
|
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM PageWrite ", page);
|
SERIAL_ECHO_START();
|
||||||
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
|
SERIAL_ECHOLNPAIR("EEPROM PageWrite ", page);
|
||||||
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
|
SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
|
||||||
DEBUG_FLUSH();
|
SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
|
||||||
|
SERIAL_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Get the page relative to the start of the EFC controller, and the EFC controller to use
|
// Get the page relative to the start of the EFC controller, and the EFC controller to use
|
||||||
Efc *efc;
|
Efc *efc;
|
||||||
@@ -245,8 +243,10 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
|||||||
// Reenable interrupts
|
// Reenable interrupts
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ", page);
|
SERIAL_ECHO_START();
|
||||||
|
SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,9 +270,10 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
|||||||
// Reenable interrupts
|
// Reenable interrupts
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Write failure for page ", page);
|
SERIAL_ECHO_START();
|
||||||
|
SERIAL_ECHOLNPAIR("EEPROM Write failure for page ", page);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,15 +287,15 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
|||||||
if (memcmp(getFlashStorage(page),data,PageSize)) {
|
if (memcmp(getFlashStorage(page),data,PageSize)) {
|
||||||
|
|
||||||
#ifdef EE_EMU_DEBUG
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHO_START();
|
SERIAL_ECHO_START();
|
||||||
DEBUG_ECHOLNPGM("EEPROM Verify Write failure for page ", page);
|
SERIAL_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
|
||||||
|
|
||||||
ee_Dump( page, (uint32_t *)addrflash);
|
ee_Dump( page,(uint32_t *) addrflash);
|
||||||
ee_Dump(-page, data);
|
ee_Dump(-page,data);
|
||||||
|
|
||||||
// Calculate count of changed bits
|
// Calculate count of changed bits
|
||||||
uint32_t *p1 = (uint32_t*)addrflash;
|
uint32_t* p1 = (uint32_t*)addrflash;
|
||||||
uint32_t *p2 = (uint32_t*)data;
|
uint32_t* p2 = (uint32_t*)data;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (i =0; i<PageSize >> 2; i++) {
|
for (i =0; i<PageSize >> 2; i++) {
|
||||||
if (p1[i] != p2[i]) {
|
if (p1[i] != p2[i]) {
|
||||||
@@ -306,7 +307,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DEBUG_ECHOLNPGM("--> Differing bits: ", count);
|
SERIAL_ECHOLNPAIR("--> Differing bits: ", count);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@@ -323,13 +324,15 @@ __attribute__ ((long_call, section (".ramfunc")))
|
|||||||
static bool ee_PageErase(uint16_t page) {
|
static bool ee_PageErase(uint16_t page) {
|
||||||
|
|
||||||
uint16_t i;
|
uint16_t i;
|
||||||
uint32_t addrflash = uint32_t(getFlashStorage(page));
|
uint32_t addrflash = ((uint32_t)getFlashStorage(page));
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM PageErase ", page);
|
SERIAL_ECHO_START();
|
||||||
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
|
SERIAL_ECHOLNPAIR("EEPROM PageErase ", page);
|
||||||
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
|
SERIAL_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
|
||||||
DEBUG_FLUSH();
|
SERIAL_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
|
||||||
|
SERIAL_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Get the page relative to the start of the EFC controller, and the EFC controller to use
|
// Get the page relative to the start of the EFC controller, and the EFC controller to use
|
||||||
Efc *efc;
|
Efc *efc;
|
||||||
@@ -370,9 +373,10 @@ static bool ee_PageErase(uint16_t page) {
|
|||||||
// Reenable interrupts
|
// Reenable interrupts
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ",page);
|
SERIAL_ECHO_START();
|
||||||
|
SERIAL_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,9 +398,10 @@ static bool ee_PageErase(uint16_t page) {
|
|||||||
// Reenable interrupts
|
// Reenable interrupts
|
||||||
__enable_irq();
|
__enable_irq();
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Erase failure for page ",page);
|
SERIAL_ECHO_START();
|
||||||
|
SERIAL_ECHOLNPAIR("EEPROM Erase failure for page ",page);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -410,17 +415,20 @@ static bool ee_PageErase(uint16_t page) {
|
|||||||
uint32_t * aligned_src = (uint32_t *) addrflash;
|
uint32_t * aligned_src = (uint32_t *) addrflash;
|
||||||
for (i = 0; i < PageSize >> 2; i++) {
|
for (i = 0; i < PageSize >> 2; i++) {
|
||||||
if (*aligned_src++ != 0xFFFFFFFF) {
|
if (*aligned_src++ != 0xFFFFFFFF) {
|
||||||
DEBUG_ECHO_START();
|
|
||||||
DEBUG_ECHOLNPGM("EEPROM Verify Erase failure for page ",page);
|
#ifdef EE_EMU_DEBUG
|
||||||
ee_Dump(page, (uint32_t *)addrflash);
|
SERIAL_ECHO_START();
|
||||||
|
SERIAL_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
|
||||||
|
|
||||||
|
ee_Dump( page,(uint32_t *) addrflash);
|
||||||
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer = false) {
|
||||||
static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) {
|
|
||||||
|
|
||||||
uint32_t baddr;
|
uint32_t baddr;
|
||||||
uint32_t blen;
|
uint32_t blen;
|
||||||
@@ -470,7 +478,7 @@ static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) {
|
|||||||
for (int page = curPage - 1; page >= 0; --page) {
|
for (int page = curPage - 1; page >= 0; --page) {
|
||||||
|
|
||||||
// Get a pointer to the flash page
|
// Get a pointer to the flash page
|
||||||
uint8_t *pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
|
uint8_t* pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
|
||||||
|
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */
|
while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */
|
||||||
@@ -503,7 +511,7 @@ static uint8_t ee_Read(uint32_t address, bool excludeRAMBuffer=false) {
|
|||||||
return 0xFF;
|
return 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) {
|
static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer = false) {
|
||||||
uint32_t baddr,
|
uint32_t baddr,
|
||||||
blen,
|
blen,
|
||||||
nextAddr = 0xFFFF,
|
nextAddr = 0xFFFF,
|
||||||
@@ -550,7 +558,7 @@ static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) {
|
|||||||
for (int page = curPage - 1; page >= 0; --page) {
|
for (int page = curPage - 1; page >= 0; --page) {
|
||||||
|
|
||||||
// Get a pointer to the flash page
|
// Get a pointer to the flash page
|
||||||
uint8_t *pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
|
uint8_t* pflash = (uint8_t*)getFlashStorage(page + curGroup * PagesPerGroup);
|
||||||
|
|
||||||
uint16_t i = 0;
|
uint16_t i = 0;
|
||||||
while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */
|
while (i <= (PageSize - 4)) { /* (PageSize - 4) because otherwise, there is not enough room for data and headers */
|
||||||
@@ -589,17 +597,17 @@ static uint32_t ee_GetAddrRange(uint32_t address, bool excludeRAMBuffer=false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool ee_IsPageClean(int page) {
|
static bool ee_IsPageClean(int page) {
|
||||||
uint32_t *pflash = (uint32_t*) getFlashStorage(page);
|
uint32_t* pflash = (uint32_t*) getFlashStorage(page);
|
||||||
for (uint16_t i = 0; i < (PageSize >> 2); ++i)
|
for (uint16_t i = 0; i < (PageSize >> 2); ++i)
|
||||||
if (*pflash++ != 0xFFFFFFFF) return false;
|
if (*pflash++ != 0xFFFFFFFF) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData=0xFF) {
|
static bool ee_Flush(uint32_t overrideAddress = 0xFFFFFFFF, uint8_t overrideData = 0xFF) {
|
||||||
|
|
||||||
// Check if RAM buffer has something to be written
|
// Check if RAM buffer has something to be written
|
||||||
bool isEmpty = true;
|
bool isEmpty = true;
|
||||||
uint32_t *p = (uint32_t*) &buffer[0];
|
uint32_t* p = (uint32_t*) &buffer[0];
|
||||||
for (uint16_t j = 0; j < (PageSize >> 2); j++) {
|
for (uint16_t j = 0; j < (PageSize >> 2); j++) {
|
||||||
if (*p++ != 0xFFFFFFFF) {
|
if (*p++ != 0xFFFFFFFF) {
|
||||||
isEmpty = false;
|
isEmpty = false;
|
||||||
@@ -921,9 +929,11 @@ static void ee_Init() {
|
|||||||
// If all groups seem to be used, default to first group
|
// If all groups seem to be used, default to first group
|
||||||
if (curGroup >= GroupCount) curGroup = 0;
|
if (curGroup >= GroupCount) curGroup = 0;
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Current Group: ",curGroup);
|
SERIAL_ECHO_START();
|
||||||
DEBUG_FLUSH();
|
SERIAL_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
|
||||||
|
SERIAL_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Now, validate that all the other group pages are empty
|
// Now, validate that all the other group pages are empty
|
||||||
for (int grp = 0; grp < GroupCount; grp++) {
|
for (int grp = 0; grp < GroupCount; grp++) {
|
||||||
@@ -931,9 +941,11 @@ static void ee_Init() {
|
|||||||
|
|
||||||
for (int page = 0; page < PagesPerGroup; page++) {
|
for (int page = 0; page < PagesPerGroup; page++) {
|
||||||
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
|
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on group ", grp);
|
SERIAL_ECHO_START();
|
||||||
DEBUG_FLUSH();
|
SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
|
||||||
|
SERIAL_FLUSH();
|
||||||
|
#endif
|
||||||
ee_PageErase(grp * PagesPerGroup + page);
|
ee_PageErase(grp * PagesPerGroup + page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -943,68 +955,66 @@ static void ee_Init() {
|
|||||||
// and also validate that all the other ones are clean
|
// and also validate that all the other ones are clean
|
||||||
for (curPage = 0; curPage < PagesPerGroup; curPage++) {
|
for (curPage = 0; curPage < PagesPerGroup; curPage++) {
|
||||||
if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) {
|
if (ee_IsPageClean(curGroup * PagesPerGroup + curPage)) {
|
||||||
ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage));
|
#ifdef EE_EMU_DEBUG
|
||||||
|
ee_Dump(curGroup * PagesPerGroup + curPage, getFlashStorage(curGroup * PagesPerGroup + curPage));
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Active page: ", curPage);
|
SERIAL_ECHO_START();
|
||||||
DEBUG_FLUSH();
|
SERIAL_ECHOLNPAIR("EEPROM Active page: ", curPage);
|
||||||
|
SERIAL_FLUSH();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Make sure the pages following the first clean one are also clean
|
// Make sure the pages following the first clean one are also clean
|
||||||
for (int page = curPage + 1; page < PagesPerGroup; page++) {
|
for (int page = curPage + 1; page < PagesPerGroup; page++) {
|
||||||
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
|
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
|
||||||
DEBUG_ECHO_START();
|
#ifdef EE_EMU_DEBUG
|
||||||
DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on active group ", curGroup);
|
SERIAL_ECHO_START();
|
||||||
DEBUG_FLUSH();
|
SERIAL_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
|
||||||
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
|
SERIAL_FLUSH();
|
||||||
|
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
|
||||||
|
#endif
|
||||||
ee_PageErase(curGroup * PagesPerGroup + page);
|
ee_PageErase(curGroup * PagesPerGroup + page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PersistentStore -----------------------------------------------------------*/
|
uint8_t eeprom_read_byte(uint8_t* addr) {
|
||||||
|
ee_Init();
|
||||||
|
return ee_Read((uint32_t)addr);
|
||||||
|
}
|
||||||
|
|
||||||
#include "../shared/eeprom_api.h"
|
void eeprom_write_byte(uint8_t* addr, uint8_t value) {
|
||||||
|
ee_Init();
|
||||||
|
ee_Write((uint32_t)addr, value);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MARLIN_EEPROM_SIZE
|
void eeprom_update_block(const void* __src, void* __dst, size_t __n) {
|
||||||
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
|
uint8_t* dst = (uint8_t*)__dst;
|
||||||
#endif
|
const uint8_t* src = (const uint8_t*)__src;
|
||||||
size_t PersistentStore::capacity() { return MARLIN_EEPROM_SIZE; }
|
while (__n--) {
|
||||||
bool PersistentStore::access_start() { ee_Init(); return true; }
|
eeprom_write_byte(dst, *src);
|
||||||
bool PersistentStore::access_finish() { ee_Flush(); return true; }
|
++dst;
|
||||||
|
++src;
|
||||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
|
||||||
uint16_t written = 0;
|
|
||||||
while (size--) {
|
|
||||||
uint8_t * const p = (uint8_t * const)pos;
|
|
||||||
uint8_t v = *value;
|
|
||||||
if (v != ee_Read(uint32_t(p))) { // EEPROM has only ~100,000 write cycles, so only write bytes that have changed!
|
|
||||||
ee_Write(uint32_t(p), v);
|
|
||||||
if (++written & 0x7F) delay(2); else safe_delay(2); // Avoid triggering watchdog during long EEPROM writes
|
|
||||||
if (ee_Read(uint32_t(p)) != v) {
|
|
||||||
SERIAL_ECHO_MSG(STR_ERR_EEPROM_WRITE);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
crc16(crc, &v, 1);
|
|
||||||
pos++;
|
|
||||||
value++;
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
void eeprom_read_block(void* __dst, const void* __src, size_t __n) {
|
||||||
do {
|
uint8_t* dst = (uint8_t*)__dst;
|
||||||
uint8_t c = ee_Read(uint32_t(pos));
|
uint8_t* src = (uint8_t*)__src;
|
||||||
if (writing) *value = c;
|
while (__n--) {
|
||||||
crc16(crc, &c, 1);
|
*dst = eeprom_read_byte(src);
|
||||||
pos++;
|
++dst;
|
||||||
value++;
|
++src;
|
||||||
} while (--size);
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FLASH_EEPROM_EMULATION
|
void eeprom_flush() {
|
||||||
#endif // ARDUINO_ARCH_SAM
|
ee_Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // EEPROM_SETTINGS && (!I2C_EEPROM && !SPI_EEPROM)
|
||||||
|
#endif // ARDUINO_ARCH_AVR
|
@@ -14,12 +14,13 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HAL for Arduino Due and compatible (SAM3X8E)
|
* Description: HAL for Arduino Due and compatible (SAM3X8E)
|
||||||
|
*
|
||||||
|
* For ARDUINO_ARCH_SAM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_SAM
|
#ifdef ARDUINO_ARCH_SAM
|
||||||
@@ -40,8 +41,6 @@ uint16_t HAL_adc_result;
|
|||||||
// Public functions
|
// Public functions
|
||||||
// ------------------------
|
// ------------------------
|
||||||
|
|
||||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
|
|
||||||
|
|
||||||
// HAL initialization task
|
// HAL initialization task
|
||||||
void HAL_init() {
|
void HAL_init() {
|
||||||
// Initialize the USB stack
|
// Initialize the USB stack
|
||||||
@@ -49,7 +48,6 @@ void HAL_init() {
|
|||||||
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
|
||||||
#endif
|
#endif
|
||||||
usb_task_init();
|
usb_task_init();
|
||||||
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// HAL idle task
|
// HAL idle task
|
||||||
@@ -77,8 +75,6 @@ uint8_t HAL_get_reset_source() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_reboot() { rstc_start_software_reset(RSTC); }
|
|
||||||
|
|
||||||
void _delay_ms(const int delay_ms) {
|
void _delay_ms(const int delay_ms) {
|
||||||
// Todo: port for Due?
|
// Todo: port for Due?
|
||||||
delay(delay_ms);
|
delay(delay_ms);
|
||||||
@@ -107,18 +103,4 @@ uint16_t HAL_adc_get_result() {
|
|||||||
return HAL_adc_result;
|
return HAL_adc_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward the default serial ports
|
|
||||||
#if USING_HW_SERIAL0
|
|
||||||
DefaultSerial1 MSerial0(false, Serial);
|
|
||||||
#endif
|
|
||||||
#if USING_HW_SERIAL1
|
|
||||||
DefaultSerial2 MSerial1(false, Serial1);
|
|
||||||
#endif
|
|
||||||
#if USING_HW_SERIAL2
|
|
||||||
DefaultSerial3 MSerial2(false, Serial2);
|
|
||||||
#endif
|
|
||||||
#if USING_HW_SERIAL3
|
|
||||||
DefaultSerial4 MSerial3(false, Serial3);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // ARDUINO_ARCH_SAM
|
#endif // ARDUINO_ARCH_SAM
|
@@ -16,83 +16,84 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HAL for Arduino Due and compatible (SAM3X8E)
|
* Description: HAL for Arduino Due and compatible (SAM3X8E)
|
||||||
|
*
|
||||||
|
* For ARDUINO_ARCH_SAM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define CPU_32_BIT
|
#define CPU_32_BIT
|
||||||
|
|
||||||
#include "../shared/Marduino.h"
|
#include "../shared/Marduino.h"
|
||||||
#include "../shared/eeprom_if.h"
|
|
||||||
#include "../shared/math_32bit.h"
|
#include "../shared/math_32bit.h"
|
||||||
#include "../shared/HAL_SPI.h"
|
#include "../shared/HAL_SPI.h"
|
||||||
#include "fastio.h"
|
#include "fastio.h"
|
||||||
#include "watchdog.h"
|
#include "watchdog.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "../../core/serial_hook.h"
|
// Define MYSERIAL0/1 before MarlinSerial includes!
|
||||||
|
#if SERIAL_PORT == -1
|
||||||
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
|
#define MYSERIAL0 customizedSerial1
|
||||||
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
|
#elif SERIAL_PORT == 0
|
||||||
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
|
#define MYSERIAL0 Serial
|
||||||
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
|
#elif SERIAL_PORT == 1
|
||||||
extern DefaultSerial1 MSerial0;
|
#define MYSERIAL0 Serial1
|
||||||
extern DefaultSerial2 MSerial1;
|
#elif SERIAL_PORT == 2
|
||||||
extern DefaultSerial3 MSerial2;
|
#define MYSERIAL0 Serial2
|
||||||
extern DefaultSerial4 MSerial3;
|
#elif SERIAL_PORT == 3
|
||||||
|
#define MYSERIAL0 Serial3
|
||||||
#define _MSERIAL(X) MSerial##X
|
|
||||||
#define MSERIAL(X) _MSERIAL(X)
|
|
||||||
|
|
||||||
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
|
|
||||||
#define MYSERIAL1 customizedSerial1
|
|
||||||
#elif WITHIN(SERIAL_PORT, 0, 3)
|
|
||||||
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
|
|
||||||
#else
|
#else
|
||||||
#error "The required SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
|
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_2
|
#ifdef SERIAL_PORT_2
|
||||||
#if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
|
#if SERIAL_PORT_2 == SERIAL_PORT
|
||||||
#define MYSERIAL2 customizedSerial2
|
#error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration."
|
||||||
#elif WITHIN(SERIAL_PORT_2, 0, 3)
|
#elif SERIAL_PORT_2 == -1
|
||||||
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
|
#define MYSERIAL1 customizedSerial2
|
||||||
|
#elif SERIAL_PORT_2 == 0
|
||||||
|
#define MYSERIAL1 Serial
|
||||||
|
#elif SERIAL_PORT_2 == 1
|
||||||
|
#define MYSERIAL1 Serial1
|
||||||
|
#elif SERIAL_PORT_2 == 2
|
||||||
|
#define MYSERIAL1 Serial2
|
||||||
|
#elif SERIAL_PORT_2 == 3
|
||||||
|
#define MYSERIAL1 Serial3
|
||||||
#else
|
#else
|
||||||
#error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial."
|
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
|
||||||
|
#endif
|
||||||
|
#define NUM_SERIAL 2
|
||||||
|
#else
|
||||||
|
#define NUM_SERIAL 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DGUS_SERIAL_PORT
|
||||||
|
#if DGUS_SERIAL_PORT == SERIAL_PORT
|
||||||
|
#error "DGUS_SERIAL_PORT must be different from SERIAL_PORT. Please update your configuration."
|
||||||
|
#elif defined(SERIAL_PORT_2) && DGUS_SERIAL_PORT == SERIAL_PORT_2
|
||||||
|
#error "DGUS_SERIAL_PORT must be different than SERIAL_PORT_2. Please update your configuration."
|
||||||
|
#elif DGUS_SERIAL_PORT == -1
|
||||||
|
#define DGUS_SERIAL internalDgusSerial
|
||||||
|
#elif DGUS_SERIAL_PORT == 0
|
||||||
|
#define DGUS_SERIAL Serial
|
||||||
|
#elif DGUS_SERIAL_PORT == 1
|
||||||
|
#define DGUS_SERIAL Serial1
|
||||||
|
#elif DGUS_SERIAL_PORT == 2
|
||||||
|
#define DGUS_SERIAL Serial2
|
||||||
|
#elif DGUS_SERIAL_PORT == 3
|
||||||
|
#define DGUS_SERIAL Serial3
|
||||||
|
#else
|
||||||
|
#error "DGUS_SERIAL_PORT must be from -1 to 3. Please update your configuration."
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef SERIAL_PORT_3
|
|
||||||
#if SERIAL_PORT_3 == -1 || ENABLED(EMERGENCY_PARSER)
|
|
||||||
#define MYSERIAL3 customizedSerial3
|
|
||||||
#elif WITHIN(SERIAL_PORT_3, 0, 3)
|
|
||||||
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
|
|
||||||
#else
|
|
||||||
#error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef MMU2_SERIAL_PORT
|
|
||||||
#if WITHIN(MMU2_SERIAL_PORT, 0, 3)
|
|
||||||
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
|
|
||||||
#else
|
|
||||||
#error "MMU2_SERIAL_PORT must be from 0 to 3."
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef LCD_SERIAL_PORT
|
|
||||||
#if WITHIN(LCD_SERIAL_PORT, 0, 3)
|
|
||||||
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
|
|
||||||
#else
|
|
||||||
#error "LCD_SERIAL_PORT must be from 0 to 3."
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "MarlinSerial.h"
|
#include "MarlinSerial.h"
|
||||||
#include "MarlinSerialUSB.h"
|
#include "MarlinSerialUSB.h"
|
||||||
@@ -100,6 +101,16 @@ extern DefaultSerial4 MSerial3;
|
|||||||
// On AVR this is in math.h?
|
// On AVR this is in math.h?
|
||||||
#define square(x) ((x)*(x))
|
#define square(x) ((x)*(x))
|
||||||
|
|
||||||
|
#ifndef strncpy_P
|
||||||
|
#define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Fix bug in pgm_read_ptr
|
||||||
|
#undef pgm_read_ptr
|
||||||
|
#define pgm_read_ptr(addr) (*((void**)(addr)))
|
||||||
|
#undef pgm_read_word
|
||||||
|
#define pgm_read_word(addr) (*((uint16_t*)(addr)))
|
||||||
|
|
||||||
typedef int8_t pin_t;
|
typedef int8_t pin_t;
|
||||||
|
|
||||||
#define SHARED_SERVOS HAS_SERVOS
|
#define SHARED_SERVOS HAS_SERVOS
|
||||||
@@ -120,7 +131,13 @@ void sei(); // Enable interrupts
|
|||||||
void HAL_clear_reset_source(); // clear reset reason
|
void HAL_clear_reset_source(); // clear reset reason
|
||||||
uint8_t HAL_get_reset_source(); // get reset reason
|
uint8_t HAL_get_reset_source(); // get reset reason
|
||||||
|
|
||||||
void HAL_reboot();
|
//
|
||||||
|
// EEPROM
|
||||||
|
//
|
||||||
|
void eeprom_write_byte(uint8_t *pos, unsigned char value);
|
||||||
|
uint8_t eeprom_read_byte(uint8_t *pos);
|
||||||
|
void eeprom_read_block (void *__dst, const void *__src, size_t __n);
|
||||||
|
void eeprom_update_block (const void *__src, void *__dst, size_t __n);
|
||||||
|
|
||||||
//
|
//
|
||||||
// ADC
|
// ADC
|
||||||
@@ -128,16 +145,15 @@ void HAL_reboot();
|
|||||||
extern uint16_t HAL_adc_result; // result of last ADC conversion
|
extern uint16_t HAL_adc_result; // result of last ADC conversion
|
||||||
|
|
||||||
#ifndef analogInputToDigitalPin
|
#ifndef analogInputToDigitalPin
|
||||||
#define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
|
#define analogInputToDigitalPin(p) ((p < 12u) ? (p) + 54u : -1)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define HAL_ANALOG_SELECT(ch)
|
#define HAL_ANALOG_SELECT(ch)
|
||||||
|
|
||||||
inline void HAL_adc_init() {}//todo
|
inline void HAL_adc_init() {}//todo
|
||||||
|
|
||||||
#define HAL_ADC_VREF 3.3
|
|
||||||
#define HAL_ADC_RESOLUTION 10
|
|
||||||
#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
|
#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
|
||||||
|
#define HAL_ADC_RESOLUTION 10
|
||||||
#define HAL_READ_ADC() HAL_adc_result
|
#define HAL_READ_ADC() HAL_adc_result
|
||||||
#define HAL_ADC_READY() true
|
#define HAL_ADC_READY() true
|
||||||
|
|
||||||
@@ -168,16 +184,10 @@ void HAL_init();
|
|||||||
//
|
//
|
||||||
void _delay_ms(const int delay);
|
void _delay_ms(const int delay);
|
||||||
|
|
||||||
#if GCC_VERSION <= 50000
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int freeMemory();
|
int freeMemory();
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
#if GCC_VERSION <= 50000
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HAL for Arduino Due and compatible (SAM3X8E)
|
* Description: HAL for Arduino Due and compatible (SAM3X8E)
|
||||||
*
|
*
|
||||||
* For ARDUINO_ARCH_SAM
|
* For ARDUINO_ARCH_SAM
|
||||||
*/
|
*/
|
||||||
@@ -56,8 +56,8 @@
|
|||||||
#pragma GCC optimize (3)
|
#pragma GCC optimize (3)
|
||||||
|
|
||||||
typedef uint8_t (*pfnSpiTransfer)(uint8_t b);
|
typedef uint8_t (*pfnSpiTransfer)(uint8_t b);
|
||||||
typedef void (*pfnSpiRxBlock)(uint8_t *buf, uint32_t nbyte);
|
typedef void (*pfnSpiRxBlock)(uint8_t* buf, uint32_t nbyte);
|
||||||
typedef void (*pfnSpiTxBlock)(const uint8_t *buf, uint32_t nbyte);
|
typedef void (*pfnSpiTxBlock)(const uint8_t* buf, uint32_t nbyte);
|
||||||
|
|
||||||
/* ---------------- Macros to be able to access definitions from asm */
|
/* ---------------- Macros to be able to access definitions from asm */
|
||||||
#define _PORT(IO) DIO ## IO ## _WPORT
|
#define _PORT(IO) DIO ## IO ## _WPORT
|
||||||
@@ -69,10 +69,10 @@
|
|||||||
|
|
||||||
// run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
|
// run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
|
||||||
static uint8_t spiTransferTx0(uint8_t bout) { // using Mode 0
|
static uint8_t spiTransferTx0(uint8_t bout) { // using Mode 0
|
||||||
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
|
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
|
||||||
uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
|
uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
|
||||||
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
|
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
|
||||||
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
|
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
|
||||||
uint32_t idx = 0;
|
uint32_t idx = 0;
|
||||||
|
|
||||||
/* Negate bout, as the assembler requires a negated value */
|
/* Negate bout, as the assembler requires a negated value */
|
||||||
@@ -154,9 +154,9 @@
|
|||||||
static uint8_t spiTransferRx0(uint8_t) { // using Mode 0
|
static uint8_t spiTransferRx0(uint8_t) { // using Mode 0
|
||||||
uint32_t bin = 0;
|
uint32_t bin = 0;
|
||||||
uint32_t work = 0;
|
uint32_t work = 0;
|
||||||
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
|
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
|
||||||
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
|
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
|
||||||
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
|
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
|
||||||
|
|
||||||
/* The software SPI routine */
|
/* The software SPI routine */
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -225,36 +225,36 @@
|
|||||||
static uint8_t spiTransfer1(uint8_t b) { // using Mode 0
|
static uint8_t spiTransfer1(uint8_t b) { // using Mode 0
|
||||||
int bits = 8;
|
int bits = 8;
|
||||||
do {
|
do {
|
||||||
WRITE(SD_MOSI_PIN, b & 0x80);
|
WRITE(MOSI_PIN, b & 0x80);
|
||||||
b <<= 1; // little setup time
|
b <<= 1; // little setup time
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, HIGH);
|
WRITE(SCK_PIN, HIGH);
|
||||||
DELAY_NS(125); // 10 cycles @ 84mhz
|
DELAY_NS(125); // 10 cycles @ 84mhz
|
||||||
|
|
||||||
b |= (READ(SD_MISO_PIN) != 0);
|
b |= (READ(MISO_PIN) != 0);
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
DELAY_NS(125); // 10 cycles @ 84mhz
|
DELAY_NS(125); // 10 cycles @ 84mhz
|
||||||
} while (--bits);
|
} while (--bits);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
// all the others
|
// all the others
|
||||||
static uint16_t spiDelayNS = 4000; // 4000ns => 125khz
|
static uint32_t spiDelayCyclesX4 = (F_CPU) / 1000000; // 4µs => 125khz
|
||||||
|
|
||||||
static uint8_t spiTransferX(uint8_t b) { // using Mode 0
|
static uint8_t spiTransferX(uint8_t b) { // using Mode 0
|
||||||
int bits = 8;
|
int bits = 8;
|
||||||
do {
|
do {
|
||||||
WRITE(SD_MOSI_PIN, b & 0x80);
|
WRITE(MOSI_PIN, b & 0x80);
|
||||||
b <<= 1; // little setup time
|
b <<= 1; // little setup time
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, HIGH);
|
WRITE(SCK_PIN, HIGH);
|
||||||
DELAY_NS(spiDelayNS);
|
__delay_4cycles(spiDelayCyclesX4);
|
||||||
|
|
||||||
b |= (READ(SD_MISO_PIN) != 0);
|
b |= (READ(MISO_PIN) != 0);
|
||||||
|
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
DELAY_NS(spiDelayNS);
|
__delay_4cycles(spiDelayCyclesX4);
|
||||||
} while (--bits);
|
} while (--bits);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
@@ -270,11 +270,11 @@
|
|||||||
static pfnSpiTransfer spiTransferTx = (pfnSpiTransfer)spiTransferX;
|
static pfnSpiTransfer spiTransferTx = (pfnSpiTransfer)spiTransferX;
|
||||||
|
|
||||||
// Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
|
// Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
|
||||||
static void spiTxBlock0(const uint8_t *ptr, uint32_t todo) {
|
static void spiTxBlock0(const uint8_t* ptr, uint32_t todo) {
|
||||||
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
|
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
|
||||||
uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
|
uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
|
||||||
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
|
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
|
||||||
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
|
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
|
||||||
uint32_t work = 0;
|
uint32_t work = 0;
|
||||||
uint32_t txval = 0;
|
uint32_t txval = 0;
|
||||||
|
|
||||||
@@ -349,12 +349,12 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spiRxBlock0(uint8_t *ptr, uint32_t todo) {
|
static void spiRxBlock0(uint8_t* ptr, uint32_t todo) {
|
||||||
uint32_t bin = 0;
|
uint32_t bin = 0;
|
||||||
uint32_t work = 0;
|
uint32_t work = 0;
|
||||||
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
|
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
|
||||||
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
|
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
|
||||||
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
|
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
|
||||||
|
|
||||||
/* The software SPI routine */
|
/* The software SPI routine */
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
@@ -425,48 +425,48 @@
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spiTxBlockX(const uint8_t *buf, uint32_t todo) {
|
static void spiTxBlockX(const uint8_t* buf, uint32_t todo) {
|
||||||
do {
|
do {
|
||||||
(void)spiTransferTx(*buf++);
|
(void)spiTransferTx(*buf++);
|
||||||
} while (--todo);
|
} while (--todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spiRxBlockX(uint8_t *buf, uint32_t todo) {
|
static void spiRxBlockX(uint8_t* buf, uint32_t todo) {
|
||||||
do {
|
do {
|
||||||
*buf++ = spiTransferRx(0xFF);
|
*buf++ = spiTransferRx(0xFF);
|
||||||
} while (--todo);
|
} while (--todo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pointers to generic functions for block transfers
|
// Pointers to generic functions for block tranfers
|
||||||
static pfnSpiTxBlock spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
|
static pfnSpiTxBlock spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
|
||||||
static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
|
static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
|
||||||
|
|
||||||
#if MB(ALLIGATOR)
|
#if MB(ALLIGATOR)
|
||||||
#define _SS_WRITE(S) WRITE(SD_SS_PIN, S)
|
#define _SS_WRITE(S) WRITE(SS_PIN, S)
|
||||||
#else
|
#else
|
||||||
#define _SS_WRITE(S) NOOP
|
#define _SS_WRITE(S) NOOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void spiBegin() {
|
void spiBegin() {
|
||||||
SET_OUTPUT(SD_SS_PIN);
|
SET_OUTPUT(SS_PIN);
|
||||||
_SS_WRITE(HIGH);
|
_SS_WRITE(HIGH);
|
||||||
SET_OUTPUT(SD_SCK_PIN);
|
SET_OUTPUT(SCK_PIN);
|
||||||
SET_INPUT(SD_MISO_PIN);
|
SET_INPUT(MISO_PIN);
|
||||||
SET_OUTPUT(SD_MOSI_PIN);
|
SET_OUTPUT(MOSI_PIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t spiRec() {
|
uint8_t spiRec() {
|
||||||
_SS_WRITE(LOW);
|
_SS_WRITE(LOW);
|
||||||
WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
|
WRITE(MOSI_PIN, HIGH); // Output 1s 1
|
||||||
uint8_t b = spiTransferRx(0xFF);
|
uint8_t b = spiTransferRx(0xFF);
|
||||||
_SS_WRITE(HIGH);
|
_SS_WRITE(HIGH);
|
||||||
return b;
|
return b;
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
if (nbyte) {
|
if (nbyte) {
|
||||||
_SS_WRITE(LOW);
|
_SS_WRITE(LOW);
|
||||||
WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
|
WRITE(MOSI_PIN, HIGH); // Output 1s 1
|
||||||
spiRxBlock(buf, nbyte);
|
spiRxBlock(buf, nbyte);
|
||||||
_SS_WRITE(HIGH);
|
_SS_WRITE(HIGH);
|
||||||
}
|
}
|
||||||
@@ -478,7 +478,7 @@
|
|||||||
_SS_WRITE(HIGH);
|
_SS_WRITE(HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
_SS_WRITE(LOW);
|
_SS_WRITE(LOW);
|
||||||
(void)spiTransferTx(token);
|
(void)spiTransferTx(token);
|
||||||
spiTxBlock(buf, 512);
|
spiTxBlock(buf, 512);
|
||||||
@@ -510,7 +510,7 @@
|
|||||||
spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
|
spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
spiDelayNS = 4000 >> (6 - spiRate); // spiRate of 2 gives the maximum error with current CPU
|
spiDelayCyclesX4 = ((F_CPU) / 1000000) >> (6 - spiRate);
|
||||||
spiTransferTx = (pfnSpiTransfer)spiTransferX;
|
spiTransferTx = (pfnSpiTransfer)spiTransferX;
|
||||||
spiTransferRx = (pfnSpiTransfer)spiTransferX;
|
spiTransferRx = (pfnSpiTransfer)spiTransferX;
|
||||||
spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
|
spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
|
||||||
@@ -519,8 +519,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
_SS_WRITE(HIGH);
|
_SS_WRITE(HIGH);
|
||||||
WRITE(SD_MOSI_PIN, HIGH);
|
WRITE(MOSI_PIN, HIGH);
|
||||||
WRITE(SD_SCK_PIN, LOW);
|
WRITE(SCK_PIN, LOW);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Begin SPI transaction, set clock, bit order, data mode */
|
/** Begin SPI transaction, set clock, bit order, data mode */
|
||||||
@@ -575,34 +575,38 @@
|
|||||||
|
|
||||||
// Configure SPI pins
|
// Configure SPI pins
|
||||||
PIO_Configure(
|
PIO_Configure(
|
||||||
g_APinDescription[SD_SCK_PIN].pPort,
|
g_APinDescription[SCK_PIN].pPort,
|
||||||
g_APinDescription[SD_SCK_PIN].ulPinType,
|
g_APinDescription[SCK_PIN].ulPinType,
|
||||||
g_APinDescription[SD_SCK_PIN].ulPin,
|
g_APinDescription[SCK_PIN].ulPin,
|
||||||
g_APinDescription[SD_SCK_PIN].ulPinConfiguration);
|
g_APinDescription[SCK_PIN].ulPinConfiguration);
|
||||||
PIO_Configure(
|
PIO_Configure(
|
||||||
g_APinDescription[SD_MOSI_PIN].pPort,
|
g_APinDescription[MOSI_PIN].pPort,
|
||||||
g_APinDescription[SD_MOSI_PIN].ulPinType,
|
g_APinDescription[MOSI_PIN].ulPinType,
|
||||||
g_APinDescription[SD_MOSI_PIN].ulPin,
|
g_APinDescription[MOSI_PIN].ulPin,
|
||||||
g_APinDescription[SD_MOSI_PIN].ulPinConfiguration);
|
g_APinDescription[MOSI_PIN].ulPinConfiguration);
|
||||||
PIO_Configure(
|
PIO_Configure(
|
||||||
g_APinDescription[SD_MISO_PIN].pPort,
|
g_APinDescription[MISO_PIN].pPort,
|
||||||
g_APinDescription[SD_MISO_PIN].ulPinType,
|
g_APinDescription[MISO_PIN].ulPinType,
|
||||||
g_APinDescription[SD_MISO_PIN].ulPin,
|
g_APinDescription[MISO_PIN].ulPin,
|
||||||
g_APinDescription[SD_MISO_PIN].ulPinConfiguration);
|
g_APinDescription[MISO_PIN].ulPinConfiguration);
|
||||||
|
|
||||||
// set master mode, peripheral select, fault detection
|
// set master mode, peripheral select, fault detection
|
||||||
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS);
|
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS);
|
||||||
SPI_Enable(SPI0);
|
SPI_Enable(SPI0);
|
||||||
|
|
||||||
SET_OUTPUT(DAC0_SYNC_PIN);
|
SET_OUTPUT(DAC0_SYNC);
|
||||||
#if HAS_MULTI_EXTRUDER
|
#if EXTRUDERS > 1
|
||||||
OUT_WRITE(DAC1_SYNC_PIN, HIGH);
|
SET_OUTPUT(DAC1_SYNC);
|
||||||
|
WRITE(DAC1_SYNC, HIGH);
|
||||||
#endif
|
#endif
|
||||||
WRITE(DAC0_SYNC_PIN, HIGH);
|
SET_OUTPUT(SPI_EEPROM1_CS);
|
||||||
OUT_WRITE(SPI_EEPROM1_CS_PIN, HIGH);
|
SET_OUTPUT(SPI_EEPROM2_CS);
|
||||||
OUT_WRITE(SPI_EEPROM2_CS_PIN, HIGH);
|
SET_OUTPUT(SPI_FLASH_CS);
|
||||||
OUT_WRITE(SPI_FLASH_CS_PIN, HIGH);
|
WRITE(DAC0_SYNC, HIGH);
|
||||||
WRITE(SD_SS_PIN, HIGH);
|
WRITE(SPI_EEPROM1_CS, HIGH);
|
||||||
|
WRITE(SPI_EEPROM2_CS, HIGH);
|
||||||
|
WRITE(SPI_FLASH_CS, HIGH);
|
||||||
|
WRITE(SS_PIN, HIGH);
|
||||||
|
|
||||||
OUT_WRITE(SDSS, LOW);
|
OUT_WRITE(SDSS, LOW);
|
||||||
|
|
||||||
@@ -641,7 +645,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read from SPI into buffer
|
// Read from SPI into buffer
|
||||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
if (!nbyte) return;
|
if (!nbyte) return;
|
||||||
--nbyte;
|
--nbyte;
|
||||||
for (int i = 0; i < nbyte; i++) {
|
for (int i = 0; i < nbyte; i++) {
|
||||||
@@ -664,7 +668,7 @@
|
|||||||
//DELAY_US(1U);
|
//DELAY_US(1U);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(const uint8_t *buf, size_t nbyte) {
|
void spiSend(const uint8_t* buf, size_t nbyte) {
|
||||||
if (!nbyte) return;
|
if (!nbyte) return;
|
||||||
--nbyte;
|
--nbyte;
|
||||||
for (size_t i = 0; i < nbyte; i++) {
|
for (size_t i = 0; i < nbyte; i++) {
|
||||||
@@ -685,7 +689,7 @@
|
|||||||
FLUSH_RX();
|
FLUSH_RX();
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {
|
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
|
||||||
if (!nbyte) return;
|
if (!nbyte) return;
|
||||||
--nbyte;
|
--nbyte;
|
||||||
for (size_t i = 0; i < nbyte; i++) {
|
for (size_t i = 0; i < nbyte; i++) {
|
||||||
@@ -698,7 +702,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write from buffer to SPI
|
// Write from buffer to SPI
|
||||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
SPI0->SPI_TDR = (uint32_t)token | SPI_PCS(SPI_CHAN);
|
SPI0->SPI_TDR = (uint32_t)token | SPI_PCS(SPI_CHAN);
|
||||||
WHILE_TX(0);
|
WHILE_TX(0);
|
||||||
//WHILE_RX(0);
|
//WHILE_RX(0);
|
||||||
@@ -755,6 +759,7 @@
|
|||||||
*
|
*
|
||||||
* All of the above can be avoided by defining FORCE_SOFT_SPI to force the
|
* All of the above can be avoided by defining FORCE_SOFT_SPI to force the
|
||||||
* display to use software SPI.
|
* display to use software SPI.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified)
|
void spiInit(uint8_t spiRate=6) { // Default to slowest rate if not specified)
|
||||||
@@ -797,19 +802,19 @@
|
|||||||
|
|
||||||
uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); }
|
uint8_t spiRec() { return (uint8_t)spiTransfer(0xFF); }
|
||||||
|
|
||||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
void spiRead(uint8_t* buf, uint16_t nbyte) {
|
||||||
for (int i = 0; i < nbyte; i++)
|
for (int i = 0; i < nbyte; i++)
|
||||||
buf[i] = spiTransfer(0xFF);
|
buf[i] = spiTransfer(0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSend(uint8_t data) { spiTransfer(data); }
|
void spiSend(uint8_t data) { spiTransfer(data); }
|
||||||
|
|
||||||
void spiSend(const uint8_t *buf, size_t nbyte) {
|
void spiSend(const uint8_t* buf, size_t nbyte) {
|
||||||
for (uint16_t i = 0; i < nbyte; i++)
|
for (uint16_t i = 0; i < nbyte; i++)
|
||||||
spiTransfer(buf[i]);
|
spiTransfer(buf[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
void spiSendBlock(uint8_t token, const uint8_t* buf) {
|
||||||
spiTransfer(token);
|
spiTransfer(token);
|
||||||
for (uint16_t i = 0; i < 512; i++)
|
for (uint16_t i = 0; i < 512; i++)
|
||||||
spiTransfer(buf[i]);
|
spiTransfer(buf[i]);
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ template<typename Cfg> typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSeria
|
|||||||
// A SW memory barrier, to ensure GCC does not overoptimize loops
|
// A SW memory barrier, to ensure GCC does not overoptimize loops
|
||||||
#define sw_barrier() asm volatile("": : :"memory");
|
#define sw_barrier() asm volatile("": : :"memory");
|
||||||
|
|
||||||
#include "../../feature/e_parser.h"
|
#include "../../feature/emergency_parser.h"
|
||||||
|
|
||||||
// (called with RX interrupts disabled)
|
// (called with RX interrupts disabled)
|
||||||
template<typename Cfg>
|
template<typename Cfg>
|
||||||
@@ -382,7 +382,7 @@ void MarlinSerial<Cfg>::flush() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename Cfg>
|
template<typename Cfg>
|
||||||
size_t MarlinSerial<Cfg>::write(const uint8_t c) {
|
void MarlinSerial<Cfg>::write(const uint8_t c) {
|
||||||
_written = true;
|
_written = true;
|
||||||
|
|
||||||
if (Cfg::TX_SIZE == 0) {
|
if (Cfg::TX_SIZE == 0) {
|
||||||
@@ -400,7 +400,7 @@ size_t MarlinSerial<Cfg>::write(const uint8_t c) {
|
|||||||
// XOFF char at the RX isr, but it is properly handled there
|
// XOFF char at the RX isr, but it is properly handled there
|
||||||
if (!(HWUART->UART_IMR & UART_IMR_TXRDY) && (HWUART->UART_SR & UART_SR_TXRDY)) {
|
if (!(HWUART->UART_IMR & UART_IMR_TXRDY) && (HWUART->UART_SR & UART_SR_TXRDY)) {
|
||||||
HWUART->UART_THR = c;
|
HWUART->UART_THR = c;
|
||||||
return 1;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
|
||||||
@@ -428,7 +428,6 @@ size_t MarlinSerial<Cfg>::write(const uint8_t c) {
|
|||||||
// Enable TX isr - Non atomic, but it will eventually enable TX isr
|
// Enable TX isr - Non atomic, but it will eventually enable TX isr
|
||||||
HWUART->UART_IER = UART_IER_TXRDY;
|
HWUART->UART_IER = UART_IER_TXRDY;
|
||||||
}
|
}
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Cfg>
|
template<typename Cfg>
|
||||||
@@ -474,21 +473,179 @@ void MarlinSerial<Cfg>::flushTX() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports from print.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(char c, int base) {
|
||||||
|
print((long)c, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(unsigned char b, int base) {
|
||||||
|
print((unsigned long)b, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(int n, int base) {
|
||||||
|
print((long)n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(unsigned int n, int base) {
|
||||||
|
print((unsigned long)n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(long n, int base) {
|
||||||
|
if (base == 0) write(n);
|
||||||
|
else if (base == 10) {
|
||||||
|
if (n < 0) { print('-'); n = -n; }
|
||||||
|
printNumber(n, 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(unsigned long n, int base) {
|
||||||
|
if (base == 0) write(n);
|
||||||
|
else printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::print(double n, int digits) {
|
||||||
|
printFloat(n, digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println() {
|
||||||
|
print('\r');
|
||||||
|
print('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(const String& s) {
|
||||||
|
print(s);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(const char c[]) {
|
||||||
|
print(c);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(char c, int base) {
|
||||||
|
print(c, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(unsigned char b, int base) {
|
||||||
|
print(b, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(int n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(unsigned int n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(long n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(unsigned long n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::println(double n, int digits) {
|
||||||
|
print(n, digits);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Methods
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::printNumber(unsigned long n, uint8_t base) {
|
||||||
|
if (n) {
|
||||||
|
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
|
||||||
|
int8_t i = 0;
|
||||||
|
while (n) {
|
||||||
|
buf[i++] = n % base;
|
||||||
|
n /= base;
|
||||||
|
}
|
||||||
|
while (i--)
|
||||||
|
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Cfg>
|
||||||
|
void MarlinSerial<Cfg>::printFloat(double number, uint8_t digits) {
|
||||||
|
// Handle negative numbers
|
||||||
|
if (number < 0.0) {
|
||||||
|
print('-');
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||||
|
double rounding = 0.5;
|
||||||
|
for (uint8_t i = 0; i < digits; ++i) rounding *= 0.1;
|
||||||
|
number += rounding;
|
||||||
|
|
||||||
|
// Extract the integer part of the number and print it
|
||||||
|
unsigned long int_part = (unsigned long)number;
|
||||||
|
double remainder = number - (double)int_part;
|
||||||
|
print(int_part);
|
||||||
|
|
||||||
|
// Print the decimal point, but only if there are digits beyond
|
||||||
|
if (digits) {
|
||||||
|
print('.');
|
||||||
|
// Extract digits from the remainder one at a time
|
||||||
|
while (digits--) {
|
||||||
|
remainder *= 10.0;
|
||||||
|
int toPrint = int(remainder);
|
||||||
|
print(toPrint);
|
||||||
|
remainder -= toPrint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If not using the USB port as serial port
|
// If not using the USB port as serial port
|
||||||
#if defined(SERIAL_PORT) && SERIAL_PORT >= 0
|
#if SERIAL_PORT >= 0
|
||||||
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT> >;
|
|
||||||
MSerialT1 customizedSerial1(MarlinSerialCfg<SERIAL_PORT>::EMERGENCYPARSER);
|
// Preinstantiate
|
||||||
|
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>;
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
|
#ifdef SERIAL_PORT_2
|
||||||
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> >;
|
|
||||||
MSerialT2 customizedSerial2(MarlinSerialCfg<SERIAL_PORT_2>::EMERGENCYPARSER);
|
// Preinstantiate
|
||||||
#endif
|
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>;
|
||||||
|
|
||||||
|
// Instantiate
|
||||||
|
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||||
|
|
||||||
#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0
|
|
||||||
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> >;
|
|
||||||
MSerialT3 customizedSerial3(MarlinSerialCfg<SERIAL_PORT_3>::EMERGENCYPARSER);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // ARDUINO_ARCH_SAM
|
#endif // ARDUINO_ARCH_SAM
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -27,10 +27,14 @@
|
|||||||
* Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
* Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "../shared/MarlinSerial.h"
|
||||||
|
|
||||||
#include <WString.h>
|
#include <WString.h>
|
||||||
|
|
||||||
#include "../../inc/MarlinConfigPre.h"
|
#define DEC 10
|
||||||
#include "../../core/serial_hook.h"
|
#define HEX 16
|
||||||
|
#define OCT 8
|
||||||
|
#define BIN 2
|
||||||
|
|
||||||
// Define constants and variables for buffering incoming serial data. We're
|
// Define constants and variables for buffering incoming serial data. We're
|
||||||
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
// using a ring buffer (I think), in which rx_buffer_head is the index of the
|
||||||
@@ -115,15 +119,42 @@ public:
|
|||||||
static int read();
|
static int read();
|
||||||
static void flush();
|
static void flush();
|
||||||
static ring_buffer_pos_t available();
|
static ring_buffer_pos_t available();
|
||||||
static size_t write(const uint8_t c);
|
static void write(const uint8_t c);
|
||||||
static void flushTX();
|
static void flushTX();
|
||||||
|
|
||||||
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
|
|
||||||
|
|
||||||
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
|
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
|
||||||
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
|
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
|
||||||
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
|
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
|
||||||
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
|
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
|
||||||
|
|
||||||
|
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
|
||||||
|
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
|
||||||
|
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
|
||||||
|
FORCE_INLINE static void print(const char* str) { write(str); }
|
||||||
|
|
||||||
|
static void print(char, int = 0);
|
||||||
|
static void print(unsigned char, int = 0);
|
||||||
|
static void print(int, int = DEC);
|
||||||
|
static void print(unsigned int, int = DEC);
|
||||||
|
static void print(long, int = DEC);
|
||||||
|
static void print(unsigned long, int = DEC);
|
||||||
|
static void print(double, int = 2);
|
||||||
|
|
||||||
|
static void println(const String& s);
|
||||||
|
static void println(const char[]);
|
||||||
|
static void println(char, int = 0);
|
||||||
|
static void println(unsigned char, int = 0);
|
||||||
|
static void println(int, int = DEC);
|
||||||
|
static void println(unsigned int, int = DEC);
|
||||||
|
static void println(long, int = DEC);
|
||||||
|
static void println(unsigned long, int = DEC);
|
||||||
|
static void println(double, int = 2);
|
||||||
|
static void println();
|
||||||
|
operator bool() { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void printNumber(unsigned long, const uint8_t);
|
||||||
|
static void printFloat(double, uint8_t);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Serial port configuration
|
// Serial port configuration
|
||||||
@@ -132,25 +163,22 @@ struct MarlinSerialCfg {
|
|||||||
static constexpr int PORT = serial;
|
static constexpr int PORT = serial;
|
||||||
static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE;
|
static constexpr unsigned int RX_SIZE = RX_BUFFER_SIZE;
|
||||||
static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE;
|
static constexpr unsigned int TX_SIZE = TX_BUFFER_SIZE;
|
||||||
static constexpr bool XONOFF = ENABLED(SERIAL_XON_XOFF);
|
static constexpr bool XONOFF = bSERIAL_XON_XOFF;
|
||||||
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
|
static constexpr bool EMERGENCYPARSER = bEMERGENCY_PARSER;
|
||||||
static constexpr bool DROPPED_RX = ENABLED(SERIAL_STATS_DROPPED_RX);
|
static constexpr bool DROPPED_RX = bSERIAL_STATS_DROPPED_RX;
|
||||||
static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
|
static constexpr bool RX_OVERRUNS = bSERIAL_STATS_RX_BUFFER_OVERRUNS;
|
||||||
static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
|
static constexpr bool RX_FRAMING_ERRORS = bSERIAL_STATS_RX_FRAMING_ERRORS;
|
||||||
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
|
static constexpr bool MAX_RX_QUEUED = bSERIAL_STATS_MAX_RX_QUEUED;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(SERIAL_PORT) && SERIAL_PORT >= 0
|
#if SERIAL_PORT >= 0
|
||||||
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT1;
|
|
||||||
extern MSerialT1 customizedSerial1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
|
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
|
||||||
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
|
|
||||||
extern MSerialT2 customizedSerial2;
|
#endif // SERIAL_PORT >= 0
|
||||||
#endif
|
|
||||||
|
#ifdef SERIAL_PORT_2
|
||||||
|
|
||||||
|
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
|
||||||
|
|
||||||
#if defined(SERIAL_PORT_3) && SERIAL_PORT_3 >= 0
|
|
||||||
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_3> > > MSerialT3;
|
|
||||||
extern MSerialT3 customizedSerial3;
|
|
||||||
#endif
|
#endif
|
290
Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.cpp
Normal file
290
Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.cpp
Normal file
@@ -0,0 +1,290 @@
|
|||||||
|
/**
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MarlinSerial_Due.cpp - Hardware serial library for Arduino DUE
|
||||||
|
* Copyright (c) 2017 Eduardo José Tagle. All right reserved
|
||||||
|
* Based on MarlinSerial for AVR, copyright (c) 2006 Nicholas Zambetti. All right reserved.
|
||||||
|
*/
|
||||||
|
#ifdef ARDUINO_ARCH_SAM
|
||||||
|
|
||||||
|
#include "../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
|
#if SERIAL_PORT == -1
|
||||||
|
|
||||||
|
#include "MarlinSerialUSB.h"
|
||||||
|
|
||||||
|
#if ENABLED(EMERGENCY_PARSER)
|
||||||
|
#include "../../feature/emergency_parser.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Imports from Atmel USB Stack/CDC implementation
|
||||||
|
extern "C" {
|
||||||
|
bool usb_task_cdc_isenabled();
|
||||||
|
bool usb_task_cdc_dtr_active();
|
||||||
|
bool udi_cdc_is_rx_ready();
|
||||||
|
int udi_cdc_getc();
|
||||||
|
bool udi_cdc_is_tx_ready();
|
||||||
|
int udi_cdc_putc(int value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Pending character
|
||||||
|
static int pending_char = -1;
|
||||||
|
|
||||||
|
#if ENABLED(EMERGENCY_PARSER)
|
||||||
|
static EmergencyParser::State emergency_state; // = EP_RESET
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Public Methods
|
||||||
|
void MarlinSerialUSB::begin(const long) {}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::end() {}
|
||||||
|
|
||||||
|
int MarlinSerialUSB::peek() {
|
||||||
|
if (pending_char >= 0)
|
||||||
|
return pending_char;
|
||||||
|
|
||||||
|
// If USB CDC not enumerated or not configured on the PC side
|
||||||
|
if (!usb_task_cdc_isenabled())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// If no bytes sent from the PC
|
||||||
|
if (!udi_cdc_is_rx_ready())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
pending_char = udi_cdc_getc();
|
||||||
|
|
||||||
|
#if ENABLED(EMERGENCY_PARSER)
|
||||||
|
emergency_parser.update(emergency_state, (char)pending_char);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return pending_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MarlinSerialUSB::read() {
|
||||||
|
if (pending_char >= 0) {
|
||||||
|
int ret = pending_char;
|
||||||
|
pending_char = -1;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If USB CDC not enumerated or not configured on the PC side
|
||||||
|
if (!usb_task_cdc_isenabled())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// If no bytes sent from the PC
|
||||||
|
if (!udi_cdc_is_rx_ready())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int c = udi_cdc_getc();
|
||||||
|
|
||||||
|
#if ENABLED(EMERGENCY_PARSER)
|
||||||
|
emergency_parser.update(emergency_state, (char)c);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MarlinSerialUSB::available() {
|
||||||
|
/* If Pending chars */
|
||||||
|
return pending_char >= 0 ||
|
||||||
|
/* or USB CDC enumerated and configured on the PC side and some
|
||||||
|
bytes where sent to us */
|
||||||
|
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::flush() { }
|
||||||
|
void MarlinSerialUSB::flushTX() { }
|
||||||
|
|
||||||
|
void MarlinSerialUSB::write(const uint8_t c) {
|
||||||
|
|
||||||
|
/* Do not even bother sending anything if USB CDC is not enumerated
|
||||||
|
or not configured on the PC side or there is no program on the PC
|
||||||
|
listening to our messages */
|
||||||
|
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* Wait until the PC has read the pending to be sent data */
|
||||||
|
while (usb_task_cdc_isenabled() &&
|
||||||
|
usb_task_cdc_dtr_active() &&
|
||||||
|
!udi_cdc_is_tx_ready()) {
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Do not even bother sending anything if USB CDC is not enumerated
|
||||||
|
or not configured on the PC side or there is no program on the PC
|
||||||
|
listening to our messages at this point */
|
||||||
|
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Fifo full
|
||||||
|
// udi_cdc_signal_overrun();
|
||||||
|
udi_cdc_putc(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports from print.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(char c, int base) {
|
||||||
|
print((long)c, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(unsigned char b, int base) {
|
||||||
|
print((unsigned long)b, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(int n, int base) {
|
||||||
|
print((long)n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(unsigned int n, int base) {
|
||||||
|
print((unsigned long)n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(long n, int base) {
|
||||||
|
if (base == 0)
|
||||||
|
write(n);
|
||||||
|
else if (base == 10) {
|
||||||
|
if (n < 0) {
|
||||||
|
print('-');
|
||||||
|
n = -n;
|
||||||
|
}
|
||||||
|
printNumber(n, 10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(unsigned long n, int base) {
|
||||||
|
if (base == 0) write(n);
|
||||||
|
else printNumber(n, base);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::print(double n, int digits) {
|
||||||
|
printFloat(n, digits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println() {
|
||||||
|
print('\r');
|
||||||
|
print('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(const String& s) {
|
||||||
|
print(s);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(const char c[]) {
|
||||||
|
print(c);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(char c, int base) {
|
||||||
|
print(c, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(unsigned char b, int base) {
|
||||||
|
print(b, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(int n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(unsigned int n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(long n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(unsigned long n, int base) {
|
||||||
|
print(n, base);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::println(double n, int digits) {
|
||||||
|
print(n, digits);
|
||||||
|
println();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Private Methods
|
||||||
|
|
||||||
|
void MarlinSerialUSB::printNumber(unsigned long n, uint8_t base) {
|
||||||
|
if (n) {
|
||||||
|
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
|
||||||
|
int8_t i = 0;
|
||||||
|
while (n) {
|
||||||
|
buf[i++] = n % base;
|
||||||
|
n /= base;
|
||||||
|
}
|
||||||
|
while (i--)
|
||||||
|
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
print('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarlinSerialUSB::printFloat(double number, uint8_t digits) {
|
||||||
|
// Handle negative numbers
|
||||||
|
if (number < 0.0) {
|
||||||
|
print('-');
|
||||||
|
number = -number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round correctly so that print(1.999, 2) prints as "2.00"
|
||||||
|
double rounding = 0.5;
|
||||||
|
for (uint8_t i = 0; i < digits; ++i)
|
||||||
|
rounding *= 0.1;
|
||||||
|
|
||||||
|
number += rounding;
|
||||||
|
|
||||||
|
// Extract the integer part of the number and print it
|
||||||
|
unsigned long int_part = (unsigned long)number;
|
||||||
|
double remainder = number - (double)int_part;
|
||||||
|
print(int_part);
|
||||||
|
|
||||||
|
// Print the decimal point, but only if there are digits beyond
|
||||||
|
if (digits) {
|
||||||
|
print('.');
|
||||||
|
// Extract digits from the remainder one at a time
|
||||||
|
while (digits--) {
|
||||||
|
remainder *= 10.0;
|
||||||
|
int toPrint = int(remainder);
|
||||||
|
print(toPrint);
|
||||||
|
remainder -= toPrint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Preinstantiate
|
||||||
|
MarlinSerialUSB customizedSerial1;
|
||||||
|
|
||||||
|
#endif // SERIAL_PORT == -1
|
||||||
|
|
||||||
|
#endif // ARDUINO_ARCH_SAM
|
93
Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.h
Normal file
93
Marlin/src/HAL/HAL_DUE/MarlinSerialUSB.h
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MarlinSerialUSB_Due.h - Hardware Serial over USB (CDC) library for Arduino DUE
|
||||||
|
* Copyright (c) 2017 Eduardo José Tagle. All right reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
|
#if SERIAL_PORT == -1
|
||||||
|
|
||||||
|
#include <WString.h>
|
||||||
|
|
||||||
|
#define DEC 10
|
||||||
|
#define HEX 16
|
||||||
|
#define OCT 8
|
||||||
|
#define BIN 2
|
||||||
|
|
||||||
|
class MarlinSerialUSB {
|
||||||
|
|
||||||
|
public:
|
||||||
|
MarlinSerialUSB() {};
|
||||||
|
static void begin(const long);
|
||||||
|
static void end();
|
||||||
|
static int peek();
|
||||||
|
static int read();
|
||||||
|
static void flush();
|
||||||
|
static void flushTX();
|
||||||
|
static bool available();
|
||||||
|
static void write(const uint8_t c);
|
||||||
|
|
||||||
|
#if ENABLED(SERIAL_STATS_DROPPED_RX)
|
||||||
|
FORCE_INLINE static uint32_t dropped() { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
|
||||||
|
FORCE_INLINE static int rxMaxEnqueued() { return 0; }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
|
||||||
|
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
|
||||||
|
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
|
||||||
|
FORCE_INLINE static void print(const char* str) { write(str); }
|
||||||
|
|
||||||
|
static void print(char, int = 0);
|
||||||
|
static void print(unsigned char, int = 0);
|
||||||
|
static void print(int, int = DEC);
|
||||||
|
static void print(unsigned int, int = DEC);
|
||||||
|
static void print(long, int = DEC);
|
||||||
|
static void print(unsigned long, int = DEC);
|
||||||
|
static void print(double, int = 2);
|
||||||
|
|
||||||
|
static void println(const String& s);
|
||||||
|
static void println(const char[]);
|
||||||
|
static void println(char, int = 0);
|
||||||
|
static void println(unsigned char, int = 0);
|
||||||
|
static void println(int, int = DEC);
|
||||||
|
static void println(unsigned int, int = DEC);
|
||||||
|
static void println(long, int = DEC);
|
||||||
|
static void println(unsigned long, int = DEC);
|
||||||
|
static void println(double, int = 2);
|
||||||
|
static void println();
|
||||||
|
operator bool() { return true; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void printNumber(unsigned long, const uint8_t);
|
||||||
|
static void printFloat(double, uint8_t);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern MarlinSerialUSB customizedSerial1;
|
||||||
|
|
||||||
|
#endif // SERIAL_PORT == -1
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
#if HAS_SERVOS
|
#if HAS_SERVOS
|
||||||
|
|
||||||
|
#include "../shared/Marduino.h"
|
||||||
#include "../shared/servo.h"
|
#include "../shared/servo.h"
|
||||||
#include "../shared/servo_private.h"
|
#include "../shared/servo_private.h"
|
||||||
|
|
@@ -18,19 +18,20 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description: Tone function for Arduino Due and compatible (SAM3X8E)
|
* Description: Tone function for Arduino Due and compatible (SAM3X8E)
|
||||||
* Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
|
* Derived from http://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ARDUINO_ARCH_SAM
|
#ifdef ARDUINO_ARCH_SAM
|
||||||
|
|
||||||
#include "../../inc/MarlinConfig.h"
|
#include "../../inc/MarlinConfig.h"
|
||||||
#include "HAL.h"
|
#include "HAL.h"
|
||||||
|
#include "timers.h"
|
||||||
|
|
||||||
static pin_t tone_pin;
|
static pin_t tone_pin;
|
||||||
volatile static int32_t toggles;
|
volatile static int32_t toggles;
|
@@ -16,10 +16,11 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Based on u8g_com_msp430_hw_spi.c
|
* Based on u8g_com_msp430_hw_spi.c
|
||||||
*
|
*
|
||||||
@@ -51,23 +52,25 @@
|
|||||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __SAM3X8E__
|
#ifdef __SAM3X8E__
|
||||||
|
|
||||||
#include "../../../inc/MarlinConfigPre.h"
|
#include "../../../inc/MarlinConfigPre.h"
|
||||||
|
|
||||||
#if HAS_MARLINUI_U8GLIB
|
#if HAS_GRAPHICAL_LCD
|
||||||
|
|
||||||
#include <U8glib-HAL.h>
|
#include <U8glib.h>
|
||||||
|
|
||||||
#include "../../../MarlinCore.h"
|
#include "../../../MarlinCore.h"
|
||||||
|
|
||||||
#ifndef LCD_SPI_SPEED
|
void spiBegin();
|
||||||
#define LCD_SPI_SPEED SPI_QUARTER_SPEED
|
void spiInit(uint8_t spiRate);
|
||||||
#endif
|
void spiSend(uint8_t b);
|
||||||
|
void spiSend(const uint8_t* buf, size_t n);
|
||||||
|
|
||||||
#include "../../shared/HAL_SPI.h"
|
#include "../../shared/Marduino.h"
|
||||||
#include "../fastio.h"
|
#include "../fastio.h"
|
||||||
|
|
||||||
void u8g_SetPIOutput_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index) {
|
void u8g_SetPIOutput_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index) {
|
||||||
@@ -98,7 +101,11 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
|
|||||||
|
|
||||||
spiBegin();
|
spiBegin();
|
||||||
|
|
||||||
spiInit(LCD_SPI_SPEED);
|
#ifndef SPI_SPEED
|
||||||
|
#define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
|
||||||
|
#endif
|
||||||
|
spiInit(2);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||||
@@ -138,6 +145,6 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_MARLINUI_U8GLIB
|
#endif // HAS_GRAPHICAL_LCD
|
||||||
|
|
||||||
#endif // __SAM3X8E__
|
#endif //__SAM3X8E__
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -59,10 +59,9 @@
|
|||||||
|
|
||||||
#if ENABLED(U8GLIB_ST7920)
|
#if ENABLED(U8GLIB_ST7920)
|
||||||
|
|
||||||
#include "../../../inc/MarlinConfig.h"
|
|
||||||
#include "../../shared/Delay.h"
|
#include "../../shared/Delay.h"
|
||||||
|
|
||||||
#include <U8glib-HAL.h>
|
#include <U8glib.h>
|
||||||
|
|
||||||
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
|
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
|
||||||
|
|
||||||
@@ -146,7 +145,7 @@ uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ENABLED(LIGHTWEIGHT_UI)
|
#if ENABLED(LIGHTWEIGHT_UI)
|
||||||
#include "../../../lcd/marlinui.h"
|
#include "../../../lcd/ultralcd.h"
|
||||||
#include "../../shared/HAL_ST7920.h"
|
#include "../../shared/HAL_ST7920.h"
|
||||||
|
|
||||||
#define ST7920_CS_PIN LCD_PINS_RS
|
#define ST7920_CS_PIN LCD_PINS_RS
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -57,14 +57,17 @@
|
|||||||
|
|
||||||
#include "../../../inc/MarlinConfigPre.h"
|
#include "../../../inc/MarlinConfigPre.h"
|
||||||
|
|
||||||
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
|
#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
|
||||||
|
|
||||||
|
#undef SPI_SPEED
|
||||||
|
#define SPI_SPEED 2 // About 2 MHz
|
||||||
|
|
||||||
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
|
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
|
||||||
|
|
||||||
#include "../../shared/Marduino.h"
|
#include "../../shared/Marduino.h"
|
||||||
#include "../../shared/Delay.h"
|
#include "../../shared/Delay.h"
|
||||||
|
|
||||||
#include <U8glib-HAL.h>
|
#include <U8glib.h>
|
||||||
|
|
||||||
#if ENABLED(FYSETC_MINI_12864)
|
#if ENABLED(FYSETC_MINI_12864)
|
||||||
#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_3
|
#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_3
|
||||||
@@ -141,5 +144,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
|
#endif // HAS_GRAPHICAL_LCD && !U8GLIB_ST7920
|
||||||
#endif // ARDUINO_ARCH_SAM
|
#endif // ARDUINO_ARCH_SAM
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -57,12 +57,11 @@
|
|||||||
|
|
||||||
#include "../../../inc/MarlinConfigPre.h"
|
#include "../../../inc/MarlinConfigPre.h"
|
||||||
|
|
||||||
#if HAS_MARLINUI_U8GLIB
|
#if HAS_GRAPHICAL_LCD
|
||||||
|
|
||||||
#include "../../../inc/MarlinConfig.h"
|
|
||||||
#include "../../shared/Delay.h"
|
#include "../../shared/Delay.h"
|
||||||
|
|
||||||
#include <U8glib-HAL.h>
|
#include <U8glib.h>
|
||||||
|
|
||||||
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
|
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
|
||||||
|
|
||||||
@@ -81,7 +80,7 @@ Pio *SCK_pPio, *MOSI_pPio;
|
|||||||
uint32_t SCK_dwMask, MOSI_dwMask;
|
uint32_t SCK_dwMask, MOSI_dwMask;
|
||||||
|
|
||||||
void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz
|
void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz
|
||||||
LOOP_L_N(i, 8) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
if (val & 0x80)
|
if (val & 0x80)
|
||||||
MOSI_pPio->PIO_SODR = MOSI_dwMask;
|
MOSI_pPio->PIO_SODR = MOSI_dwMask;
|
||||||
else
|
else
|
||||||
@@ -95,7 +94,7 @@ void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz
|
|||||||
}
|
}
|
||||||
|
|
||||||
void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz
|
void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz
|
||||||
LOOP_L_N(i, 8) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
SCK_pPio->PIO_CODR = SCK_dwMask;
|
SCK_pPio->PIO_CODR = SCK_dwMask;
|
||||||
DELAY_NS(50);
|
DELAY_NS(50);
|
||||||
if (val & 0x80)
|
if (val & 0x80)
|
||||||
@@ -109,5 +108,5 @@ void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_MARLINUI_U8GLIB
|
#endif // HAS_GRAPHICAL_LCD
|
||||||
#endif // ARDUINO_ARCH_SAM
|
#endif // ARDUINO_ARCH_SAM
|
@@ -16,14 +16,14 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "../../../inc/MarlinConfigPre.h"
|
#include "../../../inc/MarlinConfigPre.h"
|
||||||
#include "../../shared/Marduino.h"
|
#include "../../shared/Marduino.h"
|
||||||
#include <U8glib-HAL.h>
|
#include <U8glib.h>
|
||||||
|
|
||||||
void u8g_SetPIOutput_DUE(u8g_t *u8g, uint8_t pin_index);
|
void u8g_SetPIOutput_DUE(u8g_t *u8g, uint8_t pin_index);
|
||||||
void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level);
|
void u8g_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level);
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -47,27 +47,43 @@ void endstop_ISR() { endstops.update(); }
|
|||||||
|
|
||||||
void setup_endstop_interrupts() {
|
void setup_endstop_interrupts() {
|
||||||
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
|
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
|
||||||
TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN));
|
#if HAS_X_MAX
|
||||||
TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN));
|
_ATTACH(X_MAX_PIN);
|
||||||
TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN));
|
#endif
|
||||||
TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN));
|
#if HAS_X_MIN
|
||||||
TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN));
|
_ATTACH(X_MIN_PIN);
|
||||||
TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN));
|
#endif
|
||||||
TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN));
|
#if HAS_Y_MAX
|
||||||
TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN));
|
_ATTACH(Y_MAX_PIN);
|
||||||
TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN));
|
#endif
|
||||||
TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN));
|
#if HAS_Y_MIN
|
||||||
TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN));
|
_ATTACH(Y_MIN_PIN);
|
||||||
TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN));
|
#endif
|
||||||
TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN));
|
#if HAS_Z_MAX
|
||||||
TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN));
|
_ATTACH(Z_MAX_PIN);
|
||||||
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
|
#endif
|
||||||
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
|
#if HAS_Z_MIN
|
||||||
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
|
_ATTACH(Z_MIN_PIN);
|
||||||
TERN_(HAS_I_MAX, _ATTACH(I_MAX_PIN));
|
#endif
|
||||||
TERN_(HAS_I_MIN, _ATTACH(I_MIN_PIN));
|
#if HAS_Z2_MAX
|
||||||
TERN_(HAS_J_MAX, _ATTACH(J_MAX_PIN));
|
_ATTACH(Z2_MAX_PIN);
|
||||||
TERN_(HAS_J_MIN, _ATTACH(J_MIN_PIN));
|
#endif
|
||||||
TERN_(HAS_K_MAX, _ATTACH(K_MAX_PIN));
|
#if HAS_Z2_MIN
|
||||||
TERN_(HAS_K_MIN, _ATTACH(K_MIN_PIN));
|
_ATTACH(Z2_MIN_PIN);
|
||||||
|
#endif
|
||||||
|
#if HAS_Z3_MAX
|
||||||
|
_ATTACH(Z3_MAX_PIN);
|
||||||
|
#endif
|
||||||
|
#if HAS_Z3_MIN
|
||||||
|
_ATTACH(Z3_MIN_PIN);
|
||||||
|
#endif
|
||||||
|
#if HAS_Z4_MAX
|
||||||
|
_ATTACH(Z4_MAX_PIN);
|
||||||
|
#endif
|
||||||
|
#if HAS_Z4_MIN
|
||||||
|
_ATTACH(Z4_MIN_PIN);
|
||||||
|
#endif
|
||||||
|
#if HAS_Z_MIN_PROBE_PIN
|
||||||
|
_ATTACH(Z_MIN_PROBE_PIN);
|
||||||
|
#endif
|
||||||
}
|
}
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -33,7 +33,7 @@
|
|||||||
* For ARDUINO_ARCH_SAM
|
* For ARDUINO_ARCH_SAM
|
||||||
* Note the code here was specifically crafted by disassembling what GCC produces
|
* Note the code here was specifically crafted by disassembling what GCC produces
|
||||||
* out of it, so GCC is able to optimize it out as much as possible to the least
|
* out of it, so GCC is able to optimize it out as much as possible to the least
|
||||||
* amount of instructions. Be very careful if you modify them, as "clean code"
|
* amount of instructions. Be very carefull if you modify them, as "clean code"
|
||||||
* leads to less efficient compiled code!!
|
* leads to less efficient compiled code!!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@
|
|||||||
#define PWM_PIN(P) WITHIN(P, 2, 13)
|
#define PWM_PIN(P) WITHIN(P, 2, 13)
|
||||||
|
|
||||||
#ifndef MASK
|
#ifndef MASK
|
||||||
#define MASK(PIN) _BV(PIN)
|
#define MASK(PIN) (1 << PIN)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +58,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 https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
* Why double up on these macros? see http://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Read a pin
|
// Read a pin
|
||||||
@@ -163,13 +163,10 @@
|
|||||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||||
// Set pin as input with pullup (wrapper)
|
// Set pin as input with pullup (wrapper)
|
||||||
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
|
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
|
||||||
// Set pin as input with pulldown (substitution)
|
|
||||||
#define SET_INPUT_PULLDOWN SET_INPUT
|
|
||||||
|
|
||||||
// Set pin as output (wrapper) - reads the pin and sets the output to that value
|
// Set pin as output (wrapper) - reads the pin and sets the output to that value
|
||||||
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
|
||||||
// Set pin as PWM
|
// Set pin as PWM
|
||||||
#define SET_PWM SET_OUTPUT
|
#define SET_PWM(IO) SET_OUTPUT(IO)
|
||||||
|
|
||||||
// Check if pin is an input
|
// Check if pin is an input
|
||||||
#define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0)
|
#define IS_INPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) == 0)
|
||||||
@@ -177,7 +174,7 @@
|
|||||||
#define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0)
|
#define IS_OUTPUT(IO) ((digitalPinToPort(IO)->PIO_OSR & digitalPinToBitMask(IO)) != 0)
|
||||||
|
|
||||||
// Shorthand
|
// Shorthand
|
||||||
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
|
#define OUT_WRITE(IO,V) { SET_OUTPUT(IO); WRITE(IO,V); }
|
||||||
|
|
||||||
// digitalRead/Write wrappers
|
// digitalRead/Write wrappers
|
||||||
#define extDigitalRead(IO) digitalRead(IO)
|
#define extDigitalRead(IO) digitalRead(IO)
|
||||||
@@ -480,7 +477,7 @@
|
|||||||
#define DIO91_PIN 15
|
#define DIO91_PIN 15
|
||||||
#define DIO91_WPORT PIOB
|
#define DIO91_WPORT PIOB
|
||||||
|
|
||||||
#ifdef ARDUINO_SAM_ARCHIM
|
#if ARDUINO_SAM_ARCHIM
|
||||||
|
|
||||||
#define DIO92_PIN 11
|
#define DIO92_PIN 11
|
||||||
#define DIO92_WPORT PIOC
|
#define DIO92_WPORT PIOC
|
145
Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp
Normal file
145
Marlin/src/HAL/HAL_DUE/fastio/G2_PWM.cpp
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
/**
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The PWM module is only used to generate interrupts at specified times. It
|
||||||
|
* is NOT used to directly toggle pins. The ISR writes to the pin assigned to
|
||||||
|
* that interrupt.
|
||||||
|
*
|
||||||
|
* All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to
|
||||||
|
* not have obvious ripple on the Vref signals.
|
||||||
|
*
|
||||||
|
* The data structures are setup to minimize the computation done by the ISR which
|
||||||
|
* minimizes ISR execution time. Execution times are 0.8 to 1.1 microseconds.
|
||||||
|
*
|
||||||
|
* FIve PWM interrupt sources are used. Channel 0 sets the base period. All Vref
|
||||||
|
* signals are set active when this counter overflows and resets to zero. The compare
|
||||||
|
* values in channels 1-4 are set to give the desired duty cycle for that Vref pin.
|
||||||
|
* When counter 0 matches the compare value then that channel generates an interrupt.
|
||||||
|
* The ISR checks the source of the interrupt and sets the corresponding pin inactive.
|
||||||
|
*
|
||||||
|
* Some jitter in the Vref signal is OK so the interrupt priority is left at its default value.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../../../inc/MarlinConfig.h"
|
||||||
|
|
||||||
|
#if MB(PRINTRBOARD_G2)
|
||||||
|
|
||||||
|
#include "G2_PWM.h"
|
||||||
|
|
||||||
|
volatile uint32_t *SODR_A = &PIOA->PIO_SODR,
|
||||||
|
*SODR_B = &PIOB->PIO_SODR,
|
||||||
|
*CODR_A = &PIOA->PIO_CODR,
|
||||||
|
*CODR_B = &PIOB->PIO_CODR;
|
||||||
|
|
||||||
|
PWM_map ISR_table[NUM_PWMS] = PWM_MAP_INIT;
|
||||||
|
|
||||||
|
void Stepper::digipot_init() {
|
||||||
|
|
||||||
|
OUT_WRITE(MOTOR_CURRENT_PWM_X_PIN, 0); // init pins
|
||||||
|
OUT_WRITE(MOTOR_CURRENT_PWM_Y_PIN, 0);
|
||||||
|
OUT_WRITE(MOTOR_CURRENT_PWM_Z_PIN, 0);
|
||||||
|
OUT_WRITE(MOTOR_CURRENT_PWM_E_PIN, 0);
|
||||||
|
|
||||||
|
#define WPKEY (0x50574D << 8) // “PWM” in ASCII
|
||||||
|
#define WPCMD_DIS_SW 0 // command to disable Write Protect SW
|
||||||
|
#define WPRG_ALL (PWM_WPCR_WPRG0 | PWM_WPCR_WPRG1 | PWM_WPCR_WPRG2 | PWM_WPCR_WPRG3 | PWM_WPCR_WPRG4 | PWM_WPCR_WPRG5) // all Write Protect Groups
|
||||||
|
|
||||||
|
#define PWM_CLOCK_F F_CPU / 1000000UL // set clock to 1MHz
|
||||||
|
|
||||||
|
PMC->PMC_PCER1 = PMC_PCER1_PID36; // enable PWM controller clock (disabled on power up)
|
||||||
|
|
||||||
|
PWM->PWM_WPCR = WPKEY | WPRG_ALL | WPCMD_DIS_SW; // enable setting of all PWM registers
|
||||||
|
PWM->PWM_CLK = PWM_CLOCK_F; // enable CLK_A and set it to 1MHz, leave CLK_B disabled
|
||||||
|
PWM->PWM_CH_NUM[0].PWM_CMR = 0b1011; // set channel 0 to Clock A input & to left aligned
|
||||||
|
PWM->PWM_CH_NUM[1].PWM_CMR = 0b1011; // set channel 1 to Clock A input & to left aligned
|
||||||
|
PWM->PWM_CH_NUM[2].PWM_CMR = 0b1011; // set channel 2 to Clock A input & to left aligned
|
||||||
|
PWM->PWM_CH_NUM[3].PWM_CMR = 0b1011; // set channel 3 to Clock A input & to left aligned
|
||||||
|
PWM->PWM_CH_NUM[4].PWM_CMR = 0b1011; // set channel 4 to Clock A input & to left aligned
|
||||||
|
|
||||||
|
PWM->PWM_CH_NUM[0].PWM_CPRD = PWM_PERIOD_US; // set channel 0 Period
|
||||||
|
|
||||||
|
PWM->PWM_IER2 = PWM_IER1_CHID0; // generate interrupt when counter0 overflows
|
||||||
|
PWM->PWM_IER2 = PWM_IER2_CMPM0 | PWM_IER2_CMPM1 | PWM_IER2_CMPM2 | PWM_IER2_CMPM3 | PWM_IER2_CMPM4; // generate interrupt on compare event
|
||||||
|
|
||||||
|
PWM->PWM_CMP[1].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 1 PWM inactive
|
||||||
|
PWM->PWM_CMP[2].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[0])); // interrupt when counter0 == CMPV - used to set Motor 2 PWM inactive
|
||||||
|
PWM->PWM_CMP[3].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[1])); // interrupt when counter0 == CMPV - used to set Motor 3 PWM inactive
|
||||||
|
PWM->PWM_CMP[4].PWM_CMPV = 0x010000000LL | G2_VREF_COUNT(G2_VREF(motor_current_setting[2])); // interrupt when counter0 == CMPV - used to set Motor 4 PWM inactive
|
||||||
|
|
||||||
|
PWM->PWM_CMP[1].PWM_CMPM = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_CMP[2].PWM_CMPM = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_CMP[3].PWM_CMPM = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_CMP[4].PWM_CMPM = 0x0001; // enable compare event
|
||||||
|
|
||||||
|
PWM->PWM_SCM = PWM_SCM_UPDM_MODE0 | PWM_SCM_SYNC0 | PWM_SCM_SYNC1 | PWM_SCM_SYNC2 | PWM_SCM_SYNC3 | PWM_SCM_SYNC4; // sync 1-4 with 0, use mode 0 for updates
|
||||||
|
|
||||||
|
PWM->PWM_ENA = PWM_ENA_CHID0 | PWM_ENA_CHID1 | PWM_ENA_CHID2 | PWM_ENA_CHID3 | PWM_ENA_CHID4; // enable the channels used by G2
|
||||||
|
PWM->PWM_IER1 = PWM_IER1_CHID0 | PWM_IER1_CHID1 | PWM_IER1_CHID2 | PWM_IER1_CHID3 | PWM_IER1_CHID4; // enable interrupts for the channels used by G2
|
||||||
|
|
||||||
|
NVIC_EnableIRQ(PWM_IRQn); // Enable interrupt handler
|
||||||
|
NVIC_SetPriority(PWM_IRQn, NVIC_EncodePriority(0, 10, 0)); // normal priority for PWM module (can stand some jitter on the Vref signals)
|
||||||
|
}
|
||||||
|
|
||||||
|
void Stepper::digipot_current(const uint8_t driver, const int16_t current) {
|
||||||
|
|
||||||
|
if (!(PWM->PWM_CH_NUM[0].PWM_CPRD == PWM_PERIOD_US)) digipot_init(); // Init PWM system if needed
|
||||||
|
|
||||||
|
switch (driver) {
|
||||||
|
case 0: PWM->PWM_CMP[1].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update X & Y
|
||||||
|
PWM->PWM_CMP[2].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current));
|
||||||
|
PWM->PWM_CMP[1].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_CMP[2].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||||
|
break;
|
||||||
|
case 1: PWM->PWM_CMP[3].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update Z
|
||||||
|
PWM->PWM_CMP[3].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||||
|
break;
|
||||||
|
default:PWM->PWM_CMP[4].PWM_CMPVUPD = 0x010000000LL | G2_VREF_COUNT(G2_VREF(current)); // update E
|
||||||
|
PWM->PWM_CMP[4].PWM_CMPMUPD = 0x0001; // enable compare event
|
||||||
|
PWM->PWM_SCUC = PWM_SCUC_UPDULOCK; // tell the PWM controller to update the values on the next cycle
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
volatile uint32_t PWM_ISR1_STATUS, PWM_ISR2_STATUS;
|
||||||
|
|
||||||
|
void PWM_Handler() {
|
||||||
|
PWM_ISR1_STATUS = PWM->PWM_ISR1;
|
||||||
|
PWM_ISR2_STATUS = PWM->PWM_ISR2;
|
||||||
|
if (PWM_ISR1_STATUS & PWM_IER1_CHID0) { // CHAN_0 interrupt
|
||||||
|
*ISR_table[0].set_register = ISR_table[0].write_mask; // set X to active
|
||||||
|
*ISR_table[1].set_register = ISR_table[1].write_mask; // set Y to active
|
||||||
|
*ISR_table[2].set_register = ISR_table[2].write_mask; // set Z to active
|
||||||
|
*ISR_table[3].set_register = ISR_table[3].write_mask; // set E to active
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (PWM_ISR2_STATUS & PWM_IER2_CMPM1) *ISR_table[0].clr_register = ISR_table[0].write_mask; // set X to inactive
|
||||||
|
if (PWM_ISR2_STATUS & PWM_IER2_CMPM2) *ISR_table[1].clr_register = ISR_table[1].write_mask; // set Y to inactive
|
||||||
|
if (PWM_ISR2_STATUS & PWM_IER2_CMPM3) *ISR_table[2].clr_register = ISR_table[2].write_mask; // set Z to inactive
|
||||||
|
if (PWM_ISR2_STATUS & PWM_IER2_CMPM4) *ISR_table[3].clr_register = ISR_table[3].write_mask; // set E to inactive
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // PRINTRBOARD_G2
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -63,7 +63,7 @@ extern PWM_map ISR_table[NUM_PWMS];
|
|||||||
extern uint32_t motor_current_setting[3];
|
extern uint32_t motor_current_setting[3];
|
||||||
|
|
||||||
#define IR_BIT(p) (WITHIN(p, 0, 3) ? (p) : (p) + 4)
|
#define IR_BIT(p) (WITHIN(p, 0, 3) ? (p) : (p) + 4)
|
||||||
#define COPY_ACTIVE_TABLE() do{ LOOP_L_N(i, 6) work_table[i] = active_table[i]; }while(0)
|
#define COPY_ACTIVE_TABLE() do{ for (uint8_t i = 0; i < 6 ; i++) work_table[i] = active_table[i]; }while(0)
|
||||||
|
|
||||||
#define PWM_MR0 19999 // base repetition rate minus one count - 20mS
|
#define PWM_MR0 19999 // base repetition rate minus one count - 20mS
|
||||||
#define PWM_PR 24 // prescaler value - prescaler divide by 24 + 1 - 1 MHz output
|
#define PWM_PR 24 // prescaler value - prescaler divide by 24 + 1 - 1 MHz output
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
@@ -16,7 +16,7 @@
|
|||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#pragma once
|
#pragma once
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user