Compare commits

..

2 Commits

Author SHA1 Message Date
Scott Lahteine
23775c0f2d 🔖 Marlin 2.0.8.3 2023-07-20 13:47:19 -05:00
Scott Lahteine
a5051f73bd 🔨 PlatformIO 6 compatibility 2023-07-20 13:47:19 -05:00
2485 changed files with 113450 additions and 268176 deletions

View File

@@ -1,29 +0,0 @@
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.187.0/containers/python-3/.devcontainer/base.Dockerfile
# [Choice] Python version: 3, 3.9, 3.8, 3.7, 3.6
ARG VARIANT="3.9.0-buster"
FROM python:${VARIANT}
# [Option] Install Node.js
ARG INSTALL_NODE="true"
ARG NODE_VERSION="lts/*"
RUN if [ "${INSTALL_NODE}" = "true" ]; then su vscode -c "umask 0002 && . /usr/local/share/nvm/nvm.sh && nvm install ${NODE_VERSION} 2>&1"; fi
# [Optional] If your pip requirements rarely change, uncomment this section to add them to the image.
# COPY requirements.txt /tmp/pip-tmp/
# RUN pip3 --disable-pip-version-check --no-cache-dir install -r /tmp/pip-tmp/requirements.txt \
# && rm -rf /tmp/pip-tmp
# [Optional] Uncomment this section to install additional OS packages.
# RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
# && apt-get -y install --no-install-recommends <your-package-list-here>
# [Optional] Uncomment this line to install global node packages.
# RUN su vscode -c "source /usr/local/share/nvm/nvm.sh && npm install -g <your-package-here>" 2>&1
RUN pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
RUN platformio update
# To get the test platforms
RUN pip install PyYaml
#ENV PATH /code/buildroot/bin/:/code/buildroot/tests/:${PATH}

View File

@@ -1,51 +0,0 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.187.0/containers/python-3
{
"name": "Python 3",
"build": {
"dockerfile": "Dockerfile",
"context": "..",
"args": {
// Update 'VARIANT' to pick a Python version: 3, 3.6, 3.7, 3.8, 3.9
"VARIANT": "3.9.0-buster",
// Options
"INSTALL_NODE": "false",
"NODE_VERSION": "lts/*"
}
},
// Set *default* container specific settings.json values on container create.
"settings": {
"python.pythonPath": "/usr/local/bin/python",
"python.languageServer": "Pylance",
"python.linting.enabled": true,
"python.linting.pylintEnabled": true,
"python.formatting.autopep8Path": "/usr/local/py-utils/bin/autopep8",
"python.formatting.blackPath": "/usr/local/py-utils/bin/black",
"python.formatting.yapfPath": "/usr/local/py-utils/bin/yapf",
"python.linting.banditPath": "/usr/local/py-utils/bin/bandit",
"python.linting.flake8Path": "/usr/local/py-utils/bin/flake8",
"python.linting.mypyPath": "/usr/local/py-utils/bin/mypy",
"python.linting.pycodestylePath": "/usr/local/py-utils/bin/pycodestyle",
"python.linting.pydocstylePath": "/usr/local/py-utils/bin/pydocstyle",
"python.linting.pylintPath": "/usr/local/py-utils/bin/pylint"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"platformio.platformio-ide",
"marlinfirmware.auto-build",
"editorconfig.editorconfig"
],
// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
// Use 'postCreateCommand' to run commands after the container is created.
// "postCreateCommand": "pip3 install --user -r requirements.txt",
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
// "remoteUser": "vscode"
}

View File

@@ -1,33 +1,19 @@
# editorconfig.org
root = true
[*]
trim_trailing_whitespace = true
insert_final_newline = true
[{*.patch,syntax_test_*}]
trim_trailing_whitespace = false
[{*.c,*.cpp,*.h,*.ino,*.py,Makefile}]
end_of_line = lf
[{*.c,*.cpp,*.h,*.ino}]
charset = utf-8
[{*.c,*.cpp,*.h,*.ino,Makefile}]
trim_trailing_whitespace = true
insert_final_newline = true
end_of_line = lf
indent_style = space
indent_size = 2
[{Makefile}]
indent_style = tab
indent_size = 2
[*.md]
# Two spaces at the end of the line means newline in Markdown
trim_trailing_whitespace = false
[{*.py}]
indent_style = space
indent_size = 4
[{*.conf,*.sublime-project}]
[{*.py,*.conf,*.sublime-project}]
indent_style = tab
indent_size = 4

157
.github/ISSUE_TEMPLATE/bug_report.yml vendored Normal file
View File

@@ -0,0 +1,157 @@
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: Your Slicer
description: Do you use Slic3r, Prusa Slicer, Simplify3D, IdeaMaker...?
options:
- Slic3r
- Simplify3D
- Prusa Slicer
- IdeaMaker
- Cura
- Other (explain below)
- type: dropdown
attributes:
label: Host Software
description: Do you use OctoPrint, Repetier Host, Pronterface...?
options:
- SD Card (headless)
- Repetier Host
- OctoPrint
- Pronterface
- Cura
- Same as my slicer
- Other (explain below)
- type: markdown
attributes:
value: >-
## Other things to include
Please also be sure to include these items to help with troubleshooting:
* **A ZIP file** containing your `Configuration.h` and `Configuration_adv.h`.
(Please don't paste lengthy configuration text here.)
* **Log output** from the host. (`M111 S247` for maximum logging.)
* **Images or videos** demonstrating the problem, if it helps to make it clear.
* **A G-Code file** that exposes the problem, if not affecting _all_ G-code.
If you've made any other modifications to the firmware, please describe them in detail in the space provided.
When pasting formatted text into the box below don't forget to put ` ``` ` (on its own line) before and after to make it readable.
- type: textarea
attributes:
label: Additional information & file uploads

20
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,20 @@
blank_issues_enabled: false
contact_links:
- name: 📖 Marlin Documentation
url: http://marlinfw.org/
about: Lots of documentation on installing and using Marlin.
- name: 👤 MarlinFirmware Facebook group
url: https://www.facebook.com/groups/1049718498464482
about: Please ask and answer questions here.
- name: 🕹 Marlin on Discord
url: https://discord.gg/n5NJ59y
about: Join the Discord server for support and discussion.
- name: 🔗 Marlin Discussion Forum
url: http://forums.reprap.org/list.php?415
about: A searchable web forum hosted by RepRap dot org.
- name: 📺 Marlin Videos on YouTube
url: https://www.youtube.com/results?search_query=marlin+firmware
about: Tutorials and more from Marlin users all around the world. Great for new users!
- name: 💸 Want to donate?
url: https://www.thinkyhead.com/donate-to-marlin
about: Please take a look at the various options to support Marlin Firmware's development financially!

View File

@@ -0,0 +1,44 @@
name: ✨ Request a feature
description: Request a new Marlin Firmware feature
title: "[FR] (feature summary)"
labels: 'T: Feature Request'
body:
- type: markdown
attributes:
value: >
Do you want to ask a question? Are you looking for support? Please use one of the [support links](https://github.com/MarlinFirmware/Marlin/issues/new/choose).
- type: markdown
attributes:
value: >
**Thank you for requesting a new Marlin Firmware feature!**
## Before Requesting a Feature
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
- Check the latest [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see if the feature already exists.
- Before you proceed with your request, please consider if it is necessary to make it into a firmware feature, or if it may be better suited for a slicer or host feature.
- type: textarea
attributes:
label: Is your feature request related to a problem? Please describe.
description: A clear description of the problem (e.g., "I need X but Marlin can't do it [...]").
- type: textarea
attributes:
label: Are you looking for hardware support?
description: Tell us the printer, board, or peripheral that needs support.
- type: textarea
attributes:
label: Describe the feature you want
description: A clear description of the feature and how you think it should work.
validations:
required: true
- type: textarea
attributes:
label: Additional context
description: Add any other context or screenshots about the feature request here.

View File

@@ -28,9 +28,15 @@ Project maintainers are responsible for clarifying the standards of acceptable b
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by following GitHub's [reporting abuse or spam article](https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances.
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [marlinfirmware@github.com](mailto:marlinfirmware@github.com). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
## Attribution

View File

@@ -26,20 +26,16 @@ The following is a set of guidelines for contributing to Marlin, hosted by the [
## Code of Conduct
This project and everyone participating in it is governed by the [Marlin Code of Conduct](code_of_conduct.md). By participating, you are expected to uphold this code. Please report unacceptable behavior by following GitHub's [reporting abuse or spam article](https://docs.github.com/en/communities/maintaining-your-safety-on-github/reporting-abuse-or-spam).
This project and everyone participating in it is governed by the [Marlin Code of Conduct](code_of_conduct.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [marlinfirmware@github.com](mailto:marlinfirmware@github.com).
## I don't want to read this whole thing I just have a question!!!
> [!NOTE]
> Please don't file an issue to ask a question. You'll get faster results by using the resources below.
> **Note:** Please don't file an issue to ask a question. You'll get faster results by using the resources below.
We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions.
- [Marlin Documentation](https://marlinfw.org) - Official Marlin documentation
- Facebook Group ["Marlin Firmware"](https://www.facebook.com/groups/1049718498464482/)
- RepRap.org [Marlin Forum](https://forums.reprap.org/list.php?415)
- Facebook Group ["Marlin Firmware for 3D Printers"](https://www.facebook.com/groups/3Dtechtalk/)
- [Marlin Configuration](https://www.youtube.com/results?search_query=marlin+configuration) on YouTube
* [Marlin RepRap forum](https://reprap.org/forum/list.php?415)
* [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/)
If chat is more your speed, you can join the MarlinFirmware Discord server:
@@ -54,14 +50,13 @@ If chat is more your speed, you can join the MarlinFirmware Discord server:
This section guides you through submitting a Bug Report for Marlin. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
Before creating a Bug Report, please test the "nightly" development branch, as you might find out that you don't need to create one. When you are creating a Bug Report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](ISSUE_TEMPLATE/bug_report.yml), the information it asks for helps us resolve issues faster.
Before creating a Bug Report, please test the "nightly" development branch, as you might find out that you don't need to create one. When you are creating a Bug Report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](issue_template.md), the information it asks for helps us resolve issues faster.
> [!NOTE]
> Regressions can happen. If you find a **Closed** issue that seems like your issue, go ahead and open a new issue and include a link to the original issue in the body of your new one. All you need to create a link is the issue number, preceded by #. For example, #8888.
> **Note:** Regressions can happen. If you find a **Closed** issue that seems like your issue, go ahead and open a new issue and include a link to the original issue in the body of your new one. All you need to create a link is the issue number, preceded by #. For example, #8888.
#### How Do I Submit A (Good) Bug Report?
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Use the New Issue button to create an issue and provide the following information by filling in [the template](ISSUE_TEMPLATE/bug_report.yml).
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Use the New Issue button to create an issue and provide the following information by filling in [the template](issue_template.md).
Explain the problem and include additional details to help maintainers reproduce the problem:
@@ -93,12 +88,12 @@ Include details about your configuration and environment:
This section guides you through submitting a suggestion for Marlin, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions.
Before creating a suggestion, please check [this list](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aopen+is%3Aissue+label%3A%22T%3A+Feature+Request%22) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-feature-request). Fill in [the template](ISSUE_TEMPLATE/feature_request.yml), including the steps that you imagine you would take if the feature you're requesting existed.
Before creating a suggestion, please check [this list](#before-submitting-a-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). Fill in [the template](issue_template.md), including the steps that you imagine you would take if the feature you're requesting existed.
#### Before Submitting a Feature Request
* **Check the [Marlin website](https://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](https://marlinfw.org/docs/configuration/configuration.html).
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aopen+is%3Aissue+label%3A%22T%3A+Feature+Request%22)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
* **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?
@@ -121,7 +116,7 @@ Unsure where to begin contributing to Marlin? You can start by looking through t
### Pull Requests
Pull Requests should always be targeted to working branches (e.g., `bugfix-2.1.x` and/or `bugfix-1.1.x`) and never to release branches (e.g., `2.0.x` and/or `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
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.
* Fill in [the required template](pull_request_template.md).
* Don't include issue numbers in the PR title.

35
.github/issue_template.md vendored Normal file
View File

@@ -0,0 +1,35 @@
<!--
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/.github/code_of_conduct.md
Do you want to ask a question? Are you looking for support? Please don't post here. Instead use one of the following options:
- The Marlin Firmware forum at https://reprap.org/forum/list.php?415
- The MarlinFirmware Facebook Group at https://www.facebook.com/groups/1049718498464482/
- The MarlinFirmware Discord Server at https://discord.gg/n5NJ59y.
Before filing an issue be sure to test the latest "bugfix" branch to see whether the issue is already addressed.
-->
### Description
<!-- Description of the bug or requested feature -->
### Steps to Reproduce
<!-- If this is a Bug Report, please describe the steps needed to reproduce the issue -->
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:** [What you expect to happen]
**Actual behavior:** [What actually happens]
#### Additional Information
* Include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files.
* Provide pictures or links to videos that clearly demonstrate the issue.
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.

40
.github/lock.yml vendored Normal file
View File

@@ -0,0 +1,40 @@
#
# 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

35
.github/workflows/bump-date.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
#
# bump-date.yml
# Bump the distribution date once per day
#
name: Bump Distribution Date
on:
schedule:
- cron: '0 0 * * *'
jobs:
bump_date:
name: Bump Distribution Date
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- name: Check out bugfix-2.0.x
uses: actions/checkout@v2
with:
ref: bugfix-2.0.x
- name: Bump Distribution Date
run: |
# Inline Bump Script
DIST=$( date +"%Y-%m-%d" )
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/src/inc/Version.h" && \
git config user.name "${GITHUB_ACTOR}" && \
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
git add . && \
git commit -m "[cron] Bump distribution date ($DIST)" && \
git push

32
.github/workflows/check-pr.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
#
# check-pr.yml
# Close PRs directed at release branches
#
name: PR Bad Target
on:
pull_request:
branches:
- 1.0.x
- 1.1.x
- 2.0.x
jobs:
bad_target:
name: PR Bad Target
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: >
Thanks for your contribution! Unfortunately we can't accept PRs directed at release branches. We make patches to the bugfix branches and only later do we push them out as releases.
Please redo this PR starting with the `bugfix-2.0.x` branch and be careful to target `bugfix-2.0.x` when resubmitting the PR.
It may help to set your fork's default branch to `bugfix-2.0.x`.
See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions.

39
.github/workflows/clean-closed.yml vendored Normal file
View File

@@ -0,0 +1,39 @@
#
# clean-closed.yml
# Remove obsolete labels when an Issue or PR is closed
#
name: Clean Closed
on:
pull_request:
types: [closed]
issues:
types: [closed]
jobs:
remove_label:
runs-on: ubuntu-latest
strategy:
matrix:
label:
- "S: Don't Merge"
- "S: Hold for 2.1"
- "S: Please Merge"
- "S: Please Test"
- "help wanted"
- "Needs: Discussion"
- "Needs: Documentation"
- "Needs: More Data"
- "Needs: Patch"
- "Needs: Testing"
- "Needs: Work"
steps:
- uses: actions/checkout@v2
- name: Remove Labels
uses: actions-ecosystem/action-remove-labels@v1
with:
github_token: ${{ github.token }}
labels: ${{ matrix.label }}

28
.github/workflows/close-stale.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
#
# close-stale.yml
# Close open issues after a period of inactivity
#
name: Close Stale Issues
on:
schedule:
- cron: "22 1 * * *"
jobs:
stale:
name: Close Stale Issues
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has had no activity in the last 60 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 10 days.'
days-before-stale: 60
days-before-close: 10
stale-issue-label: 'stale-closing-soon'
exempt-all-assignees: true
exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: Discussion,Needs: Documentation,Needs: More Data,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking'

32
.github/workflows/lock-closed.yml vendored Normal file
View File

@@ -0,0 +1,32 @@
#
# lock-closed.yml
# Lock closed issues after a period of inactivity
#
name: Lock Closed Issues
on:
schedule:
- cron: '0 1/13 * * *'
jobs:
lock:
name: Lock Closed Issues
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
process-only: 'issues'
issue-lock-inactive-days: '60'
issue-exclude-created-before: '2017-07-01T00:00:00Z'
issue-exclude-labels: 'no-locking'
issue-lock-labels: ''
issue-lock-comment: >
This issue has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
issue-lock-reason: ''

126
.github/workflows/test-builds.yml vendored Normal file
View File

@@ -0,0 +1,126 @@
#
# test-builds.yml
# Do test builds to catch compile errors
#
name: CI
on:
pull_request:
branches:
- bugfix-2.0.x
paths-ignore:
- config/**
- data/**
- docs/**
- '**/*.md'
push:
branches:
- bugfix-2.0.x
paths-ignore:
- config/**
- data/**
- docs/**
- '**/*.md'
jobs:
test_builds:
name: Run All Tests
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
strategy:
matrix:
test-platform:
# Base Environments
- DUE
- DUE_archim
- esp32
- linux_native
- mega2560
- at90usb1286_dfu
- teensy31
- teensy35
- teensy41
- SAMD51_grandcentral_m4
# Extended AVR Environments
- FYSETC_F6
- mega1280
- rambo
- sanguino1284p
- sanguino644p
# STM32F1 (Maple) Environments
- STM32F103RC_btt
- STM32F103RC_btt_USB
- STM32F103RE_btt
- STM32F103RE_btt_USB
- STM32F103RC_fysetc
- STM32F103RC_meeb
- jgaurora_a5s_a1
- STM32F103VE_longer
- mks_robin
- mks_robin_lite
- mks_robin_pro
- STM32F103RET6_creality
- mks_robin_nano35
# STM32 (ST) Environments
- STM32F103RC_btt_stm32
- STM32F407VE_black
- STM32F401VE_STEVAL
- BIGTREE_BTT002
- BIGTREE_SKR_PRO
- BIGTREE_GTR_V1_0
- mks_robin_stm32
- ARMED
- FYSETC_S6
- STM32F070CB_malyan
- STM32F070RB_malyan
- malyan_M300
- FLYF407ZG
- rumba32
- LERDGEX
- LERDGEK
- mks_robin_nano35_stm32
- NUCLEO_F767ZI
- REMRAM_V1
- BTT_SKR_SE_BX
- chitu_f103
# Put lengthy tests last
- LPC1768
- LPC1769
# Non-working environment tests
#- at90usb1286_cdc
#- STM32F103CB_malyan
#- STM32F103RE
#- mks_robin_mini
steps:
- name: Select Python 3.7
uses: actions/setup-python@v1
with:
python-version: '3.7' # Version range or exact version of a Python version to use, using semvers version range syntax.
architecture: 'x64' # optional x64 or x86. Defaults to x64 if not specified
- name: Install PlatformIO
run: |
pip install -U https://github.com/platformio/platformio-core/archive/develop.zip
platformio update
- name: Check out the PR
uses: actions/checkout@v2
- name: Run ${{ matrix.test-platform }} Tests
run: |
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}

22
.github/workflows/unlock-reopened.yml vendored Normal file
View File

@@ -0,0 +1,22 @@
#
# unlock-reopened.yml
# Unlock an issue whenever it is re-opened
#
name: "Unlock reopened issue"
on:
issues:
types: [reopened]
jobs:
unlock:
name: Unlock Reopened
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: OSDKDev/unlock-issues@v1.1
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"

71
.gitignore vendored
View File

@@ -21,21 +21,32 @@
# Generated files
_Version.h
bdf2u8g.exe
genpages.exe
marlin_config.json
mczip.h
language*.csv
out-csv/
out-language/
*.gen
*.sublime-workspace
bdf2u8g
#
# OS
#
applet/
.DS_Store
*.DS_Store
# Compiled C++ Object files
#
# Misc
#
*~
*.orig
*.rej
*.bak
*.idea
*.s
*.i
*.ii
*.swp
tags
#
# C++
#
# Compiled Object files
*.slo
*.lo
*.o
@@ -66,7 +77,10 @@ applet/
*.out
*.app
# Compiled C Object files
#
# C
#
# Object files
*.o
*.ko
*.obj
@@ -123,22 +137,16 @@ __vm/
vc-fileutils.settings
# Visual Studio Code
.vscode/*
!.vscode/extensions.json
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/*.db
# Simulation files
imgui.ini
eeprom.dat
spi_flash.bin
fs.img
# CMake
buildroot/share/cmake/*
# cmake
CMakeLists.txt
!buildroot/share/cmake/CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
build/
# CLion
cmake-build-*
@@ -156,15 +164,6 @@ __pycache__
# IOLogger logs
*_log.csv
# Misc.
*~
*.orig
*.rej
*.bak
*.idea
*.i
*.ii
*.swp
tags
*.logs
*.bak
# Simulation / Native
eeprom.dat
imgui.ini

View File

@@ -1,12 +0,0 @@
{
// See http://go.microsoft.com/fwlink/?LinkId=827846
// for the documentation about the extensions.json format
"recommendations": [
"marlinfirmware.auto-build",
"platformio.platformio-ide"
],
"unwantedRecommendations": [
"ms-vscode-remote.remote-containers",
"ms-vscode.cpptools-extension-pack"
]
}

View File

@@ -1,18 +1,11 @@
SCRIPTS_DIR := buildroot/share/scripts
CONTAINER_RT_BIN := docker
CONTAINER_RT_OPTS := --rm -v $(PWD):/code -v platformio-cache:/root/.platformio
CONTAINER_IMAGE := marlin-dev
help:
@echo "Tasks for local development:"
@echo "make marlin : Build marlin for the configured board"
@echo "make format-pins : Reformat all pins files"
@echo "make tests-single-ci : Run a single test from inside the CI"
@echo "make tests-single-local : Run a single test locally"
@echo "make tests-single-local-docker : Run a single test locally, using docker"
@echo "make tests-all-local : Run all tests locally"
@echo "make tests-all-local-docker : Run all tests locally, using docker"
@echo "make setup-local-docker : Build the local docker image"
@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"
@@ -25,41 +18,35 @@ help:
@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!"
marlin:
./buildroot/bin/mftest -a
.PHONY: marlin
.PHONY: help
tests-single-ci:
export GIT_RESET_HARD=true
$(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) PLATFORMIO_BUILD_FLAGS=-DGITHUB_ACTION
$(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 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
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
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 PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& for TEST_TARGET in $$($(SCRIPTS_DIR)/get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
&& 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:
@if ! $(CONTAINER_RT_BIN) images -q $(CONTAINER_IMAGE) > /dev/null ; then $(MAKE) setup-local-docker ; fi
$(CONTAINER_RT_BIN) run $(CONTAINER_RT_OPTS) $(CONTAINER_IMAGE) $(MAKE) tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
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:
$(CONTAINER_RT_BIN) build -t $(CONTAINER_IMAGE) -f docker/Dockerfile .
PINS := $(shell find Marlin/src/pins -mindepth 2 -name '*.h')
$(PINS): %:
@echo "Formatting $@" && node $(SCRIPTS_DIR)/pinsformat.js $@
format-pins: $(PINS)
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

View File

@@ -63,8 +63,8 @@ HARDWARE_MOTHERBOARD ?= 1020
ifeq ($(OS),Windows_NT)
# Windows
ARDUINO_INSTALL_DIR ?= ${HOME}/AppData/Local/Arduino
ARDUINO_USER_DIR ?= ${HOME}/Documents/Arduino
ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino
ARDUINO_USER_DIR ?= ${HOME}/Arduino
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
@@ -82,11 +82,11 @@ endif
# Arduino source install directory, and version number
# On most linuxes this will be /usr/share/arduino
ARDUINO_INSTALL_DIR ?= ${HOME}/AppData/Local/Arduino # C:/Users/${USERNAME}/AppData/Local/Arduino
ARDUINO_VERSION ?= 10819
ARDUINO_INSTALL_DIR ?= ${HOME}/Arduino
ARDUINO_VERSION ?= 106
# The installed Libraries are in the User folder
ARDUINO_USER_DIR ?= ${HOME}/Documents/Arduino
ARDUINO_USER_DIR ?= ${HOME}/Arduino
# You can optionally set a path to the avr-gcc tools.
# Requires a trailing slash. For example, /usr/local/avr-gcc/bin/
@@ -109,8 +109,8 @@ LIQUID_TWI2 ?= 0
# This defines if Wire is needed
WIRE ?= 0
# This defines if Tone is needed (i.e., SPEAKER is defined in Configuration.h)
# Disabling this (and SPEAKER) saves approximately 350 bytes of memory.
# This defines if Tone is needed (i.e SPEAKER is defined in Configuration.h)
# Disabling this (and SPEAKER) saves approximatively 350 bytes of memory.
TONE ?= 1
# This defines if U8GLIB is needed (may require RELOC_WORKAROUND)
@@ -132,7 +132,7 @@ CC_MIN:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_MINOR__ | cut -f3 -d\ )
CC_PATCHLEVEL:=$(shell $(CC) -dM -E - < /dev/null | grep __GNUC_PATCHLEVEL__ | cut -f3 -d\ )
CC_VER:=$(shell echo $$(( $(CC_MAJ) * 10000 + $(CC_MIN) * 100 + $(CC_PATCHLEVEL) )))
ifeq ($(shell test $(CC_VER) -lt 40901 && echo 1),1)
$(warning This GCC version $(CC_VER) is likely broken. Enabling relocation workaround.)
@echo This version of GCC is likely broken. Enabling relocation workaround.
RELOC_WORKAROUND = 1
endif
@@ -207,11 +207,11 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1105)
else ifeq ($(HARDWARE_MOTHERBOARD),1106)
# MKS BASE v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1107)
# MKS BASE v1.4 with Allegro A4982 stepper drivers
# MKS v1.4 with A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1108)
# MKS BASE v1.5 with Allegro A4982 stepper drivers
# MKS v1.5 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1109)
# MKS BASE v1.6 with Allegro A4982 stepper drivers
# MKS v1.6 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1110)
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),1111)
@@ -219,110 +219,93 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1111)
else ifeq ($(HARDWARE_MOTHERBOARD),1112)
# MKS GEN L
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
# BigTreeTech or BIQU KFB2.0
# zrib V2.0 control board (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
# zrib V2.0 (Chinese RAMPS replica)
# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
# zrib V5.2 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
# Invent-A-Part RigidBoard
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
# Invent-A-Part RigidBoard V2
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
# Sainsmart 2-in-1 board
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
# Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
MCU ?= atmega1280
PROG_MCU ?= m1280
# Azteeg X3
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
# Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
# Raise3D Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
# Raise3D N series Rumba derivative
# Rapide Lite RL200 Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
# Rapide Lite 200 (v1, low-cost RUMBA clone with drv)
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
# Formbot T-Rex 2 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
# Formbot T-Rex 3
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
# Formbot Raptor
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
# Formbot Raptor 2
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
# bq ZUM Mega 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
# MakeBoard Mini v2.1.2 by MicroMake
# TriGorilla Anycubic version 1.3 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
# TriGorilla Anycubic version 1.3-based on RAMPS EFB
# TriGorilla Anycubic version 1.4 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
# ... Ver 1.4
# TriGorilla Anycubic version 1.4 Rev 1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
# ... Rev 1.1 (new servo pin order)
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
# Creality: Ender-4, CR-8
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
# FYSETC F6 1.5
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# FYSETC F6 1.4
# Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
# Wanhao Duplicator i3 Plus
# VORON
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
# VORON Design
# TRONXY V3 1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# Tronxy TRONXY-V3-1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
# MKS GEN L V2.1
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
# Ortur 4
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
# Tenlog D3 Hero
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3 Hero IDEX printer
else ifeq ($(HARDWARE_MOTHERBOARD),1156)
# Tenlog D3,5,6 Pro IDEX printers
else ifeq ($(HARDWARE_MOTHERBOARD),1157)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1158)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1159)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1160)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1161)
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1162)
# Zonestar zrib V5.3 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1163)
# Pxmalion Core I3
else ifeq ($(HARDWARE_MOTHERBOARD),1164)
#
# RAMBo and derivatives
@@ -375,38 +358,20 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1311)
else ifeq ($(HARDWARE_MOTHERBOARD),1312)
# Mega controller
else ifeq ($(HARDWARE_MOTHERBOARD),1313)
# Geeetech GT2560 Rev A
else ifeq ($(HARDWARE_MOTHERBOARD),1314)
# Geeetech GT2560 Rev A+ (with auto level probe)
else ifeq ($(HARDWARE_MOTHERBOARD),1315)
# Geeetech GT2560 Rev B
else ifeq ($(HARDWARE_MOTHERBOARD),1316)
# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1317)
# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
# Geeetech GT2560 Rev B for Mecreator2
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
else ifeq ($(HARDWARE_MOTHERBOARD),1314)
# Geeetech GT2560 Rev. A
else ifeq ($(HARDWARE_MOTHERBOARD),1315)
# Geeetech GT2560 Rev. A+ (with auto level probe)
else ifeq ($(HARDWARE_MOTHERBOARD),1316)
# Geeetech GT2560 Rev B for A10(M/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1317)
# Geeetech GT2560 Rev B for A20(M/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1321)
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
#
# ATmega1281, ATmega2561
@@ -480,11 +445,6 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1510)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# ZoneStar ZMIB V2
else ifeq ($(HARDWARE_MOTHERBOARD),1511)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
#
# Other ATmega644P, ATmega644, ATmega1284P
@@ -656,18 +616,18 @@ 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/arduino/avr/libraries/SPI
# New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/arduino/avr/1.8.6/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
endif
ifeq ($(IS_MCU),1)
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/arduino/avr/1.8.6/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/SoftwareSerial
# New libraries (avr-core >= 1.6.21 / Arduino >= 1.6.8)
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/arduino/avr/1.8.6/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/arduino/avr/1.8.6/libraries/SoftwareSerial/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SoftwareSerial/src
endif
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
@@ -681,17 +641,17 @@ ifeq ($(WIRE), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire
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)/packages/arduino/hardware/avr/1.8.6/libraries/Wire/src
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/avr/1.8.6/libraries/Wire/src/utility
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/Wire/src/utility
endif
ifeq ($(NEOPIXEL), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
endif
ifeq ($(U8GLIB), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib-HAL
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib-HAL/src
# VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib
# VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/src
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/csrc
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/cppsrc
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/fntsrc
endif
ifeq ($(TMC), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/TMCStepper/src
@@ -700,9 +660,9 @@ endif
ifeq ($(HARDWARE_VARIANT), arduino)
HARDWARE_SUB_VARIANT ?= mega
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/avr/1.8.6/variants/$(HARDWARE_SUB_VARIANT)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/variants/$(HARDWARE_SUB_VARIANT)
else ifeq ($(HARDWARE_VARIANT), Sanguino)
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/avr/1.8.6/variants/sanguino
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/marlin/avr/variants/sanguino
else ifeq ($(HARDWARE_VARIANT), archim)
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/libsam
VPATH += $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/system/CMSIS/CMSIS/Include/
@@ -718,7 +678,7 @@ else ifeq ($(HARDWARE_VARIANT), archim)
LDLIBS = $(ARDUINO_INSTALL_DIR)/packages/ultimachine/hardware/sam/1.6.9-b/variants/archim/libsam_sam3x8e_gcc_rel.a
else
HARDWARE_SUB_VARIANT ?= standard
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/avr/1.8.6/variants/$(HARDWARE_SUB_VARIANT)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/$(HARDWARE_VARIANT)/variants/$(HARDWARE_SUB_VARIANT)
endif
LIB_SRC = wiring.c \
@@ -733,7 +693,7 @@ endif
ifeq ($(HARDWARE_VARIANT), Teensy)
LIB_SRC = wiring.c
VPATH += $(ARDUINO_INSTALL_DIR)/packages/arduino/hardware/teensy/cores/teensy
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
endif
LIB_CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp
@@ -880,7 +840,7 @@ AVRDUDE_WRITE_FLASH = -Uflash:w:$(BUILD_DIR)/$(TARGET).hex:i
ifeq ($(shell uname -s), Linux)
AVRDUDE_CONF = /etc/avrdude/avrdude.conf
else
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/packages/arduino/tools/avrdude/6.3.0-arduino17/etc/avrdude.conf
AVRDUDE_CONF = $(ARDUINO_INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf
endif
AVRDUDE_FLAGS = -D -C$(AVRDUDE_CONF) \
-p$(PROG_MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) \

View File

@@ -2,7 +2,7 @@
Marlin Firmware
(c) 2011-2024 MarlinFirmware
(c) 2011-2020 MarlinFirmware
Portions of Marlin are (c) by their respective authors.
All code complies with GPLv2 and/or GPLv3
@@ -27,7 +27,7 @@ Configuration
- https://github.com/MarlinFirmware/Configurations
Example configurations for several printer models.
- https://youtu.be/3gwWVFtdg-4
- https://www.youtube.com/watch?v=3gwWVFtdg-4
A good 20-minute overview of Marlin configuration by Tom Sanladerer.
(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

View File

@@ -28,7 +28,7 @@
/**
* Marlin release version identifier
*/
//#define SHORT_BUILD_VERSION "2.1.2.4"
//#define SHORT_BUILD_VERSION "2.0.8.3"
/**
* Verbose version identifier which should contain a reference to the location
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2024-05-29"
//#define STRING_DISTRIBUTION_DATE "2023-07-18"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.

View File

@@ -1,251 +0,0 @@
#
# Marlin Firmware
# config.ini - Options to apply before the build
#
[config:base]
#
# ini_use_config - A comma-separated list of actions to apply to the Configuration files.
# The actions will be applied in the listed order.
# - none
# Ignore this file and don't apply any configuration options
#
# - base
# Just apply the options in config:base to the configuration
#
# - minimal
# Just apply the options in config:minimal to the configuration
#
# - all
# Apply all 'config:*' sections in this file to the configuration
#
# - another.ini
# Load another INI file with a path relative to this config.ini file (i.e., within Marlin/)
#
# - https://me.myserver.com/path/to/configs
# Fetch configurations from any URL.
#
# - example/Creality/Ender-5 Plus @ bugfix-2.1.x
# Fetch example configuration files from the MarlinFirmware/Configurations repository
# https://raw.githubusercontent.com/MarlinFirmware/Configurations/bugfix-2.1.x/config/examples/Creality/Ender-5%20Plus/
#
# - example/default @ release-2.0.9.7
# Fetch default configuration files from the MarlinFirmware/Configurations repository
# https://raw.githubusercontent.com/MarlinFirmware/Configurations/release-2.0.9.7/config/default/
#
# - [disable]
# Comment out all #defines in both Configuration.h and Configuration_adv.h. This is useful
# to start with a clean slate before applying any config: options, so only the options explicitly
# set in config.ini will be enabled in the configuration.
#
# - [flatten] (Not yet implemented)
# Produce a flattened set of Configuration.h and Configuration_adv.h files with only the enabled
# #defines and no comments. A clean look, but context-free.
#
ini_use_config = none
# Load all config: sections in this file
;ini_use_config = all
# Disable everything and apply subsequent config:base options
;ini_use_config = [disable], base
# Load config file relative to Marlin/
;ini_use_config = another.ini
# Download configurations from GitHub
;ini_use_config = example/Creality/Ender-5 Plus @ bugfix-2.1.x
# Download configurations from your server
;ini_use_config = https://me.myserver.com/path/to/configs
# Evaluate config:base and do a config dump
;ini_use_config = base
;config_export = 2
[config:minimal]
motherboard = BOARD_RAMPS_14_EFB
serial_port = 0
baudrate = 250000
use_watchdog = on
thermal_protection_hotends = on
thermal_protection_hysteresis = 4
thermal_protection_period = 40
bufsize = 4
block_buffer_size = 16
max_cmd_size = 96
extruders = 1
temp_sensor_0 = 1
temp_hysteresis = 3
heater_0_mintemp = 5
heater_0_maxtemp = 275
preheat_1_temp_hotend = 180
bang_max = 255
pidtemp = on
pid_k1 = 0.95
pid_max = 255
pid_functional_range = 10
default_kp = 22.20
default_ki = 1.08
default_kd = 114.00
x_driver_type = A4988
y_driver_type = A4988
z_driver_type = A4988
e0_driver_type = A4988
x_bed_size = 200
x_min_pos = 0
x_max_pos = X_BED_SIZE
y_bed_size = 200
y_min_pos = 0
y_max_pos = Y_BED_SIZE
z_min_pos = 0
z_max_pos = 200
x_home_dir = -1
y_home_dir = -1
z_home_dir = -1
use_xmin_plug = on
use_ymin_plug = on
use_zmin_plug = on
x_min_endstop_inverting = false
y_min_endstop_inverting = false
z_min_endstop_inverting = false
default_axis_steps_per_unit = { 80, 80, 400, 500 }
axis_relative_modes = { false, false, false, false }
default_max_feedrate = { 300, 300, 5, 25 }
default_max_acceleration = { 3000, 3000, 100, 10000 }
homing_feedrate_mm_m = { (50*60), (50*60), (4*60) }
homing_bump_divisor = { 2, 2, 4 }
x_enable_on = 0
y_enable_on = 0
z_enable_on = 0
e_enable_on = 0
invert_x_dir = false
invert_y_dir = true
invert_z_dir = false
invert_e0_dir = false
invert_e_step_pin = false
invert_x_step_pin = false
invert_y_step_pin = false
invert_z_step_pin = false
disable_x = off
disable_y = off
disable_z = off
disable_e = off
proportional_font_ratio = 1.0
default_nominal_filament_dia = 1.75
junction_deviation_mm = 0.013
default_acceleration = 3000
default_travel_acceleration = 3000
default_retract_acceleration = 3000
default_minimumfeedrate = 0.0
default_mintravelfeedrate = 0.0
minimum_planner_speed = 0.05
min_steps_per_segment = 6
default_minsegmenttime = 20000
[config:basic]
bed_overshoot = 10
busy_while_heating = on
default_ejerk = 5.0
default_keepalive_interval = 2
default_leveling_fade_height = 0.0
disable_other_extruders = on
display_charset_hd44780 = JAPANESE
eeprom_boot_silent = on
eeprom_chitchat = on
endstoppullups = on
extrude_maxlength = 200
extrude_mintemp = 170
host_keepalive_feature = on
hotend_overshoot = 15
jd_handle_small_segments = on
lcd_info_screen_style = 0
lcd_language = en
max_bed_power = 255
mesh_inset = 0
min_software_endstops = on
max_software_endstops = on
min_software_endstop_x = on
min_software_endstop_y = on
min_software_endstop_z = on
max_software_endstop_x = on
max_software_endstop_y = on
max_software_endstop_z = on
preheat_1_fan_speed = 0
preheat_1_label = "PLA"
preheat_1_temp_bed = 70
prevent_cold_extrusion = on
prevent_lengthy_extrude = on
printjob_timer_autostart = on
probing_margin = 10
show_bootscreen = on
soft_pwm_scale = 0
string_config_h_author = "(none, default config)"
temp_bed_hysteresis = 3
temp_bed_residency_time = 10
temp_bed_window = 1
temp_residency_time = 10
temp_window = 1
validate_homing_endstops = on
xy_probe_feedrate = (133*60)
z_clearance_between_probes = 5
z_clearance_deploy_probe = 10
z_clearance_multi_probe = 5
[config:advanced]
arc_support = on
auto_report_temperatures = on
autotemp = on
autotemp_oldweight = 0.98
bed_check_interval = 5000
default_stepper_timeout_sec = 120
default_volumetric_extruder_limit = 0.00
disable_idle_x = on
disable_idle_y = on
disable_idle_z = on
disable_idle_e = on
e0_auto_fan_pin = -1
encoder_100x_steps_per_sec = 80
encoder_10x_steps_per_sec = 30
encoder_rate_multiplier = on
extended_capabilities_report = on
extruder_auto_fan_speed = 255
extruder_auto_fan_temperature = 50
fanmux0_pin = -1
fanmux1_pin = -1
fanmux2_pin = -1
faster_gcode_parser = on
homing_bump_mm = { 5, 5, 2 }
max_arc_segment_mm = 1.0
min_arc_segment_mm = 0.1
min_circle_segments = 72
n_arc_correction = 25
serial_overrun_protection = on
slowdown = on
slowdown_divisor = 2
temp_sensor_bed = 0
thermal_protection_bed_hysteresis = 2
thermocouple_max_errors = 15
tx_buffer_size = 0
watch_bed_temp_increase = 2
watch_bed_temp_period = 60
watch_temp_increase = 2
watch_temp_period = 20

View File

@@ -23,7 +23,6 @@
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#include <avr/wdt.h>
#ifdef USBCON
DefaultSerial1 MSerial0(false, Serial);
@@ -36,56 +35,30 @@
// Public Variables
// ------------------------
// Don't initialize/override variable (which would happen in .init4)
uint8_t MarlinHAL::reset_reason __attribute__((section(".noinit")));
//uint8_t MCUSR;
// ------------------------
// Public functions
// ------------------------
__attribute__((naked)) // Don't output function pro- and epilogue
__attribute__((used)) // Output the function, even if "not used"
__attribute__((section(".init3"))) // Put in an early user definable section
void save_reset_reason() {
#if ENABLED(OPTIBOOT_RESET_REASON)
__asm__ __volatile__(
A("STS %0, r2")
: "=m"(hal.reset_reason)
);
#else
hal.reset_reason = MCUSR;
#endif
// Clear within 16ms since WDRF bit enables a 16ms watchdog timer -> Boot loop
hal.clear_reset_source();
wdt_disable();
}
void MarlinHAL::init() {
void HAL_init() {
// Init Servo Pins
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
#if HAS_SERVO_0
OUT_WRITE(SERVO0_PIN, LOW);
INIT_SERVO(0);
#endif
#if HAS_SERVO_1
OUT_WRITE(SERVO1_PIN, LOW);
INIT_SERVO(1);
#endif
#if HAS_SERVO_2
OUT_WRITE(SERVO2_PIN, LOW);
INIT_SERVO(2);
#endif
#if HAS_SERVO_3
OUT_WRITE(SERVO3_PIN, LOW);
INIT_SERVO(3);
#endif
#if HAS_SERVO_4
OUT_WRITE(SERVO4_PIN, LOW);
#endif
#if HAS_SERVO_5
OUT_WRITE(SERVO5_PIN, LOW);
#endif
init_pwm_timers(); // Init user timers to default frequency - 1000HZ
}
void MarlinHAL::reboot() {
void HAL_reboot() {
#if ENABLED(USE_WATCHDOG)
while (1) { /* run out the watchdog */ }
#else
@@ -94,68 +67,12 @@ void MarlinHAL::reboot() {
#endif
}
// ------------------------
// Watchdog Timer
// ------------------------
#if ENABLED(USE_WATCHDOG)
#include <avr/wdt.h>
#include "../../MarlinCore.h"
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
void MarlinHAL::watchdog_init() {
#if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S)
#define WDTO_NS WDTO_8S
#else
#define WDTO_NS WDTO_4S
#endif
#if ENABLED(WATCHDOG_RESET_MANUAL)
// Enable the watchdog timer, but only for the interrupt.
// Take care, as this requires the correct order of operation, with interrupts disabled.
// See the datasheet of any AVR chip for details.
wdt_reset();
cli();
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
_WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5
// So worked for up to WDTO_2S
sei();
wdt_reset();
#else
wdt_enable(WDTO_NS); // The function handles the upper bit correct.
#endif
//delay(10000); // test it!
}
//===========================================================================
//=================================== ISR ===================================
//===========================================================================
// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled.
#if ENABLED(WATCHDOG_RESET_MANUAL)
ISR(WDT_vect) {
sei(); // With the interrupt driven serial we need to allow interrupts.
SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED);
minkill(); // interrupt-safe final kill and infinite loop
}
#endif
// Reset watchdog. MUST be called at least every 4 seconds after the
// first watchdog_init or AVR will go into emergency procedures.
void MarlinHAL::watchdog_refresh() { wdt_reset(); }
#endif // USE_WATCHDOG
// ------------------------
// Free Memory Accessor
// ------------------------
#if HAS_MEDIA
#if ENABLED(SDSUPPORT)
#include "../../sd/SdFatUtil.h"
int freeMemory() { return SdFatUtil::FreeRam(); }
#else // !HAS_MEDIA
#else // !SDSUPPORT
extern "C" {
extern char __bss_end;
@@ -172,6 +89,6 @@ void MarlinHAL::reboot() {
}
}
#endif // !HAS_MEDIA
#endif // !SDSUPPORT
#endif // __AVR__

View File

@@ -1,9 +1,7 @@
/**
* 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
* 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
@@ -21,20 +19,17 @@
*/
#pragma once
/**
* HAL for Arduino AVR
*/
#include "../shared/Marduino.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "math.h"
#ifdef USBCON
#include <HardwareSerial.h>
#else
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
#include "MarlinSerial.h"
#define BOARD_NO_NATIVE_USB
#endif
#include <stdint.h>
@@ -44,19 +39,6 @@
#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
@@ -79,9 +61,9 @@
#define CRITICAL_SECTION_START() unsigned char _sreg = SREG; cli()
#define CRITICAL_SECTION_END() SREG = _sreg
#endif
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
#define PWM_FREQUENCY 1000 // Default PWM frequency when set_pwm_duty() is called without set_pwm_frequency()
#define ISRS_ENABLED() TEST(SREG, SREG_I)
#define ENABLE_ISRS() sei()
#define DISABLE_ISRS() cli()
// ------------------------
// Types
@@ -89,15 +71,16 @@
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
class Servo;
typedef Servo hal_servo_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;
@@ -109,57 +92,101 @@ typedef Servo hal_servo_t;
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#else
#if !WITHIN(SERIAL_PORT, 0, 3)
#error "SERIAL_PORT must be from 0 to 3."
#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, 0, 3)
#error "SERIAL_PORT_2 must be from 0 to 3."
#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, 0, 3)
#error "SERIAL_PORT_3 must be from 0 to 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, 0, 3)
#error "MMU2_SERIAL_PORT must be from 0 to 3"
#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, 0, 3)
#error "LCD_SERIAL_PORT must be from 0 to 3."
#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 LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free()
#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
//
#define HAL_ADC_VREF_MV 5000
#define HAL_ADC_RESOLUTION 10
#ifdef DIDR2
#define HAL_ANALOG_SELECT(ind) do{ if (ind < 8) SBI(DIDR0, ind); else SBI(DIDR2, ind & 0x07); }while(0)
#else
#define HAL_ANALOG_SELECT(ind) SBI(DIDR0, ind);
#endif
inline void HAL_adc_init() {
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
}
#define SET_ADMUX_ADCSRA(ch) ADMUX = _BV(REFS0) | (ch & 0x07); SBI(ADCSRA, ADSC)
#ifdef MUX5
#define HAL_START_ADC(ch) if (ch > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
#else
#define HAL_START_ADC(ch) ADCSRB = 0; SET_ADMUX_ADCSRA(ch)
#endif
#define HAL_ADC_VREF 5.0
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() ADC
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
//
// Pin Mapping for M42, M43, M226
//
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#define HAL_SENSITIVE_PINS 0, 1,
#define HAL_SENSITIVE_PINS 0, 1
#ifdef __AVR_AT90USB1286__
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)
@@ -168,113 +195,23 @@ typedef Servo hal_servo_t;
// AVR compatibility
#define strtof strtod
// ------------------------
// Free Memory Accessor
// ------------------------
#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
#pragma GCC diagnostic pop
// ------------------------
// MarlinHAL Class
// ------------------------
class MarlinHAL {
public:
// Earliest possible init, before setup()
MarlinHAL() {}
// Watchdog
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
static void init(); // Called early in setup()
static void init_board() {} // Called less early in setup()
static void reboot(); // Restart the firmware from 0x0
// Interrupts
static bool isr_state() { return TEST(SREG, SREG_I); }
static void isr_on() { sei(); }
static void isr_off() { cli(); }
static void delay_ms(const int ms) { _delay_ms(ms); }
// Tasks, called from idle()
static void idletask() {}
// Reset
static uint8_t reset_reason;
static uint8_t get_reset_source() { return reset_reason; }
static void clear_reset_source() { MCUSR = 0; }
// Free SRAM
static int freeMemory() { return ::freeMemory(); }
//
// ADC Methods
//
// Called by Temperature::init once at startup
static void adc_init() {
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
}
// Called by Temperature::init for each sensor at startup
static void adc_enable(const uint8_t ch) {
#ifdef DIDR2
if (ch > 7) { SBI(DIDR2, ch & 0x07); return; }
#endif
SBI(DIDR0, ch);
}
// Begin ADC sampling on the given channel. Called from Temperature::isr!
static void adc_start(const uint8_t ch) {
#ifdef MUX5
ADCSRB = ch > 7 ? _BV(MUX5) : 0;
#else
ADCSRB = 0;
#endif
ADMUX = _BV(REFS0) | (ch & 0x07);
SBI(ADCSRA, ADSC);
}
// Is the ADC ready for reading?
static bool adc_ready() { return !TEST(ADCSRA, ADSC); }
// The current value of the ADC register
static __typeof__(ADC) adc_value() { return ADC; }
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
/**
* init_pwm_timers
* Set the default frequency for timers 2-5 to 1000HZ
*/
static void init_pwm_timers();
/**
* Set the PWM duty cycle for the pin to the given value.
* Optionally invert the duty cycle [default = false]
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
*/
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
/**
* Set the frequency of the timer for the given pin as close as
* possible to the provided desired frequency. Internally calculate
* the required waveform generation mode, prescaler, and resolution
* values and set timer registers accordingly.
* 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_PWM_FAN Settings)
* NOTE that there are limitations, particularly if using TIMER2. (see Configuration_adv.h -> FAST FAN PWM Settings)
*/
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
};
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);

View File

@@ -34,21 +34,21 @@
#include "../../inc/MarlinConfig.h"
void spiBegin() {
#if PIN_EXISTS(SD_SS)
// Do not init HIGH for boards with pin 4 used as Fans or Heaters or otherwise, not likely to have multiple SPI devices anyway.
#if defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
// SS must be in output mode even it is not chip select
SET_OUTPUT(SD_SS_PIN);
#else
// set SS high - may be chip select for another SPI device
OUT_WRITE(SD_SS_PIN, HIGH);
#endif
#endif
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
IF_DISABLED(SOFTWARE_SPI, spiInit(SPI_HALF_SPEED));
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
//SET_OUTPUT(SD_SS_PIN);
// set SS high - may be chip select for another SPI device
//#if SET_SPI_SS_HIGH
//WRITE(SD_SS_PIN, HIGH);
//#endif
// set a default rate
spiInit(1);
#endif
}
#if NONE(SOFTWARE_SPI, FORCE_SOFT_SPI)
@@ -74,8 +74,7 @@ void spiBegin() {
#elif defined(PRR0)
PRR0
#endif
, PRSPI
);
, PRSPI);
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
@@ -119,6 +118,7 @@ void spiBegin() {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
/** begin spi transaction */
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
// Based on Arduino SPI library
@@ -174,6 +174,7 @@ void spiBegin() {
SPSR = clockDiv | 0x01;
}
#else // SOFTWARE_SPI || FORCE_SOFT_SPI
// ------------------------
@@ -196,7 +197,7 @@ void spiBegin() {
// output pin high - like sending 0xFF
WRITE(SD_MOSI_PIN, HIGH);
for (uint8_t i = 0; i < 8; ++i) {
LOOP_L_N(i, 8) {
WRITE(SD_SCK_PIN, HIGH);
nop; // adjust so SCK is nice
@@ -223,7 +224,7 @@ void spiBegin() {
void spiSend(uint8_t data) {
// no interrupts during byte send - about 8µs
cli();
for (uint8_t i = 0; i < 8; ++i) {
LOOP_L_N(i, 8) {
WRITE(SD_SCK_PIN, LOW);
WRITE(SD_MOSI_PIN, data & 0x80);
data <<= 1;

View File

@@ -486,7 +486,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
// If global interrupts are disabled (as the result of being called from an ISR)...
if (!hal.isr_state()) {
if (!ISRS_ENABLED()) {
// Make room by polling if it is possible to transmit, and do so!
while (i == tx_buffer.tail) {
@@ -534,7 +534,7 @@ void MarlinSerial<Cfg>::flushTX() {
if (!_written) return;
// If global interrupts are disabled (as the result of being called from an ISR)...
if (!hal.isr_state()) {
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) {

View File

@@ -34,9 +34,12 @@
#include <WString.h>
#include "../../inc/MarlinConfigPre.h"
#include "../../core/types.h"
#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
#endif
#ifndef USBCON
// The presence of the UBRRH register is used to detect a UART.
@@ -135,6 +138,10 @@
#define BYTE 0
// Templated type selector
template<bool b, typename T, typename F> struct TypeSelector { typedef T type;} ;
template<typename T, typename F> struct TypeSelector<false, T, F> { typedef F type; };
template<typename Cfg>
class MarlinSerial {
protected:
@@ -157,7 +164,7 @@
static constexpr B_U2Xx<Cfg::PORT> B_U2X = 0;
// Base size of type on buffer size
typedef uvalue_t(Cfg::RX_SIZE - 1) ring_buffer_pos_t;
typedef typename TypeSelector<(Cfg::RX_SIZE>256), uint16_t, uint8_t>::type ring_buffer_pos_t;
struct ring_buffer_r {
volatile ring_buffer_pos_t head, tail;
@@ -184,13 +191,13 @@
rx_framing_errors;
static ring_buffer_pos_t rx_max_enqueued;
FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_head();
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_head();
static volatile bool rx_tail_value_not_stable;
static volatile uint16_t rx_tail_value_backup;
FORCE_INLINE static void atomic_set_rx_tail(ring_buffer_pos_t value);
FORCE_INLINE static ring_buffer_pos_t atomic_read_rx_tail();
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
public:
FORCE_INLINE static void store_rxd_char();
@@ -210,7 +217,7 @@
#endif
enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
static bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
@@ -276,7 +283,7 @@
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
static constexpr bool RX_OVERRUNS = ALL(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS);
static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS);
};
typedef Serial1Class< MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> > > MSerialLCD;

View File

@@ -63,28 +63,30 @@
static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
/************ static functions common to all instances ***********************/
static inline void handle_interrupts(const timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) {
int8_t cho = Channel[timer]; // Handle the prior Channel[timer] first
if (cho < 0) // Channel -1 indicates the refresh interval completed...
*TCNTn = 0; // ...so reset the timer
else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled?
extDigitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW
static inline void handle_interrupts(timer16_Sequence_t timer, volatile uint16_t* TCNTn, volatile uint16_t* OCRnA) {
if (Channel[timer] < 0)
*TCNTn = 0; // channel set to -1 indicated that refresh interval completed so reset the timer
else {
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
}
Channel[timer] = ++cho; // Handle the next channel (or 0)
if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) {
*OCRnA = *TCNTn + SERVO(timer, cho).ticks; // set compare to current ticks plus duration
if (SERVO(timer, cho).Pin.isActive) // activated?
extDigitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
*OCRnA = *TCNTn + SERVO(timer, Channel[timer]).ticks;
if (SERVO(timer, Channel[timer]).Pin.isActive) // check if activated
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // it's an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
const unsigned int cval = ((unsigned)*TCNTn) + 32 / (SERVO_TIMER_PRESCALER), // allow 32 cycles to ensure the next OCR1A not missed
ival = (unsigned int)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed
*OCRnA = max(cval, ival);
Channel[timer] = -1; // reset the timer counter to 0 on the next call
if (((unsigned)*TCNTn) + 4 < usToTicks(REFRESH_INTERVAL)) // allow a few ticks to ensure the next OCR1A not missed
*OCRnA = (unsigned int)usToTicks(REFRESH_INTERVAL);
else
*OCRnA = *TCNTn + 4; // at least REFRESH_INTERVAL has elapsed
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
}
}
@@ -121,12 +123,9 @@ static inline void handle_interrupts(const timer16_Sequence_t timer, volatile ui
/****************** end of static functions ******************************/
void initISR(const timer16_Sequence_t timer_index) {
switch (timer_index) {
default: break;
void initISR(timer16_Sequence_t timer) {
#ifdef _useTimer1
case _timer1:
if (timer == _timer1) {
TCCR1A = 0; // normal counting mode
TCCR1B = _BV(CS11); // set prescaler of 8
TCNT1 = 0; // clear the timer count
@@ -141,11 +140,11 @@ void initISR(const timer16_Sequence_t timer_index) {
#ifdef WIRING
timerAttach(TIMER1OUTCOMPAREA_INT, Timer1Service);
#endif
break;
}
#endif
#ifdef _useTimer3
case _timer3:
if (timer == _timer3) {
TCCR3A = 0; // normal counting mode
TCCR3B = _BV(CS31); // set prescaler of 8
TCNT3 = 0; // clear the timer count
@@ -159,64 +158,56 @@ void initISR(const timer16_Sequence_t timer_index) {
#ifdef WIRING
timerAttach(TIMER3OUTCOMPAREA_INT, Timer3Service); // for Wiring platform only
#endif
break;
}
#endif
#ifdef _useTimer4
case _timer4:
if (timer == _timer4) {
TCCR4A = 0; // normal counting mode
TCCR4B = _BV(CS41); // set prescaler of 8
TCNT4 = 0; // clear the timer count
TIFR4 = _BV(OCF4A); // clear any pending interrupts;
TIMSK4 = _BV(OCIE4A); // enable the output compare interrupt
break;
}
#endif
#ifdef _useTimer5
case _timer5:
if (timer == _timer5) {
TCCR5A = 0; // normal counting mode
TCCR5B = _BV(CS51); // set prescaler of 8
TCNT5 = 0; // clear the timer count
TIFR5 = _BV(OCF5A); // clear any pending interrupts;
TIMSK5 = _BV(OCIE5A); // enable the output compare interrupt
break;
}
#endif
}
}
void finISR(const timer16_Sequence_t timer_index) {
void finISR(timer16_Sequence_t timer) {
// Disable use of the given timer
#ifdef WIRING
switch (timer_index) {
default: break;
case _timer1:
if (timer == _timer1) {
CBI(
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
TIMSK1
#else
TIMSK
#endif
, OCIE1A // disable timer 1 output compare interrupt
);
, OCIE1A); // disable timer 1 output compare interrupt
timerDetach(TIMER1OUTCOMPAREA_INT);
break;
case _timer3:
}
else if (timer == _timer3) {
CBI(
#if defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
TIMSK3
#else
ETIMSK
#endif
, OCIE3A // disable the timer3 output compare A interrupt
);
, OCIE3A); // disable the timer3 output compare A interrupt
timerDetach(TIMER3OUTCOMPAREA_INT);
break;
}
#else // !WIRING
// For arduino - in future: call here to a currently undefined function to reset the timer
UNUSED(timer_index);
UNUSED(timer);
#endif
}

View File

@@ -23,7 +23,7 @@
#include "../../inc/MarlinConfig.h"
#if ANY(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
#if EITHER(EEPROM_SETTINGS, SD_FIRMWARE_UPDATE)
/**
* PersistentStore for Arduino-style EEPROM interface

View File

@@ -91,6 +91,7 @@ void endstop_ISR() { endstops.update(); }
#endif
// Install Pin change interrupt for a pin. Can be called multiple times.
void pciSetup(const int8_t pin) {
if (digitalPinHasPCICR(pin)) {
@@ -119,7 +120,7 @@ void pciSetup(const int8_t pin) {
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
#if USE_X_MAX
#if HAS_X_MAX
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MAX_PIN);
#else
@@ -127,7 +128,7 @@ void setup_endstop_interrupts() {
pciSetup(X_MAX_PIN);
#endif
#endif
#if USE_X_MIN
#if HAS_X_MIN
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MIN_PIN);
#else
@@ -135,7 +136,7 @@ void setup_endstop_interrupts() {
pciSetup(X_MIN_PIN);
#endif
#endif
#if USE_Y_MAX
#if HAS_Y_MAX
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MAX_PIN);
#else
@@ -143,7 +144,7 @@ void setup_endstop_interrupts() {
pciSetup(Y_MAX_PIN);
#endif
#endif
#if USE_Y_MIN
#if HAS_Y_MIN
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MIN_PIN);
#else
@@ -151,7 +152,7 @@ void setup_endstop_interrupts() {
pciSetup(Y_MIN_PIN);
#endif
#endif
#if USE_Z_MAX
#if HAS_Z_MAX
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MAX_PIN);
#else
@@ -159,7 +160,7 @@ void setup_endstop_interrupts() {
pciSetup(Z_MAX_PIN);
#endif
#endif
#if USE_Z_MIN
#if HAS_Z_MIN
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PIN);
#else
@@ -167,97 +168,7 @@ void setup_endstop_interrupts() {
pciSetup(Z_MIN_PIN);
#endif
#endif
#if USE_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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(I_MAX_PIN);
#endif
#elif USE_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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(I_MIN_PIN);
#endif
#endif
#if USE_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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(J_MAX_PIN);
#endif
#elif USE_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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(J_MIN_PIN);
#endif
#endif
#if USE_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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(K_MAX_PIN);
#endif
#elif USE_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. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(K_MIN_PIN);
#endif
#endif
#if USE_U_MAX
#if (digitalPinToInterrupt(U_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(U_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(U_MAX_PIN), "U_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(U_MAX_PIN);
#endif
#elif USE_U_MIN
#if (digitalPinToInterrupt(U_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(U_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(U_MIN_PIN), "U_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(U_MIN_PIN);
#endif
#endif
#if USE_V_MAX
#if (digitalPinToInterrupt(V_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(V_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(V_MAX_PIN), "V_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(V_MAX_PIN);
#endif
#elif USE_V_MIN
#if (digitalPinToInterrupt(V_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(V_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(V_MIN_PIN), "V_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(V_MIN_PIN);
#endif
#endif
#if USE_W_MAX
#if (digitalPinToInterrupt(W_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(W_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(W_MAX_PIN), "W_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(W_MAX_PIN);
#endif
#elif USE_W_MIN
#if (digitalPinToInterrupt(W_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(W_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(W_MIN_PIN), "W_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(W_MIN_PIN);
#endif
#endif
#if USE_X2_MAX
#if HAS_X2_MAX
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN);
#else
@@ -265,7 +176,7 @@ void setup_endstop_interrupts() {
pciSetup(X2_MAX_PIN);
#endif
#endif
#if USE_X2_MIN
#if HAS_X2_MIN
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MIN_PIN);
#else
@@ -273,7 +184,7 @@ void setup_endstop_interrupts() {
pciSetup(X2_MIN_PIN);
#endif
#endif
#if USE_Y2_MAX
#if HAS_Y2_MAX
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MAX_PIN);
#else
@@ -281,7 +192,7 @@ void setup_endstop_interrupts() {
pciSetup(Y2_MAX_PIN);
#endif
#endif
#if USE_Y2_MIN
#if HAS_Y2_MIN
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MIN_PIN);
#else
@@ -289,7 +200,7 @@ void setup_endstop_interrupts() {
pciSetup(Y2_MIN_PIN);
#endif
#endif
#if USE_Z2_MAX
#if HAS_Z2_MAX
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MAX_PIN);
#else
@@ -297,7 +208,7 @@ void setup_endstop_interrupts() {
pciSetup(Z2_MAX_PIN);
#endif
#endif
#if USE_Z2_MIN
#if HAS_Z2_MIN
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MIN_PIN);
#else
@@ -305,7 +216,7 @@ void setup_endstop_interrupts() {
pciSetup(Z2_MIN_PIN);
#endif
#endif
#if USE_Z3_MAX
#if HAS_Z3_MAX
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MAX_PIN);
#else
@@ -313,7 +224,7 @@ void setup_endstop_interrupts() {
pciSetup(Z3_MAX_PIN);
#endif
#endif
#if USE_Z3_MIN
#if HAS_Z3_MIN
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MIN_PIN);
#else
@@ -321,7 +232,7 @@ void setup_endstop_interrupts() {
pciSetup(Z3_MIN_PIN);
#endif
#endif
#if USE_Z4_MAX
#if HAS_Z4_MAX
#if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MAX_PIN);
#else
@@ -329,7 +240,7 @@ void setup_endstop_interrupts() {
pciSetup(Z4_MAX_PIN);
#endif
#endif
#if USE_Z4_MIN
#if HAS_Z4_MIN
#if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MIN_PIN);
#else

View File

@@ -21,11 +21,11 @@
*/
#ifdef __AVR__
#include "../../inc/MarlinConfig.h"
#include "../../inc/MarlinConfigPre.h"
//#define DEBUG_AVR_FAST_PWM
#define DEBUG_OUT ENABLED(DEBUG_AVR_FAST_PWM)
#include "../../core/debug_out.h"
#if NEEDS_HARDWARE_PWM // Specific meta-flag for features that mandate PWM
#include "HAL.h"
struct Timer {
volatile uint8_t* TCCRnQ[3]; // max 3 TCCR registers per timer
@@ -33,207 +33,250 @@ struct Timer {
volatile uint16_t* ICRn; // max 1 ICR register per timer
uint8_t n; // the timer number [0->5]
uint8_t q; // the timer output [0->2] (A->C)
bool isPWM; // True if pin is a "hardware timer"
bool isProtected; // True if timer is protected
};
// Macros for the Timer structure
#define _SET_WGMnQ(T, V) do{ \
*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
*(T.TCCRnQ)[1] = (*(T.TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
}while(0)
// Set TCCR CS bits
#define _SET_CSn(T, V) (*(T.TCCRnQ)[1] = (*(T.TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0))
// Set TCCR COM bits
#define _SET_COMnQ(T, Q, V) (*(T.TCCRnQ)[0] = (*(T.TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q))))
// Set OCRnQ register
#define _SET_OCRnQ(T, Q, V) (*(T.OCRnQ)[Q] = int(V) & 0xFFFF)
// Set ICRn register (one per timer)
#define _SET_ICRn(T, V) (*(T.ICRn) = int(V) & 0xFFFF)
/**
* Return a Timer struct describing a pin's timer.
* get_pwm_timer
* Get the timer information and register of the provided pin.
* Return a Timer struct containing this information.
* Used by set_pwm_frequency, set_pwm_duty
*/
const Timer get_pwm_timer(const pin_t pin) {
Timer get_pwm_timer(const pin_t pin) {
uint8_t q = 0;
switch (digitalPinToTimer(pin)) {
// Protect reserved timers (TIMER0 & TIMER1)
#ifdef TCCR0A
IF_DISABLED(AVR_AT90USB1286_FAMILY, case TIMER0A:)
#if !AVR_AT90USB1286_FAMILY
case TIMER0A:
#endif
case TIMER0B:
#endif
#ifdef TCCR1A
case TIMER1A: case TIMER1B:
#endif
break; // Protect reserved timers (TIMER0 & TIMER1)
#ifdef TCCR0A
case TIMER0B: // Protected timer, but allow setting the duty cycle on OCR0B for pin D4 only
return Timer({ { &TCCR0A, nullptr, nullptr }, { (uint16_t*)&OCR0A, (uint16_t*)&OCR0B, nullptr }, nullptr, 0, 1, true, true });
#endif
#if HAS_TCCR2
case TIMER2:
return Timer({ { &TCCR2, nullptr, nullptr }, { (uint16_t*)&OCR2, nullptr, nullptr }, nullptr, 2, 0, true, false });
#elif ENABLED(USE_OCR2A_AS_TOP)
case TIMER2A: break; // Protect TIMER2A since its OCR is used by TIMER2B
case TIMER2B:
return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, 1, true, false });
break;
#if defined(TCCR2) || defined(TCCR2A)
#ifdef TCCR2
case TIMER2: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2, nullptr, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2, nullptr, nullptr },
/*ICRn*/ nullptr,
/*n, q*/ 2, 0
};
}
#elif defined(TCCR2A)
case TIMER2B: ++q; case TIMER2A:
return Timer({ { &TCCR2A, &TCCR2B, nullptr }, { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr }, nullptr, 2, q, true, false });
#if ENABLED(USE_OCR2A_AS_TOP)
case TIMER2A: break; // protect TIMER2A
case TIMER2B: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
/*ICRn*/ nullptr,
/*n, q*/ 2, 1
};
return timer;
}
#else
case TIMER2B: ++q;
case TIMER2A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR2A, &TCCR2B, nullptr },
/*OCRnQ*/ { (uint16_t*)&OCR2A, (uint16_t*)&OCR2B, nullptr },
/*ICRn*/ nullptr,
2, q
};
return timer;
}
#endif
#endif
#endif
#ifdef OCR3C
case TIMER3C: ++q; case TIMER3B: ++q; case TIMER3A:
return Timer({ { &TCCR3A, &TCCR3B, &TCCR3C }, { &OCR3A, &OCR3B, &OCR3C }, &ICR3, 3, q, true, false });
case TIMER3C: ++q;
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, &TCCR3C },
/*OCRnQ*/ { &OCR3A, &OCR3B, &OCR3C },
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
#elif defined(OCR3B)
case TIMER3B: ++q; case TIMER3A:
return Timer({ { &TCCR3A, &TCCR3B, nullptr }, { &OCR3A, &OCR3B, nullptr }, &ICR3, 3, q, true, false });
case TIMER3B: ++q;
case TIMER3A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR3A, &TCCR3B, nullptr },
/*OCRnQ*/ { &OCR3A, &OCR3B, nullptr },
/*ICRn*/ &ICR3,
/*n, q*/ 3, q
};
return timer;
}
#endif
#ifdef TCCR4A
case TIMER4C: ++q; case TIMER4B: ++q; case TIMER4A:
return Timer({ { &TCCR4A, &TCCR4B, &TCCR4C }, { &OCR4A, &OCR4B, &OCR4C }, &ICR4, 4, q, true, false });
case TIMER4C: ++q;
case TIMER4B: ++q;
case TIMER4A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR4A, &TCCR4B, &TCCR4C },
/*OCRnQ*/ { &OCR4A, &OCR4B, &OCR4C },
/*ICRn*/ &ICR4,
/*n, q*/ 4, q
};
return timer;
}
#endif
#ifdef TCCR5A
case TIMER5C: ++q; case TIMER5B: ++q; case TIMER5A:
return Timer({ { &TCCR5A, &TCCR5B, &TCCR5C }, { &OCR5A, &OCR5B, &OCR5C }, &ICR5, 5, q, true, false });
case TIMER5C: ++q;
case TIMER5B: ++q;
case TIMER5A: {
Timer timer = {
/*TCCRnQ*/ { &TCCR5A, &TCCR5B, &TCCR5C },
/*OCRnQ*/ { &OCR5A, &OCR5B, &OCR5C },
/*ICRn*/ &ICR5,
/*n, q*/ 5, q
};
return timer;
}
#endif
}
return Timer();
Timer timer = {
/*TCCRnQ*/ { nullptr, nullptr, nullptr },
/*OCRnQ*/ { nullptr, nullptr, nullptr },
/*ICRn*/ nullptr,
0, 0
};
return timer;
}
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
DEBUG_ECHOLNPGM("set_pwm_frequency(pin=", pin, ", freq=", f_desired, ")");
const Timer timer = get_pwm_timer(pin);
if (timer.isProtected || !timer.isPWM) return; // Don't proceed if protected timer or not recognized
void set_pwm_frequency(const pin_t pin, int f_desired) {
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
uint16_t size;
if (timer.n == 2) size = 255; else size = 65535;
const bool is_timer2 = timer.n == 2;
const uint16_t maxtop = is_timer2 ? 0xFF : 0xFFFF;
DEBUG_ECHOLNPGM("maxtop=", maxtop);
uint16_t res = 0xFF; // resolution (TOP value)
uint8_t j = CS_NONE; // prescaler index
uint8_t wgm = WGM_PWM_PC_8; // waveform generation mode
uint16_t res = 255; // resolution (TOP value)
uint8_t j = 0; // prescaler index
uint8_t wgm = 1; // waveform generation mode
// Calculating the prescaler and resolution to use to achieve closest frequency
if (f_desired != 0) {
constexpr uint16_t prescaler[] = { 1, 8, (32), 64, (128), 256, 1024 }; // (*) are Timer 2 only
uint16_t f = (F_CPU) / (uint32_t(maxtop) << 11) + 1; // Start with the lowest non-zero frequency achievable (for 16MHz, 1 or 31)
int f = (F_CPU) / (2 * 1024 * size) + 1; // Initialize frequency as lowest (non-zero) achievable
uint16_t prescaler[] = { 0, 1, 8, /*TIMER2 ONLY*/32, 64, /*TIMER2 ONLY*/128, 256, 1024 };
DEBUG_ECHOLNPGM("f=", f);
DEBUG_ECHOLNPGM("(prescaler loop)");
for (uint8_t i = 0; i < COUNT(prescaler); ++i) { // Loop through all prescaler values
const uint32_t p = prescaler[i]; // Extend to 32 bits for calculations
DEBUG_ECHOLNPGM("prescaler[", i, "]=", p);
uint16_t res_fast_temp, res_pc_temp;
if (is_timer2) {
#if ENABLED(USE_OCR2A_AS_TOP) // No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
const uint16_t rft = (F_CPU) / (p * f_desired);
res_fast_temp = rft - 1;
res_pc_temp = rft / 2;
DEBUG_ECHOLNPGM("(Timer2) res_fast_temp=", res_fast_temp, " res_pc_temp=", res_pc_temp);
#else
res_fast_temp = res_pc_temp = maxtop;
DEBUG_ECHOLNPGM("(Timer2) res_fast_temp=", maxtop, " res_pc_temp=", maxtop);
// loop over prescaler values
LOOP_S_L_N(i, 1, 8) {
uint16_t res_temp_fast = 255, res_temp_phase_correct = 255;
if (timer.n == 2) {
// No resolution calculation for TIMER2 unless enabled USE_OCR2A_AS_TOP
#if ENABLED(USE_OCR2A_AS_TOP)
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
#endif
}
else {
if (p == 32 || p == 128) continue; // Skip TIMER2 specific prescalers when not TIMER2
const uint16_t rft = (F_CPU) / (p * f_desired);
DEBUG_ECHOLNPGM("(Not Timer 2) F_CPU=", STRINGIFY(F_CPU), " prescaler=", p, " f_desired=", f_desired);
res_fast_temp = rft - 1;
res_pc_temp = rft / 2;
// Skip TIMER2 specific prescalers when not TIMER2
if (i == 3 || i == 5) continue;
const uint16_t rtf = (F_CPU) / (prescaler[i] * f_desired);
res_temp_fast = rtf - 1;
res_temp_phase_correct = rtf / 2;
}
LIMIT(res_fast_temp, 1U, maxtop);
LIMIT(res_pc_temp, 1U, maxtop);
LIMIT(res_temp_fast, 1U, size);
LIMIT(res_temp_phase_correct, 1U, size);
// Calculate frequencies of test prescaler and resolution values
const uint16_t f_fast_temp = (F_CPU) / (p * (1 + res_fast_temp)),
f_pc_temp = (F_CPU) / ((p * res_pc_temp) << 1),
f_diff = _MAX(f, f_desired) - _MIN(f, f_desired),
f_fast_diff = _MAX(f_fast_temp, f_desired) - _MIN(f_fast_temp, f_desired),
f_pc_diff = _MAX(f_pc_temp, f_desired) - _MIN(f_pc_temp, f_desired);
const int f_temp_fast = (F_CPU) / (prescaler[i] * (1 + res_temp_fast)),
f_temp_phase_correct = (F_CPU) / (2 * prescaler[i] * res_temp_phase_correct),
f_diff = ABS(f - f_desired),
f_fast_diff = ABS(f_temp_fast - f_desired),
f_phase_diff = ABS(f_temp_phase_correct - f_desired);
DEBUG_ECHOLNPGM("f_fast_temp=", f_fast_temp, " f_pc_temp=", f_pc_temp, " f_diff=", f_diff, " f_fast_diff=", f_fast_diff, " f_pc_diff=", f_pc_diff);
if (f_fast_diff < f_diff && f_fast_diff <= f_pc_diff) { // FAST values are closest to desired f
// Set the Wave Generation Mode to FAST PWM
wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_FAST_PWM_OCR2A, WGM2_FAST_PWM)) : uint8_t(WGM_FAST_PWM_ICRn);
// If FAST values are closest to desired f
if (f_fast_diff < f_diff && f_fast_diff <= f_phase_diff) {
// Remember this combination
f = f_fast_temp; res = res_fast_temp; j = i + 1;
DEBUG_ECHOLNPGM("(FAST) updated f=", f);
f = f_temp_fast;
res = res_temp_fast;
j = i;
// Set the Wave Generation Mode to FAST PWM
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_FAST_PWM_OCR2A
#else
WGM2_FAST_PWM
#endif
);
}
else if (f_pc_diff < f_diff) { // PHASE CORRECT values are closes to desired f
else wgm = WGM_FAST_PWM_ICRn;
}
// If PHASE CORRECT values are closes to desired f
else if (f_phase_diff < f_diff) {
f = f_temp_phase_correct;
res = res_temp_phase_correct;
j = i;
// Set the Wave Generation Mode to PWM PHASE CORRECT
wgm = is_timer2 ? uint8_t(TERN(USE_OCR2A_AS_TOP, WGM2_PWM_PC_OCR2A, WGM2_PWM_PC)) : uint8_t(WGM_PWM_PC_ICRn);
f = f_pc_temp; res = res_pc_temp; j = i + 1;
DEBUG_ECHOLNPGM("(PHASE) updated f=", f);
if (timer.n == 2) {
wgm = (
#if ENABLED(USE_OCR2A_AS_TOP)
WGM2_PWM_PC_OCR2A
#else
WGM2_PWM_PC
#endif
);
}
} // prescaler loop
else wgm = WGM_PWM_PC_ICRn;
}
}
}
_SET_WGMnQ(timer.TCCRnQ, wgm);
_SET_CSn(timer.TCCRnQ, j);
_SET_WGMnQ(timer, wgm);
_SET_CSn(timer, j);
if (is_timer2) {
TERN_(USE_OCR2A_AS_TOP, _SET_OCRnQ(timer, 0, res)); // Set OCR2A value (TOP) = res
if (timer.n == 2) {
#if ENABLED(USE_OCR2A_AS_TOP)
_SET_OCRnQ(timer.OCRnQ, 0, res); // Set OCR2A value (TOP) = res
#endif
}
else
_SET_ICRn(timer, res); // Set ICRn value (TOP) = res
_SET_ICRn(timer.ICRn, res); // Set ICRn value (TOP) = res
}
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
// If v is 0 or v_size (max), digitalWrite to LOW or HIGH.
// Note that digitalWrite also disables PWM output for us (sets COM bit to 0)
// Note that digitalWrite also disables pwm output for us (sets COM bit to 0)
if (v == 0)
digitalWrite(pin, invert);
else if (v == v_size)
digitalWrite(pin, !invert);
else {
const Timer timer = get_pwm_timer(pin);
if (timer.isPWM) {
if (timer.n == 0) {
_SET_COMnQ(timer, timer.q, COM_CLEAR_SET); // Only allow a TIMER0B select...
_SET_OCRnQ(timer, timer.q, v); // ...and OCR0B duty update. For output pin D4 no frequency changes are permitted.
}
else if (!timer.isProtected) {
const uint16_t top = timer.n == 2 ? TERN(USE_OCR2A_AS_TOP, *timer.OCRnQ[0], 255) : *timer.ICRn;
_SET_COMnQ(timer, SUM_TERN(HAS_TCCR2, timer.q, timer.q == 2), COM_CLEAR_SET + invert); // COM20 is on bit 4 of TCCR2, so +1 for q==2
_SET_OCRnQ(timer, timer.q, uint16_t(uint32_t(v) * top / v_size)); // Scale 8/16-bit v to top value
}
Timer timer = get_pwm_timer(pin);
if (timer.n == 0) return; // Don't proceed if protected timer or not recognised
// Set compare output mode to CLEAR -> SET or SET -> CLEAR (if inverted)
_SET_COMnQ(timer.TCCRnQ, (timer.q
#ifdef TCCR2
+ (timer.q == 2) // COM20 is on bit 4 of TCCR2, thus requires q + 1 in the macro
#endif
), COM_CLEAR_SET + invert
);
uint16_t top;
if (timer.n == 2) { // if TIMER2
top = (
#if ENABLED(USE_OCR2A_AS_TOP)
*timer.OCRnQ[0] // top = OCR2A
#else
255 // top = 0xFF (max)
#endif
);
}
else
digitalWrite(pin, v < v_size / 2 ? LOW : HIGH);
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
}
}
void MarlinHAL::init_pwm_timers() {
// Init some timer frequencies to a default 1KHz
const pin_t pwm_pin[] = {
#ifdef __AVR_ATmega2560__
10, 5, 6, 46
#elif defined(__AVR_ATmega1280__)
12, 31
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega1284__)
15, 6
#elif defined(__AVR_AT90USB1286__) || defined(__AVR_mega64) || defined(__AVR_mega128)
16, 24
#endif
};
for (uint8_t i = 0; i < COUNT(pwm_pin); ++i)
set_pwm_frequency(pwm_pin[i], 1000);
}
#endif // NEEDS_HARDWARE_PWM
#endif // __AVR__

View File

@@ -245,7 +245,7 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
float count = 0;
if (hz > 0 && (dca || dcb || dcc)) {
count = float(F_CPU) / hz; // 1x prescaler, TOP for 16MHz base freq.
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5kHz (>31)
uint16_t prescaler; // Range of 30.5Hz (65535) 64.5KHz (>31)
if (count >= 255. * 256.) { prescaler = 1024; SET_CS(5, PRESCALER_1024); }
else if (count >= 255. * 64.) { prescaler = 256; SET_CS(5, PRESCALER_256); }
@@ -267,17 +267,17 @@ uint16_t set_pwm_frequency_hz(const_float_t hz, const float dca, const float dcb
SET_WGM(5, FAST_PWM_ICRn); // Fast PWM with ICR5 as TOP
//SERIAL_ECHOLNPGM("Timer 5 Settings:");
//SERIAL_ECHOLNPGM(" Prescaler=", prescaler);
//SERIAL_ECHOLNPGM(" TOP=", ICR5);
//SERIAL_ECHOLNPGM(" OCR5A=", OCR5A);
//SERIAL_ECHOLNPGM(" OCR5B=", OCR5B);
//SERIAL_ECHOLNPGM(" OCR5C=", OCR5C);
//SERIAL_ECHOLNPAIR(" Prescaler=", prescaler);
//SERIAL_ECHOLNPAIR(" TOP=", ICR5);
//SERIAL_ECHOLNPAIR(" OCR5A=", OCR5A);
//SERIAL_ECHOLNPAIR(" OCR5B=", OCR5B);
//SERIAL_ECHOLNPAIR(" 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
SET_CS(5, PRESCALER_64); // 16MHz / 64 = 250KHz
OCR5A = OCR5B = OCR5C = 0;
}
return round(count);

View File

@@ -118,7 +118,7 @@
*/
// Waveform Generation Modes
enum WaveGenMode : uint8_t {
enum WaveGenMode : char {
WGM_NORMAL, // 0
WGM_PWM_PC_8, // 1
WGM_PWM_PC_9, // 2
@@ -138,7 +138,7 @@ enum WaveGenMode : uint8_t {
};
// Wavefore Generation Modes (Timer 2 only)
enum WaveGenMode2 : uint8_t {
enum WaveGenMode2 : char {
WGM2_NORMAL, // 0
WGM2_PWM_PC, // 1
WGM2_CTC_OCR2A, // 2
@@ -150,7 +150,7 @@ enum WaveGenMode2 : uint8_t {
};
// Compare Modes
enum CompareMode : uint8_t {
enum CompareMode : char {
COM_NORMAL, // 0
COM_TOGGLE, // 1 Non-PWM: OCnx ... Both PWM (WGM 9,11,14,15): OCnA only ... else NORMAL
COM_CLEAR_SET, // 2 Non-PWM: OCnx ... Fast PWM: OCnx/Bottom ... PF-FC: OCnx Up/Down
@@ -158,7 +158,7 @@ enum CompareMode : uint8_t {
};
// Clock Sources
enum ClockSource : uint8_t {
enum ClockSource : char {
CS_NONE, // 0
CS_PRESCALER_1, // 1
CS_PRESCALER_8, // 2
@@ -170,7 +170,7 @@ enum ClockSource : uint8_t {
};
// Clock Sources (Timer 2 only)
enum ClockSource2 : uint8_t {
enum ClockSource2 : char {
CS2_NONE, // 0
CS2_PRESCALER_1, // 1
CS2_PRESCALER_8, // 2
@@ -203,33 +203,40 @@ enum ClockSource2 : uint8_t {
TCCR##T##B = (TCCR##T##B & ~(0x3 << WGM##T##2)) | (((int(V) >> 2) & 0x3) << WGM##T##2); \
}while(0)
#define SET_WGM(T,V) _SET_WGM(T,WGM_##V)
// Runtime (see set_pwm_frequency):
#define _SET_WGMnQ(TCCRnQ, V) do{ \
*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << 0)) | (( int(V) & 0x3) << 0); \
*(TCCRnQ)[1] = (*(TCCRnQ)[1] & ~(0x3 << 3)) | (((int(V) >> 2) & 0x3) << 3); \
}while(0)
// Set Clock Select bits
// Ex: SET_CS3(PRESCALER_64);
#ifdef TCCR2
#define HAS_TCCR2 1
#endif
#define _SET_CS(T,V) (TCCR##T##B = (TCCR##T##B & ~(0x7 << CS##T##0)) | ((int(V) & 0x7) << CS##T##0))
#define _SET_CS0(V) _SET_CS(0,V)
#define _SET_CS1(V) _SET_CS(1,V)
#ifdef TCCR2
#define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
#else
#define _SET_CS2(V) _SET_CS(2,V)
#endif
#define _SET_CS3(V) _SET_CS(3,V)
#define _SET_CS4(V) _SET_CS(4,V)
#define _SET_CS5(V) _SET_CS(5,V)
#define SET_CS0(V) _SET_CS0(CS_##V)
#define SET_CS1(V) _SET_CS1(CS_##V)
#if HAS_TCCR2
#define _SET_CS2(V) (TCCR2 = (TCCR2 & ~(0x7 << CS20)) | (int(V) << CS20))
#ifdef TCCR2
#define SET_CS2(V) _SET_CS2(CS2_##V)
#else
#define _SET_CS2(V) _SET_CS(2,V)
#define SET_CS2(V) _SET_CS2(CS_##V)
#endif
#define SET_CS3(V) _SET_CS3(CS_##V)
#define SET_CS4(V) _SET_CS4(CS_##V)
#define SET_CS5(V) _SET_CS5(CS_##V)
#define SET_CS(T,V) SET_CS##T(V)
// Runtime (see set_pwm_frequency)
#define _SET_CSn(TCCRnQ, V) do{ \
(*(TCCRnQ)[1] = (*(TCCRnQ[1]) & ~(0x7 << 0)) | ((int(V) & 0x7) << 0)); \
}while(0)
// Set Compare Mode bits
// Ex: SET_COMS(4,CLEAR_SET,CLEAR_SET,CLEAR_SET);
@@ -239,6 +246,22 @@ enum ClockSource2 : uint8_t {
#define SET_COMB(T,V) SET_COM(T,B,V)
#define SET_COMC(T,V) SET_COM(T,C,V)
#define SET_COMS(T,V1,V2,V3) do{ SET_COMA(T,V1); SET_COMB(T,V2); SET_COMC(T,V3); }while(0)
// Runtime (see set_pwm_duty)
#define _SET_COMnQ(TCCRnQ, Q, V) do{ \
(*(TCCRnQ)[0] = (*(TCCRnQ)[0] & ~(0x3 << (6-2*(Q)))) | (int(V) << (6-2*(Q)))); \
}while(0)
// Set OCRnQ register
// Runtime (see set_pwm_duty):
#define _SET_OCRnQ(OCRnQ, Q, V) do{ \
(*(OCRnQ)[(Q)] = (0x0000) | (int(V) & 0xFFFF)); \
}while(0)
// Set ICRn register (one per timer)
// Runtime (see set_pwm_frequency)
#define _SET_ICRn(ICRn, V) do{ \
(*(ICRn) = (0x0000) | (int(V) & 0xFFFF)); \
}while(0)
// Set Noise Canceler bit
// Ex: SET_ICNC(2,1)
@@ -255,6 +278,84 @@ enum ClockSource2 : uint8_t {
#define SET_FOCB(T,V) SET_FOC(T,B,V)
#define SET_FOCC(T,V) SET_FOC(T,C,V)
#if 0
/**
* PWM availability macros
*/
// Determine which harware PWMs are already in use
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN || P == COOLER_AUTO_FAN_PIN)
#if PIN_EXISTS(CONTROLLER_FAN)
#define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN)
#else
#define PWM_CHK_FAN_B(P) _PWM_CHK_FAN_B(P)
#endif
#if ANY_PIN(FAN, FAN1, FAN2, FAN3, FAN4, FAN5, FAN6, FAN7)
#if PIN_EXISTS(FAN7)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN || P == FAN5_PIN || P == FAN6_PIN || P == FAN7_PIN)
#elif PIN_EXISTS(FAN6)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN || P == FAN5_PIN || P == FAN6_PIN)
#elif PIN_EXISTS(FAN5)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN || P == FAN5_PIN)
#elif PIN_EXISTS(FAN4)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN || P == FAN4_PIN)
#elif PIN_EXISTS(FAN3)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN || P == FAN3_PIN)
#elif PIN_EXISTS(FAN2)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN || P == FAN2_PIN)
#elif PIN_EXISTS(FAN1)
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN || P == FAN1_PIN)
#else
#define PWM_CHK_FAN_A(P) (P == FAN0_PIN)
#endif
#else
#define PWM_CHK_FAN_A(P) false
#endif
#if HAS_MOTOR_CURRENT_PWM
#if PIN_EXISTS(MOTOR_CURRENT_PWM_XY)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_Z || P == MOTOR_CURRENT_PWM_XY)
#elif PIN_EXISTS(MOTOR_CURRENT_PWM_Z)
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E || P == MOTOR_CURRENT_PWM_Z)
#else
#define PWM_CHK_MOTOR_CURRENT(P) (P == MOTOR_CURRENT_PWM_E)
#endif
#else
#define PWM_CHK_MOTOR_CURRENT(P) false
#endif
#ifdef NUM_SERVOS
#if AVR_ATmega2560_FAMILY
#define PWM_CHK_SERVO(P) (P == 5 || (NUM_SERVOS > 12 && P == 6) || (NUM_SERVOS > 24 && P == 46)) // PWMS 3A, 4A & 5A
#elif AVR_ATmega2561_FAMILY
#define PWM_CHK_SERVO(P) (P == 5) // PWM3A
#elif AVR_ATmega1284_FAMILY
#define PWM_CHK_SERVO(P) false
#elif AVR_AT90USB1286_FAMILY
#define PWM_CHK_SERVO(P) (P == 16) // PWM3A
#elif AVR_ATmega328_FAMILY
#define PWM_CHK_SERVO(P) false
#endif
#else
#define PWM_CHK_SERVO(P) false
#endif
#if ENABLED(BARICUDA)
#if HAS_HEATER_1 && HAS_HEATER_2
#define PWM_CHK_HEATER(P) (P == HEATER_1_PIN || P == HEATER_2_PIN)
#elif HAS_HEATER_1
#define PWM_CHK_HEATER(P) (P == HEATER_1_PIN)
#endif
#else
#define PWM_CHK_HEATER(P) false
#endif
#define PWM_CHK(P) (PWM_CHK_HEATER(P) || PWM_CHK_SERVO(P) || PWM_CHK_MOTOR_CURRENT(P) || PWM_CHK_FAN_A(P) || PWM_CHK_FAN_B(P))
#endif // PWM_CHK is not used in Marlin
// define which hardware PWMs are available for the current CPU
// all timer 1 PWMS deleted from this list because they are never available
#if AVR_ATmega2560_FAMILY

View File

@@ -27,41 +27,43 @@
* 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
* 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
* Analog Input : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
*/
#include "../fastio.h"
// change for your board
#define DEBUG_LED DIO21
// UART
#define RXD 0
#define TXD 1
#define RXD DIO0
#define TXD DIO1
// SPI
#define MISO 50
#define MOSI 51
#define SCK 52
#define SS 53
#define SCK DIO52
#define MISO DIO50
#define MOSI DIO51
#define SS DIO53
// TWI (I2C)
#define SCL 21
#define SDA 20
#define SCL DIO21
#define SDA DIO20
// Timers and PWM
#define OC0A 13
#define OC0B 4
#define OC1A 11
#define OC1B 12
#define OC2A 10
#define OC2B 9
#define OC3A 5
#define OC3B 2
#define OC3C 3
#define OC4A 6
#define OC4B 7
#define OC4C 8
#define OC5A 46
#define OC5B 45
#define OC5C 44
#define OC0A DIO13
#define OC0B DIO4
#define OC1A DIO11
#define OC1B DIO12
#define OC2A DIO10
#define OC2B DIO9
#define OC3A DIO5
#define OC3B DIO2
#define OC3C DIO3
#define OC4A DIO6
#define OC4B DIO7
#define OC4C DIO8
#define OC5A DIO46
#define OC5B DIO45
#define OC5C DIO44
// Digital I/O

View File

@@ -30,29 +30,32 @@
#include "../fastio.h"
// change for your board
#define DEBUG_LED DIO46
// UART
#define RXD 0
#define TXD 1
#define RXD DIO0
#define TXD DIO1
// SPI
#define SCK 10
#define MISO 12
#define MOSI 11
#define SS 16
#define SCK DIO10
#define MISO DIO12
#define MOSI DIO11
#define SS DIO16
// TWI (I2C)
#define SCL 17
#define SDA 18
#define SCL DIO17
#define SDA DIO18
// Timers and PWM
#define OC0A 9
#define OC0B 4
#define OC1A 7
#define OC1B 8
#define OC2A 6
#define OC3A 5
#define OC3B 2
#define OC3C 3
#define OC0A DIO9
#define OC0B DIO4
#define OC1A DIO7
#define OC1B DIO8
#define OC2A DIO6
#define OC3A DIO5
#define OC3B DIO2
#define OC3C DIO3
// Digital I/O

View File

@@ -30,27 +30,29 @@
#include "../fastio.h"
#define DEBUG_LED AIO5
// UART
#define RXD 0
#define TXD 1
#define RXD DIO0
#define TXD DIO1
// SPI
#define SS 10
#define MOSI 11
#define MISO 12
#define SCK 13
#define SCK DIO13
#define MISO DIO12
#define MOSI DIO11
#define SS DIO10
// TWI (I2C)
#define SCL AIO5
#define SDA AIO4
// Timers and PWM
#define OC0A 6
#define OC0B 5
#define OC1A 9
#define OC1B 10
#define OC2A 11
#define OC2B 3
#define OC0A DIO6
#define OC0B DIO5
#define OC1A DIO9
#define OC1B DIO10
#define OC2A DIO11
#define OC2B DIO3
// Digital I/O

View File

@@ -56,32 +56,34 @@
#include "../fastio.h"
// UART
#define RXD 8
#define TXD 9
#define RXD0 8
#define TXD0 9
#define DEBUG_LED DIO0
#define RXD1 10
#define TXD1 11
// UART
#define RXD DIO8
#define TXD DIO9
#define RXD0 DIO8
#define TXD0 DIO9
#define RXD1 DIO10
#define TXD1 DIO11
// SPI
#define SS 4
#define MOSI 5
#define MISO 6
#define SCK 7
#define SCK DIO7
#define MISO DIO6
#define MOSI DIO5
#define SS DIO4
// TWI (I2C)
#define SCL 16
#define SDA 17
#define SCL DIO16
#define SDA DIO17
// Timers and PWM
#define OC0A 3
#define OC0B 4
#define OC1A 13
#define OC1B 12
#define OC2A 15
#define OC2B 14
#define OC0A DIO3
#define OC0B DIO4
#define OC1A DIO13
#define OC1B DIO12
#define OC2A DIO15
#define OC2B DIO14
// Digital I/O

View File

@@ -31,11 +31,14 @@
#include "../fastio.h"
// change for your board
#define DEBUG_LED DIO31 /* led D5 red */
// SPI
#define SS 20 // 8
#define SCK 21 // 9
#define MOSI 22 // 10
#define MISO 23 // 11
#define SCK DIO21 // 9
#define MISO DIO23 // 11
#define MOSI DIO22 // 10
#define SS DIO20 // 8
// Digital I/O
@@ -676,6 +679,7 @@
#define PF7_PWM 0
#define PF7_DDR DDRF
/**
* Some of the pin mapping functions of the Teensduino extension to the Arduino IDE
* do not function the same as the other Arduino extensions.

View File

@@ -21,6 +21,6 @@
*/
#pragma once
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/AVR."
#endif

View File

@@ -25,81 +25,35 @@
* Test AVR-specific configuration values for errors at compile-time.
*/
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/AVR."
#endif
/**
* Check for common serial pin conflicts
*/
#define CHECK_SERIAL_PIN(N) ( \
X_STOP_PIN == N || Y_STOP_PIN == N || Z_STOP_PIN == N \
|| X_MIN_PIN == N || Y_MIN_PIN == N || Z_MIN_PIN == N \
|| X_MAX_PIN == N || Y_MAX_PIN == N || Z_MAX_PIN == N \
|| X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_PIN == N \
|| X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
|| BTN_EN1 == N || BTN_EN2 == N || LCD_PINS_EN == N \
)
#if SERIAL_IN_USE(0)
// D0-D1. No known conflicts.
#endif
#if SERIAL_IN_USE(1)
#if NOT_TARGET(__AVR_ATmega644P__, __AVR_ATmega1284P__)
#if CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19)
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
#endif
#else
#if CHECK_SERIAL_PIN(10) || CHECK_SERIAL_PIN(11)
#error "Serial Port 1 pin D10 and/or D11 conflicts with another pin on the board."
#endif
#endif
#endif
#if SERIAL_IN_USE(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
#endif
#if SERIAL_IN_USE(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15))
#error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board."
#endif
#undef CHECK_SERIAL_PIN
/**
* Checks for FAST PWM
*/
#if ALL(FAST_PWM_FAN, USE_OCR2A_AS_TOP, HAS_TCCR2)
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2."
#endif
/**
* Checks for SOFT PWM
*/
#if HAS_FAN0 && FAN0_PIN == 9 && DISABLED(FAN_SOFT_PWM) && ENABLED(SPEAKER)
#error "FAN0_PIN 9 Hardware PWM uses Timer 2 which conflicts with Arduino AVR Tone Timer (for SPEAKER)."
#error "Disable SPEAKER or enable FAN_SOFT_PWM."
#if ENABLED(FAST_PWM_FAN) && (ENABLED(USE_OCR2A_AS_TOP) && defined(TCCR2))
#error "USE_OCR2A_AS_TOP does not apply to devices with a single output TIMER2"
#endif
/**
* Sanity checks for Spindle / Laser PWM
*/
#if ENABLED(SPINDLE_LASER_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)
#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)
#error "Counter/Timer for SPINDLE_LASER_PWM_PIN is used by the servo system."
#endif
#elif SPINDLE_LASER_FREQUENCY
#error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_USE_PWM."
#elif defined(SPINDLE_LASER_FREQUENCY)
#error "SPINDLE_LASER_FREQUENCY requires SPINDLE_LASER_PWM."
#endif
/**
* The Trinamic library includes SoftwareSerial.h, leading to a compile error.
*/
#if ALL(HAS_TRINAMIC_CONFIG, ENDSTOP_INTERRUPTS_FEATURE)
#if BOTH(HAS_TRINAMIC_CONFIG, ENDSTOP_INTERRUPTS_FEATURE)
#error "TMCStepper includes SoftwareSerial.h which is incompatible with ENDSTOP_INTERRUPTS_FEATURE. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
#if ALL(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS)
#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS)
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
#endif
@@ -109,7 +63,3 @@
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not supported on AVR boards."
#endif
#if USING_PULLDOWNS
#error "PULLDOWN pin mode is not available on AVR boards."
#endif

View File

@@ -27,16 +27,15 @@
// intRes = longIn1 * longIn2 >> 24
// uses:
// r1, r0 for the result of mul.
// [tmp1] to store 0.
// [tmp2] to store bits 16-23 of the 56 bit result. The top bit of [tmp2] is used for rounding.
// Note that the lower two bytes and the upper two bytes of the 56 bit result are not calculated.
// This can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
// [intRes] (A B) is bits 24-39 and is the returned value.
// [longIn1] (C B A) is a 24 bit parameter.
// [longIn2] (D C B A) is a 32 bit parameter.
// A[tmp] to store 0
// B[tmp] to store bits 16-23 of the 48bit result. The top bit is used to round the two byte result.
// note that the lower two bytes and the upper byte of the 48bit result are not calculated.
// this can cause the result to be out by one as the lower bytes may cause carries into the upper ones.
// B A are bits 24-39 and are the returned value
// C B A is longIn1
// D C B A is longIn2
//
FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
static FORCE_INLINE uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2) {
uint8_t tmp1;
uint8_t tmp2;
uint16_t intRes;
@@ -67,9 +66,11 @@ FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
A("add %[tmp2], r1")
A("adc %A[intRes], %[tmp1]")
A("adc %B[intRes], %[tmp1]")
A("lsr %[tmp2]")
A("adc %A[intRes], %[tmp1]")
A("adc %B[intRes], %[tmp1]")
A("mul %D[longIn2], %A[longIn1]")
A("lsl %[tmp2]")
A("adc %A[intRes], r0")
A("add %A[intRes], r0")
A("adc %B[intRes], r1")
A("mul %D[longIn2], %B[longIn1]")
A("add %B[intRes], r0")
@@ -84,16 +85,11 @@ FORCE_INLINE static uint16_t MultiU24X32toH16(uint32_t longIn1, uint32_t longIn2
return intRes;
}
// intRes = intIn1 * intIn2 >> 8
// intRes = intIn1 * intIn2 >> 16
// uses:
// r1, r0 for the result of mul. After the second mul, r0 holds bits 0-7 of the 24 bit result and
// the top bit of r0 is used for rounding.
// [tmp] to store 0.
// [intRes] (A B) is bits 8-15 and is the returned value.
// [charIn1] is an 8 bit parameter.
// [intIn2] (B A) is a 16 bit parameter.
//
FORCE_INLINE static uint16_t MultiU8X16toH16(uint8_t charIn1, uint16_t intIn2) {
// r26 to store 0
// r27 to store the byte 1 of the 24 bit result
static FORCE_INLINE uint16_t MultiU16X8toH16(uint8_t charIn1, uint16_t intIn2) {
uint8_t tmp;
uint16_t intRes;
__asm__ __volatile__ (
@@ -101,8 +97,10 @@ FORCE_INLINE static uint16_t MultiU8X16toH16(uint8_t charIn1, uint16_t intIn2) {
A("mul %[charIn1], %B[intIn2]")
A("movw %A[intRes], r0")
A("mul %[charIn1], %A[intIn2]")
A("lsl r0")
A("adc %A[intRes], r1")
A("add %A[intRes], r1")
A("adc %B[intRes], %[tmp]")
A("lsr r0")
A("adc %A[intRes], %[tmp]")
A("adc %B[intRes], %[tmp]")
A("clr r1")
: [intRes] "=&r" (intRes),

View File

@@ -2,9 +2,6 @@
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
@@ -64,25 +61,23 @@
#define VALID_PIN(pin) (pin >= 0 && pin < NUM_DIGITAL_PINS ? 1 : 0)
#if AVR_ATmega1284_FAMILY
#define IS_ANALOG(P) WITHIN(P, analogInputToDigitalPin(7), analogInputToDigitalPin(0))
#define DIGITAL_PIN_TO_ANALOG_PIN(P) int(IS_ANALOG(P) ? (P) - analogInputToDigitalPin(7) : -1)
#define DIGITAL_PIN_TO_ANALOG_PIN(P) int(analogInputToDigitalPin(0) - (P))
#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(7) && (P) <= analogInputToDigitalPin(0))
#else
#define _ANALOG1(P) WITHIN(P, analogInputToDigitalPin(0), analogInputToDigitalPin(7))
#define _ANALOG2(P) WITHIN(P, analogInputToDigitalPin(8), analogInputToDigitalPin(15))
#define IS_ANALOG(P) (_ANALOG1(P) || _ANALOG2(P))
#define DIGITAL_PIN_TO_ANALOG_PIN(P) int(_ANALOG1(P) ? (P) - analogInputToDigitalPin(0) : _ANALOG2(P) ? (P) - analogInputToDigitalPin(8) + 8 : -1)
#define DIGITAL_PIN_TO_ANALOG_PIN(P) int((P) - analogInputToDigitalPin(0))
#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && ((P) <= analogInputToDigitalPin(15) || (P) <= analogInputToDigitalPin(7)))
#endif
#define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin)
#define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin
void PRINT_ARRAY_NAME(uint8_t x) {
PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name);
for (uint8_t y = 0; y < MAX_NAME_LENGTH; ++y) {
char *name_mem_pointer = (char*)pgm_read_ptr(&pin_array[x].name);
LOOP_L_N(y, MAX_NAME_LENGTH) {
char temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0)
SERIAL_CHAR(temp_char);
else {
for (uint8_t i = 0; i < MAX_NAME_LENGTH - y; ++i) SERIAL_CHAR(' ');
LOOP_L_N(i, MAX_NAME_LENGTH - y) SERIAL_CHAR(' ');
break;
}
}
@@ -90,6 +85,7 @@ void PRINT_ARRAY_NAME(uint8_t x) {
#define GET_ARRAY_IS_DIGITAL(x) pgm_read_byte(&pin_array[x].is_digital)
#if defined(__AVR_ATmega1284P__) // 1284 IDE extensions set this to the number of
#undef NUM_DIGITAL_PINS // digital only pins while all other CPUs have it
#define NUM_DIGITAL_PINS 32 // set to digital only + digital/analog
@@ -103,18 +99,18 @@ void PRINT_ARRAY_NAME(uint8_t x) {
return true; \
} else return false
#define ABTEST(N) defined(TCCR##N##A) && defined(COM##N##A1)
/**
* Print a pin's PWM status.
* Return true if it's currently a PWM pin.
*/
bool pwm_status(uint8_t pin) {
static bool pwm_status(uint8_t pin) {
char buffer[20]; // for the sprintf statements
switch (digitalPinToTimer_DEBUG(pin)) {
#if ABTEST(0)
#if defined(TCCR0A) && defined(COM0A1)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
PWM_CASE(0, A);
@@ -123,7 +119,7 @@ bool pwm_status(uint8_t pin) {
PWM_CASE(0, B);
#endif
#if ABTEST(1)
#if defined(TCCR1A) && defined(COM1A1)
PWM_CASE(1, A);
PWM_CASE(1, B);
#if defined(COM1C1) && defined(TIMER1C)
@@ -131,12 +127,12 @@ bool pwm_status(uint8_t pin) {
#endif
#endif
#if ABTEST(2)
#if defined(TCCR2A) && defined(COM2A1)
PWM_CASE(2, A);
PWM_CASE(2, B);
#endif
#if ABTEST(3)
#if defined(TCCR3A) && defined(COM3A1)
PWM_CASE(3, A);
PWM_CASE(3, B);
#ifdef COM3C1
@@ -150,7 +146,7 @@ bool pwm_status(uint8_t pin) {
PWM_CASE(4, C);
#endif
#if ABTEST(5)
#if defined(TCCR5A) && defined(COM5A1)
PWM_CASE(5, A);
PWM_CASE(5, B);
PWM_CASE(5, C);
@@ -163,23 +159,25 @@ bool pwm_status(uint8_t pin) {
SERIAL_ECHO_SP(2);
} // pwm_status
const volatile uint8_t* const PWM_other[][3] PROGMEM = {
{ &TCCR0A, &TCCR0B, &TIMSK0 },
{ &TCCR1A, &TCCR1B, &TIMSK1 },
#if ABTEST(2)
#if defined(TCCR2A) && defined(COM2A1)
{ &TCCR2A, &TCCR2B, &TIMSK2 },
#endif
#if ABTEST(3)
#if defined(TCCR3A) && defined(COM3A1)
{ &TCCR3A, &TCCR3B, &TIMSK3 },
#endif
#ifdef TCCR4A
{ &TCCR4A, &TCCR4B, &TIMSK4 },
#endif
#if ABTEST(5)
#if defined(TCCR5A) && defined(COM5A1)
{ &TCCR5A, &TCCR5B, &TIMSK5 },
#endif
};
const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
#ifdef TIMER0A
@@ -194,11 +192,11 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
{ (const uint8_t*)&OCR1A, (const uint8_t*)&OCR1B, 0 },
#endif
#if ABTEST(2)
#if defined(TCCR2A) && defined(COM2A1)
{ &OCR2A, &OCR2B, 0 },
#endif
#if ABTEST(3)
#if defined(TCCR3A) && defined(COM3A1)
#ifdef COM3C1
{ (const uint8_t*)&OCR3A, (const uint8_t*)&OCR3B, (const uint8_t*)&OCR3C },
#else
@@ -210,11 +208,12 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
{ (const uint8_t*)&OCR4A, (const uint8_t*)&OCR4B, (const uint8_t*)&OCR4C },
#endif
#if ABTEST(5)
#if defined(TCCR5A) && defined(COM5A1)
{ (const uint8_t*)&OCR5A, (const uint8_t*)&OCR5B, (const uint8_t*)&OCR5C },
#endif
};
#define TCCR_A(T) pgm_read_word(&PWM_other[T][0])
#define TCCR_B(T) pgm_read_word(&PWM_other[T][1])
#define TIMSK(T) pgm_read_word(&PWM_other[T][2])
@@ -229,16 +228,16 @@ const volatile uint8_t* const PWM_OCR[][3] PROGMEM = {
#define OCR_VAL(T, L) pgm_read_word(&PWM_OCR[T][L])
void err_is_counter() { SERIAL_ECHOPGM(" non-standard PWM mode"); }
void err_is_interrupt() { SERIAL_ECHOPGM(" compare interrupt enabled"); }
void err_prob_interrupt() { SERIAL_ECHOPGM(" overflow interrupt enabled"); }
void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin"); SERIAL_ECHO_SP(14); }
static void err_is_counter() { SERIAL_ECHOPGM(" non-standard PWM mode"); }
static void err_is_interrupt() { SERIAL_ECHOPGM(" compare interrupt enabled"); }
static void err_prob_interrupt() { SERIAL_ECHOPGM(" overflow interrupt enabled"); }
static void print_is_also_tied() { SERIAL_ECHOPGM(" is also tied to this pin"); SERIAL_ECHO_SP(14); }
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);
SERIAL_ECHOPGM(" COM", AS_DIGIT(N));
SERIAL_ECHOPAIR(" COM", AS_CHAR('0' + N));
SERIAL_CHAR(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
@@ -248,7 +247,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
uint8_t WGM = (((*TCCRB & _BV(WGM_2)) >> 1) | (*TCCRA & (_BV(WGM_0) | _BV(WGM_1))));
if (N == 4) WGM |= ((*TCCRB & _BV(WGM_3)) >> 1);
SERIAL_ECHOPGM(" TIMER", AS_DIGIT(T));
SERIAL_ECHOPAIR(" TIMER", AS_CHAR(T + '0'));
SERIAL_CHAR(L);
SERIAL_ECHO_SP(3);
@@ -260,14 +259,14 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
const uint16_t *OCRVAL16 = (uint16_t*)OCR_VAL(T, L - 'A');
PWM_PRINT(*OCRVAL16);
}
SERIAL_ECHOPGM(" WGM: ", WGM);
SERIAL_ECHOPAIR(" WGM: ", WGM);
com_print(T,L);
SERIAL_ECHOPGM(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "A: ", *TCCRA);
SERIAL_ECHOPGM(" TCCR", AS_DIGIT(T), "B: ", *TCCRB);
SERIAL_ECHOPAIR(" CS: ", (*TCCRB & (_BV(CS_0) | _BV(CS_1) | _BV(CS_2)) ));
SERIAL_ECHOPAIR(" TCCR", AS_CHAR(T + '0'), "A: ", *TCCRA);
SERIAL_ECHOPAIR(" TCCR", AS_CHAR(T + '0'), "B: ", *TCCRB);
const uint8_t *TMSK = (uint8_t*)TIMSK(T);
SERIAL_ECHOPGM(" TIMSK", AS_DIGIT(T), ": ", *TMSK);
SERIAL_ECHOPAIR(" TIMSK", AS_CHAR(T + '0'), ": ", *TMSK);
const uint8_t OCIE = L - 'A' + 1;
if (N == 3) { if (WGM == 0 || WGM == 2 || WGM == 4 || WGM == 6) err_is_counter(); }
@@ -276,10 +275,10 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
if (TEST(*TMSK, TOIE)) err_prob_interrupt();
}
void pwm_details(uint8_t pin) {
static void pwm_details(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
#if ABTEST(0)
#if defined(TCCR0A) && defined(COM0A1)
#ifdef TIMER0A
#if !AVR_AT90USB1286_FAMILY // not available in Teensyduino type IDEs
case TIMER0A: timer_prefix(0, 'A', 3); break;
@@ -288,7 +287,7 @@ void pwm_details(uint8_t pin) {
case TIMER0B: timer_prefix(0, 'B', 3); break;
#endif
#if ABTEST(1)
#if defined(TCCR1A) && defined(COM1A1)
case TIMER1A: timer_prefix(1, 'A', 4); break;
case TIMER1B: timer_prefix(1, 'B', 4); break;
#if defined(COM1C1) && defined(TIMER1C)
@@ -296,12 +295,12 @@ void pwm_details(uint8_t pin) {
#endif
#endif
#if ABTEST(2)
#if defined(TCCR2A) && defined(COM2A1)
case TIMER2A: timer_prefix(2, 'A', 3); break;
case TIMER2B: timer_prefix(2, 'B', 3); break;
#endif
#if ABTEST(3)
#if defined(TCCR3A) && defined(COM3A1)
case TIMER3A: timer_prefix(3, 'A', 4); break;
case TIMER3B: timer_prefix(3, 'B', 4); break;
#ifdef COM3C1
@@ -315,7 +314,7 @@ void pwm_details(uint8_t pin) {
case TIMER4C: timer_prefix(4, 'C', 4); break;
#endif
#if ABTEST(5)
#if defined(TCCR5A) && defined(COM5A1)
case TIMER5A: timer_prefix(5, 'A', 4); break;
case TIMER5B: timer_prefix(5, 'B', 4); break;
case TIMER5C: timer_prefix(5, 'C', 4); break;
@@ -349,14 +348,17 @@ void pwm_details(uint8_t pin) {
#endif
} // pwm_details
#ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs
int digitalRead_mod(const pin_t pin) { // same as digitalRead except the PWM stop section has been removed
int digitalRead_mod(const int8_t pin) { // same as digitalRead except the PWM stop section has been removed
const uint8_t port = digitalPinToPort_DEBUG(pin);
return (port != NOT_A_PIN) && (*portInputRegister(port) & digitalPinToBitMask_DEBUG(pin)) ? HIGH : LOW;
}
#endif
void print_port(const pin_t pin) { // print port number
#ifndef PRINT_PORT
void print_port(int8_t pin) { // print port number
#ifdef digitalPinToPort_DEBUG
uint8_t x;
SERIAL_ECHOPGM(" Port: ");
@@ -386,7 +388,8 @@ void print_port(const pin_t pin) { // print port number
#endif
}
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PORT(p) print_port(p)
#undef ABTEST
#endif
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)

View File

@@ -2,9 +2,6 @@
* 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
@@ -22,10 +19,11 @@
#pragma once
//
// Some of the pin mapping functions of the Arduino IDE Teensduino extension
// function differently from other Arduino extensions.
// some of the pin mapping functions of the Teensduino extension to the Arduino IDE
// do not function the same as the other Arduino extensions
//
#define TEENSYDUINO_IDE
//digitalPinToTimer(pin) function works like Arduino but Timers are not defined
@@ -47,6 +45,8 @@
#define PE 5
#define PF 6
#undef digitalPinToPort
const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PD, // 0 - PD0 - INT0 - PWM
PD, // 1 - PD1 - INT1 - PWM
@@ -98,7 +98,7 @@ const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
PE, // 47 - PE3 (not defined in teensyduino)
};
#define digitalPinToPort(P) pgm_read_byte(digital_pin_to_port_PGM[P])
#define digitalPinToPort(P) ( pgm_read_byte( digital_pin_to_port_PGM + (P) ) )
// digitalPinToBitMask(pin) is OK

View File

@@ -2,9 +2,6 @@
* 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
@@ -231,6 +228,7 @@ const uint8_t PROGMEM digital_pin_to_bit_mask_PGM_plus_70[] = {
#define digitalPinToBitMask_plus_70(P) ( pgm_read_byte( digital_pin_to_bit_mask_PGM_plus_70 + (P) ) )
const uint8_t PROGMEM digital_pin_to_timer_PGM_plus_70[] = {
// TIMERS
// ------------------------

View File

@@ -1,9 +1,7 @@
/**
* 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
* 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
@@ -36,23 +34,23 @@ typedef uint16_t hal_timer_t;
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 1
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 1
#endif
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#endif
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 0
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 0
#endif
#define TEMP_TIMER_FREQUENCY (((F_CPU) + 0x2000) / 0x4000)
#define TEMP_TIMER_FREQUENCY ((F_CPU) / 64.0 / 256.0)
#define STEPPER_TIMER_RATE HAL_TIMER_RATE
#define STEPPER_TIMER_PRESCALE 8
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000)
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // Cannot be of type double
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
@@ -60,13 +58,13 @@ typedef uint16_t hal_timer_t;
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0A)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0A)
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
switch (timer_num) {
case MF_TIMER_STEP:
case STEP_TIMER_NUM:
// waveform generation = 0100 = CTC
SET_WGM(1, CTC_OCRnA);
@@ -86,10 +84,10 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
TCNT1 = 0;
break;
case MF_TIMER_TEMP:
case TEMP_TIMER_NUM:
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0A = 128;
OCR0B = 128;
break;
}
}
@@ -111,12 +109,12 @@ FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t) {
* (otherwise, characters will be lost due to UART overflow).
* Then: Stepper, Endstops, Temperature, and -finally- all others.
*/
#define HAL_timer_isr_prologue(T) NOOP
#define HAL_timer_isr_epilogue(T) NOOP
#ifndef HAL_STEP_TIMER_ISR
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
/* 18 cycles maximum latency */
#ifndef 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_bottom() asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
@@ -182,7 +180,7 @@ void TIMER1_COMPA_vect() { \
: \
: [timsk0] "i" ((uint16_t)&TIMSK0), \
[timsk1] "i" ((uint16_t)&TIMSK1), \
[msk0] "M" ((uint8_t)(1<<OCIE0A)),\
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
: \
); \
@@ -195,9 +193,9 @@ void TIMER1_COMPA_vect_bottom()
/* 14 cycles maximum latency */
#define HAL_TEMP_TIMER_ISR() \
extern "C" void TIMER0_COMPA_vect() __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPA_vect_bottom() asm ("TIMER0_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPA_vect() { \
extern "C" void TIMER0_COMPB_vect() __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPB_vect_bottom() asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPB_vect() { \
__asm__ __volatile__ ( \
A("push r16") /* 2 Save R16 */ \
A("in r16, __SREG__") /* 1 Get SREG */ \
@@ -225,7 +223,7 @@ void TIMER0_COMPA_vect() { \
A("push r30") \
A("push r31") \
A("clr r1") /* C runtime expects this register to be 0 */ \
A("call TIMER0_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("pop r31") \
A("pop r30") \
A("pop r27") \
@@ -253,10 +251,10 @@ void TIMER0_COMPA_vect() { \
A("reti") /* 4 Return from interrupt */ \
: \
: [timsk0] "i"((uint16_t)&TIMSK0), \
[msk0] "M" ((uint8_t)(1<<OCIE0A)) \
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
: \
); \
} \
void TIMER0_COMPA_vect_bottom()
void TIMER0_COMPB_vect_bottom()
#endif // HAL_TEMP_TIMER_ISR

View File

@@ -62,10 +62,10 @@
#include "../shared/Marduino.h"
#include "../shared/Delay.h"
#include <U8glib-HAL.h>
#include <U8glib.h>
static uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
static volatile uint8_t *u8g_outData, *u8g_outClock;
uint8_t u8g_bitData, u8g_bitNotData, u8g_bitClock, u8g_bitNotClock;
volatile uint8_t *u8g_outData, *u8g_outClock;
static void u8g_com_arduino_init_shift_out(uint8_t dataPin, uint8_t clockPin) {
u8g_outData = portOutputRegister(digitalPinToPort(dataPin));
@@ -88,7 +88,7 @@ void u8g_spiSend_sw_AVR_mode_0(uint8_t val) {
volatile uint8_t *outData = u8g_outData,
*outClock = u8g_outClock;
U8G_ATOMIC_START();
for (uint8_t i = 0; i < 8; ++i) {
LOOP_L_N(i, 8) {
if (val & 0x80)
*outData |= bitData;
else
@@ -108,7 +108,7 @@ void u8g_spiSend_sw_AVR_mode_3(uint8_t val) {
volatile uint8_t *outData = u8g_outData,
*outClock = u8g_outClock;
U8G_ATOMIC_START();
for (uint8_t i = 0; i < 8; ++i) {
LOOP_L_N(i, 8) {
*outClock &= bitNotClock;
if (val & 0x80)
*outData |= bitData;
@@ -120,6 +120,7 @@ void u8g_spiSend_sw_AVR_mode_3(uint8_t val) {
U8G_ATOMIC_END();
}
#if ENABLED(FYSETC_MINI_12864)
#define SPISEND_SW_AVR u8g_spiSend_sw_AVR_mode_3
#else

View File

@@ -0,0 +1,70 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef __AVR__
#include "../../inc/MarlinConfig.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#include "../../MarlinCore.h"
// Initialize watchdog with 8s timeout, if possible. Otherwise, make it 4s.
void watchdog_init() {
#if ENABLED(WATCHDOG_DURATION_8S) && defined(WDTO_8S)
#define WDTO_NS WDTO_8S
#else
#define WDTO_NS WDTO_4S
#endif
#if ENABLED(WATCHDOG_RESET_MANUAL)
// Enable the watchdog timer, but only for the interrupt.
// Take care, as this requires the correct order of operation, with interrupts disabled.
// See the datasheet of any AVR chip for details.
wdt_reset();
cli();
_WD_CONTROL_REG = _BV(_WD_CHANGE_BIT) | _BV(WDE);
_WD_CONTROL_REG = _BV(WDIE) | (WDTO_NS & 0x07) | ((WDTO_NS & 0x08) << 2); // WDTO_NS directly does not work. bit 0-2 are consecutive in the register but the highest value bit is at bit 5
// So worked for up to WDTO_2S
sei();
wdt_reset();
#else
wdt_enable(WDTO_NS); // The function handles the upper bit correct.
#endif
//delay(10000); // test it!
}
//===========================================================================
//=================================== ISR ===================================
//===========================================================================
// Watchdog timer interrupt, called if main program blocks >4sec and manual reset is enabled.
#if ENABLED(WATCHDOG_RESET_MANUAL)
ISR(WDT_vect) {
sei(); // With the interrupt driven serial we need to allow interrupts.
SERIAL_ERROR_MSG(STR_WATCHDOG_FIRED);
minkill(); // interrupt-safe final kill and infinite loop
}
#endif
#endif // USE_WATCHDOG
#endif // __AVR__

View File

@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 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
@@ -21,19 +21,11 @@
*/
#pragma once
#include "../inc/MarlinConfigPre.h"
#include <avr/wdt.h>
#include <Wire.h>
#include <INA226.h>
// Initialize watchdog with a 4 second interrupt time
void watchdog_init();
class Ammeter {
private:
static float scale;
public:
static float current;
static void init();
static float read();
};
extern Ammeter ammeter;
// Reset watchdog. MUST be called at least every 4 seconds after the
// first watchdog_init or AVR will go into emergency procedures.
inline void HAL_watchdog_refresh() { wdt_reset(); }

View File

@@ -1,9 +1,7 @@
/**
* 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
* 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
@@ -27,7 +25,7 @@
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfig.h"
#include "../../MarlinCore.h"
#include "HAL.h"
#include <Wire.h>
#include "usb/usb_task.h"
@@ -36,33 +34,39 @@
// Public Variables
// ------------------------
uint16_t MarlinHAL::adc_result;
uint16_t HAL_adc_result;
// ------------------------
// Public functions
// ------------------------
#if ENABLED(POSTMORTEM_DEBUGGING)
extern void install_min_serial();
#endif
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
void MarlinHAL::init() {
#if HAS_MEDIA
// HAL initialization task
void HAL_init() {
// Initialize the USB stack
#if ENABLED(SDSUPPORT)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
usb_task_init(); // Initialize the USB stack
usb_task_init();
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
void MarlinHAL::init_board() {
#ifdef BOARD_INIT
BOARD_INIT();
#endif
// HAL idle task
void HAL_idletask() {
// Perform USB stack housekeeping
usb_task_idle();
}
void MarlinHAL::idletask() { usb_task_idle(); } // Perform USB stack housekeeping
// Disable interrupts
void cli() { noInterrupts(); }
uint8_t MarlinHAL::get_reset_source() {
// Enable interrupts
void sei() { interrupts(); }
void HAL_clear_reset_source() { }
uint8_t HAL_get_reset_source() {
switch ((RSTC->RSTC_SR >> 8) & 0x07) {
case 0: return RST_POWER_ON;
case 1: return RST_BACKUP;
@@ -73,105 +77,13 @@ uint8_t MarlinHAL::get_reset_source() {
}
}
void MarlinHAL::reboot() { rstc_start_software_reset(RSTC); }
void HAL_reboot() { rstc_start_software_reset(RSTC); }
// ------------------------
// Watchdog Timer
// ------------------------
#if ENABLED(USE_WATCHDOG)
// Initialize watchdog - On SAM3X, Watchdog was already configured
// and enabled or disabled at startup, so no need to reconfigure it
// here.
void MarlinHAL::watchdog_init() { WDT_Restart(WDT); } // Reset watchdog to start clean
// Reset watchdog. MUST be called at least every 4 seconds after the
// first watchdog_init or AVR will go into emergency procedures.
void MarlinHAL::watchdog_refresh() { watchdogReset(); }
#endif
// Override Arduino runtime to either config or disable the watchdog
//
// We need to configure the watchdog as soon as possible in the boot
// process, because watchdog initialization at hardware reset on SAM3X8E
// is unreliable, and there is risk of unintended resets if we delay
// that initialization to a later time.
void watchdogSetup() {
#if ENABLED(USE_WATCHDOG)
// 4 seconds timeout
uint32_t timeout = TERN(WATCHDOG_DURATION_8S, 8000, 4000);
// Calculate timeout value in WDT counter ticks: This assumes
// the slow clock is running at 32.768 kHz watchdog
// frequency is therefore 32768 / 128 = 256 Hz
timeout = (timeout << 8) / 1000;
if (timeout == 0)
timeout = 1;
else if (timeout > 0xFFF)
timeout = 0xFFF;
// We want to enable the watchdog with the specified timeout
uint32_t value =
WDT_MR_WDV(timeout) | // With the specified timeout
WDT_MR_WDD(timeout) | // and no invalid write window
#if !(SAMV70 || SAMV71 || SAME70 || SAMS70)
WDT_MR_WDRPROC | // WDT fault resets processor only - We want
// to keep PIO controller state
#endif
WDT_MR_WDDBGHLT | // WDT stops in debug state.
WDT_MR_WDIDLEHLT; // WDT stops in idle state.
#if ENABLED(WATCHDOG_RESET_MANUAL)
// We enable the watchdog timer, but only for the interrupt.
// Configure WDT to only trigger an interrupt
value |= WDT_MR_WDFIEN; // Enable WDT fault interrupt.
// Disable WDT interrupt (just in case, to avoid triggering it!)
NVIC_DisableIRQ(WDT_IRQn);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
__DSB();
__ISB();
// Initialize WDT with the given parameters
WDT_Enable(WDT, value);
// Configure and enable WDT interrupt.
NVIC_ClearPendingIRQ(WDT_IRQn);
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
NVIC_EnableIRQ(WDT_IRQn);
#else
// a WDT fault triggers a reset
value |= WDT_MR_WDRSTEN;
// Initialize WDT with the given parameters
WDT_Enable(WDT, value);
#endif
// Reset the watchdog
WDT_Restart(WDT);
#else
// Make sure to completely disable the Watchdog
WDT_Disable(WDT);
#endif
void _delay_ms(const int delay_ms) {
// Todo: port for Due?
delay(delay_ms);
}
// ------------------------
// Free Memory Accessor
// ------------------------
extern "C" {
extern unsigned int _ebss; // end of bss section
}
@@ -183,9 +95,18 @@ int freeMemory() {
}
// ------------------------
// Serial Ports
// ADC
// ------------------------
void HAL_adc_start_conversion(const uint8_t ch) {
HAL_adc_result = analogRead(ch);
}
uint16_t HAL_adc_get_result() {
// nop
return HAL_adc_result;
}
// Forward the default serial ports
#if USING_HW_SERIAL0
DefaultSerial1 MSerial0(false, Serial);

View File

@@ -1,9 +1,9 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* 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
*
* 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
@@ -32,15 +32,12 @@
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include <stdint.h>
#include "../../core/serial_hook.h"
// ------------------------
// Serial ports
// ------------------------
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
@@ -100,38 +97,55 @@ extern DefaultSerial4 MSerial3;
#include "MarlinSerial.h"
#include "MarlinSerialUSB.h"
// ------------------------
// Types
// ------------------------
// On AVR this is in math.h?
#define square(x) ((x)*(x))
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS // Use shared/servos.cpp
class Servo;
typedef Servo hal_servo_t;
#define SHARED_SERVOS HAS_SERVOS
#define HAL_SERVO_LIB Servo
//
// Interrupts
//
#define sei() interrupts()
#define cli() noInterrupts()
#define CRITICAL_SECTION_START() uint32_t primask = __get_PRIMASK(); __disable_irq()
#define CRITICAL_SECTION_END() if (!primask) __enable_irq()
#define ISRS_ENABLED() (!__get_PRIMASK())
#define ENABLE_ISRS() __enable_irq()
#define DISABLE_ISRS() __disable_irq()
#define CRITICAL_SECTION_START() const bool _irqon = hal.isr_state(); hal.isr_off()
#define CRITICAL_SECTION_END() if (_irqon) hal.isr_on()
void cli(); // Disable interrupts
void sei(); // Enable interrupts
void HAL_clear_reset_source(); // clear reset reason
uint8_t HAL_get_reset_source(); // get reset reason
void HAL_reboot();
//
// ADC
//
#define HAL_ADC_VREF_MV 3300
#define HAL_ADC_RESOLUTION 10
extern uint16_t HAL_adc_result; // result of last ADC conversion
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
#endif
#define HAL_ANALOG_SELECT(ch)
inline void HAL_adc_init() {}//todo
#define HAL_ADC_VREF 3.3
#define HAL_ADC_RESOLUTION 10
#define HAL_START_ADC(ch) HAL_adc_start_conversion(ch)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
void HAL_adc_start_conversion(const uint8_t ch);
uint16_t HAL_adc_get_result();
//
// Pin Mapping for M42, M43, M226
// Pin Map
//
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
@@ -140,19 +154,30 @@ typedef Servo hal_servo_t;
//
// Tone
//
void toneInit();
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
void noTone(const pin_t _pin);
// ------------------------
// Class Utilities
// ------------------------
// Enable hooks into idle and setup for HAL
#define HAL_IDLETASK 1
void HAL_idletask();
void HAL_init();
//
// Utility functions
//
void _delay_ms(const int delay);
#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
extern "C" {
@@ -161,73 +186,3 @@ char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s
#ifdef __cplusplus
}
#endif
// Return free RAM between end of heap (or end bss) and whatever is current
int freeMemory();
// ------------------------
// MarlinHAL Class
// ------------------------
class MarlinHAL {
public:
// Earliest possible init, before setup()
MarlinHAL() {}
// Watchdog
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
static void init(); // Called early in setup()
static void init_board(); // Called less early in setup()
static void reboot(); // Restart the firmware
// Interrupts
static bool isr_state() { return !__get_PRIMASK(); }
static void isr_on() { __enable_irq(); }
static void isr_off() { __disable_irq(); }
static void delay_ms(const int ms) { delay(ms); }
// Tasks, called from idle()
static void idletask();
// Reset
static uint8_t get_reset_source();
static void clear_reset_source() {}
// Free SRAM
static int freeMemory() { return ::freeMemory(); }
//
// ADC Methods
//
static uint16_t adc_result;
// Called by Temperature::init once at startup
static void adc_init() {}
// Called by Temperature::init for each sensor at startup
static void adc_enable(const uint8_t /*ch*/) {}
// Begin ADC sampling on the given channel. Called from Temperature::isr!
static void adc_start(const uint8_t ch) { adc_result = analogRead(ch); }
// Is the ADC ready for reading?
static bool adc_ready() { return true; }
// The current value of the ADC register
static uint16_t adc_value() { return adc_result; }
/**
* Set the PWM duty cycle for the pin to the given value.
* No inverting the duty cycle in this HAL.
* No changing the maximum size of the provided value to enable finer PWM duty control in this HAL.
*/
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t=255, const bool=false) {
analogWrite(pin, v);
}
};

View File

@@ -25,7 +25,7 @@
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/MinSerial.h"
#include "../shared/HAL_MinSerial.h"
#include <stdarg.h>

View File

@@ -31,6 +31,8 @@
/**
* HAL for Arduino Due and compatible (SAM3X8E)
*
* For ARDUINO_ARCH_SAM
*/
#ifdef ARDUINO_ARCH_SAM
@@ -42,7 +44,7 @@
// Public functions
// ------------------------
#if ANY(DUE_SOFTWARE_SPI, FORCE_SOFT_SPI)
#if EITHER(DUE_SOFTWARE_SPI, FORCE_SOFT_SPI)
// ------------------------
// Software SPI
@@ -238,7 +240,7 @@
}
// all the others
static uint16_t spiDelayNS = 4000; // 4000ns => 125khz
static uint32_t spiDelayCyclesX4 = 4 * (F_CPU) / 1000000; // 4µs => 125khz
static uint8_t spiTransferX(uint8_t b) { // using Mode 0
int bits = 8;
@@ -247,12 +249,12 @@
b <<= 1; // little setup time
WRITE(SD_SCK_PIN, HIGH);
DELAY_NS_VAR(spiDelayNS);
DELAY_CYCLES(spiDelayCyclesX4);
b |= (READ(SD_MISO_PIN) != 0);
WRITE(SD_SCK_PIN, LOW);
DELAY_NS_VAR(spiDelayNS);
DELAY_CYCLES(spiDelayCyclesX4);
} while (--bits);
return b;
}
@@ -435,7 +437,7 @@
} while (--todo);
}
// Pointers to generic functions for block transfers
// Pointers to generic functions for block tranfers
static pfnSpiTxBlock spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
@@ -508,7 +510,7 @@
spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
break;
default:
spiDelayNS = 4000 >> (6 - spiRate); // spiRate of 2 gives the maximum error with current CPU
spiDelayCyclesX4 = ((F_CPU) / 1000000) >> (6 - spiRate) << 2; // spiRate of 2 gives the maximum error with current CPU
spiTransferTx = (pfnSpiTransfer)spiTransferX;
spiTransferRx = (pfnSpiTransfer)spiTransferX;
spiTxBlock = (pfnSpiTxBlock)spiTxBlockX;
@@ -592,14 +594,18 @@
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS);
SPI_Enable(SPI0);
SET_OUTPUT(DAC0_SYNC_PIN);
SET_OUTPUT(DAC0_SYNC);
#if HAS_MULTI_EXTRUDER
OUT_WRITE(DAC1_SYNC_PIN, HIGH);
SET_OUTPUT(DAC1_SYNC);
WRITE(DAC1_SYNC, HIGH);
#endif
WRITE(DAC0_SYNC_PIN, HIGH);
OUT_WRITE(SPI_EEPROM1_CS_PIN, HIGH);
OUT_WRITE(SPI_EEPROM2_CS_PIN, HIGH);
OUT_WRITE(SPI_FLASH_CS_PIN, HIGH);
SET_OUTPUT(SPI_EEPROM1_CS);
SET_OUTPUT(SPI_EEPROM2_CS);
SET_OUTPUT(SPI_FLASH_CS);
WRITE(DAC0_SYNC, HIGH);
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM2_CS, HIGH);
WRITE(SPI_FLASH_CS, HIGH);
WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, LOW);

View File

@@ -41,7 +41,7 @@
practice, we need alignment to 256 bytes to make this work in all
cases */
__attribute__ ((aligned(256)))
static DeviceVectors ram_tab[61] = { nullptr };
static DeviceVectors ram_tab = { nullptr };
/**
* This function checks if the exception/interrupt table is already in SRAM or not.

View File

@@ -406,7 +406,7 @@ size_t MarlinSerial<Cfg>::write(const uint8_t c) {
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
// If global interrupts are disabled (as the result of being called from an ISR)...
if (!hal.isr_state()) {
if (!ISRS_ENABLED()) {
// Make room by polling if it is possible to transmit, and do so!
while (i == tx_buffer.tail) {
@@ -454,7 +454,7 @@ void MarlinSerial<Cfg>::flushTX() {
if (!_written) return;
// If global interrupts are disabled (as the result of being called from an ISR)...
if (!hal.isr_state()) {
if (!ISRS_ENABLED()) {
// Wait until everything was transmitted - We must do polling, as interrupts are disabled
while (tx_buffer.head != tx_buffer.tail || !(HWUART->UART_SR & UART_SR_TXEMPTY)) {
@@ -474,6 +474,7 @@ void MarlinSerial<Cfg>::flushTX() {
}
}
// If not using the USB port as serial port
#if defined(SERIAL_PORT) && SERIAL_PORT >= 0
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT> >;

View File

@@ -30,7 +30,6 @@
#include <WString.h>
#include "../../inc/MarlinConfigPre.h"
#include "../../core/types.h"
#include "../../core/serial_hook.h"
// Define constants and variables for buffering incoming serial data. We're
@@ -53,6 +52,10 @@
// #error "TX_BUFFER_SIZE must be 0, a power of 2 greater than 1, and no greater than 256."
//#endif
// Templated type selector
template<bool b, typename T, typename F> struct TypeSelector { typedef T type;} ;
template<typename T, typename F> struct TypeSelector<false, T, F> { typedef F type; };
// Templated structure wrapper
template<typename S, unsigned int addr> struct StructWrapper {
constexpr StructWrapper(int) {}
@@ -73,7 +76,7 @@ protected:
static constexpr int HWUART_IRQ_ID = IRQ_IDS[Cfg::PORT];
// Base size of type on buffer size
typedef uvalue_t(Cfg::RX_SIZE - 1) ring_buffer_pos_t;
typedef typename TypeSelector<(Cfg::RX_SIZE>256), uint16_t, uint8_t>::type ring_buffer_pos_t;
struct ring_buffer_r {
volatile ring_buffer_pos_t head, tail;
@@ -115,7 +118,7 @@ public:
static size_t write(const uint8_t c);
static void flushTX();
static bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }

View File

@@ -41,7 +41,7 @@ extern "C" {
int udi_cdc_getc();
bool udi_cdc_is_tx_ready();
int udi_cdc_putc(int value);
}
};
// Pending character
static int pending_char = -1;

View File

@@ -47,12 +47,12 @@
#include "../shared/servo.h"
#include "../shared/servo_private.h"
static Flags<_Nbr_16timers> DisablePending; // ISR should disable the timer at the next timer reset
static volatile int8_t Channel[_Nbr_16timers]; // counter for the servo being pulsed for each timer (or -1 if refresh interval)
// ------------------------
/// Interrupt handler for the TC0 channel 1.
// ------------------------
void Servo_Handler(const timer16_Sequence_t, Tc*, const uint8_t);
void Servo_Handler(timer16_Sequence_t timer, Tc *pTc, uint8_t channel);
#ifdef _useTimer1
void HANDLER_FOR_TIMER1() { Servo_Handler(_timer1, TC_FOR_TIMER1, CHANNEL_FOR_TIMER1); }
@@ -70,92 +70,88 @@ void Servo_Handler(const timer16_Sequence_t, Tc*, const uint8_t);
void HANDLER_FOR_TIMER5() { Servo_Handler(_timer5, TC_FOR_TIMER5, CHANNEL_FOR_TIMER5); }
#endif
void Servo_Handler(const timer16_Sequence_t timer, Tc *tc, const uint8_t channel) {
static int8_t Channel[_Nbr_16timers]; // Servo counters to pulse (or -1 for refresh interval)
int8_t cho = Channel[timer]; // Handle the prior Channel[timer] first
if (cho < 0) { // Channel -1 indicates the refresh interval completed...
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // ...so reset the timer
if (DisablePending[timer]) {
// Disabling only after the full servo period expires prevents
// pulses being too close together if immediately re-enabled.
DisablePending.clear(timer);
TC_Stop(tc, channel);
tc->TC_CHANNEL[channel].TC_SR; // clear interrupt
return;
}
}
else if (SERVO_INDEX(timer, cho) < ServoCount) // prior channel handled?
extDigitalWrite(SERVO(timer, cho).Pin.nbr, LOW); // pulse the prior channel LOW
void Servo_Handler(timer16_Sequence_t timer, Tc *tc, uint8_t channel) {
// clear interrupt
tc->TC_CHANNEL[channel].TC_SR;
if (Channel[timer] < 0)
tc->TC_CHANNEL[channel].TC_CCR |= TC_CCR_SWTRG; // channel set to -1 indicated that refresh interval completed so reset the timer
else if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && SERVO(timer, Channel[timer]).Pin.isActive)
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, LOW); // pulse this channel low if activated
Channel[timer] = ++cho; // go to the next channel (or 0)
if (cho < SERVOS_PER_TIMER && SERVO_INDEX(timer, cho) < ServoCount) {
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer, cho).ticks;
if (SERVO(timer, cho).Pin.isActive) // activated?
extDigitalWrite(SERVO(timer, cho).Pin.nbr, HIGH); // yes: pulse HIGH
Channel[timer]++; // increment to the next channel
if (SERVO_INDEX(timer, Channel[timer]) < ServoCount && Channel[timer] < SERVOS_PER_TIMER) {
tc->TC_CHANNEL[channel].TC_RA = tc->TC_CHANNEL[channel].TC_CV + SERVO(timer,Channel[timer]).ticks;
if (SERVO(timer,Channel[timer]).Pin.isActive) // check if activated
extDigitalWrite(SERVO(timer, Channel[timer]).Pin.nbr, HIGH); // its an active channel so pulse it high
}
else {
// finished all channels so wait for the refresh period to expire before starting over
const unsigned int cval = tc->TC_CHANNEL[channel].TC_CV + 128 / (SERVO_TIMER_PRESCALER), // allow 128 cycles to ensure the next CV not missed
ival = (unsigned int)usToTicks(REFRESH_INTERVAL); // at least REFRESH_INTERVAL has elapsed
tc->TC_CHANNEL[channel].TC_RA = max(cval, ival);
Channel[timer] = -1; // reset the timer CCR on the next call
tc->TC_CHANNEL[channel].TC_RA =
tc->TC_CHANNEL[channel].TC_CV < usToTicks(REFRESH_INTERVAL) - 4
? (unsigned int)usToTicks(REFRESH_INTERVAL) // allow a few ticks to ensure the next OCR1A not missed
: tc->TC_CHANNEL[channel].TC_CV + 4; // at least REFRESH_INTERVAL has elapsed
Channel[timer] = -1; // this will get incremented at the end of the refresh period to start again at the first channel
}
tc->TC_CHANNEL[channel].TC_SR; // clear interrupt
}
static void _initISR(Tc *tc, uint32_t channel, uint32_t id, IRQn_Type irqn) {
pmc_enable_periph_clk(id);
TC_Configure(tc, channel,
TC_CMR_WAVE // Waveform mode
| TC_CMR_WAVSEL_UP_RC // Counter running up and reset when equal to RC
| (SERVO_TIMER_PRESCALER == 2 ? TC_CMR_TCCLKS_TIMER_CLOCK1 : 0) // MCK/2
| (SERVO_TIMER_PRESCALER == 8 ? TC_CMR_TCCLKS_TIMER_CLOCK2 : 0) // MCK/8
| (SERVO_TIMER_PRESCALER == 32 ? TC_CMR_TCCLKS_TIMER_CLOCK3 : 0) // MCK/32
| (SERVO_TIMER_PRESCALER == 128 ? TC_CMR_TCCLKS_TIMER_CLOCK4 : 0) // MCK/128
);
TC_CMR_TCCLKS_TIMER_CLOCK3 | // MCK/32
TC_CMR_WAVE | // Waveform mode
TC_CMR_WAVSEL_UP_RC ); // Counter running up and reset when equals to RC
// Wait 1ms before the first ISR
TC_SetRA(tc, channel, (F_CPU) / (SERVO_TIMER_PRESCALER) / 1000UL); // 1ms
/* 84MHz, MCK/32, for 1.5ms: 3937 */
TC_SetRA(tc, channel, 2625); // 1ms
// Configure and enable interrupt
/* Configure and enable interrupt */
NVIC_EnableIRQ(irqn);
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS; // TC_IER_CPAS: RA Compare
// TC_IER_CPAS: RA Compare
tc->TC_CHANNEL[channel].TC_IER = TC_IER_CPAS;
// Enables the timer clock and performs a software reset to start the counting
TC_Start(tc, channel);
}
void initISR(const timer16_Sequence_t timer_index) {
CRITICAL_SECTION_START();
const bool disable_soon = DisablePending[timer_index];
DisablePending.clear(timer_index);
CRITICAL_SECTION_END();
if (!disable_soon) switch (timer_index) {
default: break;
void initISR(timer16_Sequence_t timer) {
#ifdef _useTimer1
case _timer1: return _initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
if (timer == _timer1)
_initISR(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1, ID_TC_FOR_TIMER1, IRQn_FOR_TIMER1);
#endif
#ifdef _useTimer2
case _timer2: return _initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
if (timer == _timer2)
_initISR(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2, ID_TC_FOR_TIMER2, IRQn_FOR_TIMER2);
#endif
#ifdef _useTimer3
case _timer3: return _initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
if (timer == _timer3)
_initISR(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3, ID_TC_FOR_TIMER3, IRQn_FOR_TIMER3);
#endif
#ifdef _useTimer4
case _timer4: return _initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
if (timer == _timer4)
_initISR(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4, ID_TC_FOR_TIMER4, IRQn_FOR_TIMER4);
#endif
#ifdef _useTimer5
case _timer5: return _initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
if (timer == _timer5)
_initISR(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5, ID_TC_FOR_TIMER5, IRQn_FOR_TIMER5);
#endif
}
}
void finISR(const timer16_Sequence_t timer_index) {
// Timer is disabled from the ISR, to ensure proper final pulse length.
DisablePending.set(timer_index);
void finISR(timer16_Sequence_t) {
#ifdef _useTimer1
TC_Stop(TC_FOR_TIMER1, CHANNEL_FOR_TIMER1);
#endif
#ifdef _useTimer2
TC_Stop(TC_FOR_TIMER2, CHANNEL_FOR_TIMER2);
#endif
#ifdef _useTimer3
TC_Stop(TC_FOR_TIMER3, CHANNEL_FOR_TIMER3);
#endif
#ifdef _useTimer4
TC_Stop(TC_FOR_TIMER4, CHANNEL_FOR_TIMER4);
#endif
#ifdef _useTimer5
TC_Stop(TC_FOR_TIMER5, CHANNEL_FOR_TIMER5);
#endif
}
#endif // HAS_SERVOS

View File

@@ -37,7 +37,7 @@
#define _useTimer5
#define TRIM_DURATION 2 // compensation ticks to trim adjust for digitalWrite delays
#define SERVO_TIMER_PRESCALER 2 // timer prescaler
#define SERVO_TIMER_PRESCALER 32 // timer prescaler
/*
TC0, chan 0 => TC0_Handler

View File

@@ -35,20 +35,20 @@
static pin_t tone_pin;
volatile static int32_t toggles;
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration/*=0*/) {
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
tone_pin = _pin;
toggles = 2 * frequency * duration / 1000;
HAL_timer_start(MF_TIMER_TONE, 2 * frequency);
HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
}
void noTone(const pin_t _pin) {
HAL_timer_disable_interrupt(MF_TIMER_TONE);
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
extDigitalWrite(_pin, LOW);
}
HAL_TONE_TIMER_ISR() {
static uint8_t pin_state = 0;
HAL_timer_isr_prologue(MF_TIMER_TONE);
HAL_timer_isr_prologue(TONE_TIMER_NUM);
if (toggles) {
toggles--;

View File

@@ -20,6 +20,7 @@
*
*/
/**
* Based on u8g_com_msp430_hw_spi.c
*
@@ -59,7 +60,7 @@
#if HAS_MARLINUI_U8GLIB
#include <U8glib-HAL.h>
#include <U8glib.h>
#include "../../../MarlinCore.h"

View File

@@ -57,12 +57,12 @@
#include "../../../inc/MarlinConfigPre.h"
#if IS_U8GLIB_ST7920
#if ENABLED(U8GLIB_ST7920)
#include "../../../inc/MarlinConfig.h"
#include "../../shared/Delay.h"
#include <U8glib-HAL.h>
#include <U8glib.h>
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
@@ -182,5 +182,5 @@ uint8_t u8g_com_HAL_DUE_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
}
#endif // LIGHTWEIGHT_UI
#endif // IS_U8GLIB_ST7920
#endif // U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM

View File

@@ -57,14 +57,14 @@
#include "../../../inc/MarlinConfigPre.h"
#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
#include "../../shared/Marduino.h"
#include "../../shared/Delay.h"
#include <U8glib-HAL.h>
#include <U8glib.h>
#if ENABLED(FYSETC_MINI_12864)
#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_3
@@ -141,5 +141,5 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
return 1;
}
#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
#endif // HAS_MARLINUI_U8GLIB && !U8GLIB_ST7920
#endif // ARDUINO_ARCH_SAM

View File

@@ -62,7 +62,7 @@
#include "../../../inc/MarlinConfig.h"
#include "../../shared/Delay.h"
#include <U8glib-HAL.h>
#include <U8glib.h>
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
@@ -81,7 +81,7 @@ Pio *SCK_pPio, *MOSI_pPio;
uint32_t SCK_dwMask, MOSI_dwMask;
void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz
for (uint8_t i = 0; i < 8; ++i) {
LOOP_L_N(i, 8) {
if (val & 0x80)
MOSI_pPio->PIO_SODR = MOSI_dwMask;
else
@@ -95,7 +95,7 @@ void u8g_spiSend_sw_DUE_mode_0(uint8_t val) { // 3MHz
}
void u8g_spiSend_sw_DUE_mode_3(uint8_t val) { // 3.5MHz
for (uint8_t i = 0; i < 8; ++i) {
LOOP_L_N(i, 8) {
SCK_pPio->PIO_CODR = SCK_dwMask;
DELAY_NS(50);
if (val & 0x80)

View File

@@ -23,7 +23,7 @@
#include "../../../inc/MarlinConfigPre.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_SetPILevel_DUE(u8g_t *u8g, uint8_t pin_index, uint8_t level);

View File

@@ -1,9 +1,10 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
* Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
*
* 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
@@ -198,9 +199,10 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
for (i = 0; i <PageSize >> 2; i++)
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
DEBUG_ECHO_MSG("EEPROM PageWrite ", page);
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM PageWrite ", page);
DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
// Get the page relative to the start of the EFC controller, and the EFC controller to use
@@ -243,7 +245,8 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_MSG("EEPROM Unlock failure for page ", page);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ", page);
return false;
}
@@ -267,7 +270,8 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_MSG("EEPROM Write failure for page ", page);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Write failure for page ", page);
return false;
}
@@ -282,7 +286,8 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
if (memcmp(getFlashStorage(page),data,PageSize)) {
#ifdef EE_EMU_DEBUG
DEBUG_ECHO_MSG("EEPROM Verify Write failure for page ", page);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Verify Write failure for page ", page);
ee_Dump( page, (uint32_t *)addrflash);
ee_Dump(-page, data);
@@ -301,7 +306,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
}
}
}
DEBUG_ECHOLNPGM("--> Differing bits: ", count);
DEBUG_ECHOLNPAIR("--> Differing bits: ", count);
#endif
return false;
@@ -320,9 +325,10 @@ static bool ee_PageErase(uint16_t page) {
uint16_t i;
uint32_t addrflash = uint32_t(getFlashStorage(page));
DEBUG_ECHO_MSG("EEPROM PageErase ", page);
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM PageErase ", page);
DEBUG_ECHOLNPAIR(" in FLASH address ", (uint32_t)addrflash);
DEBUG_ECHOLNPAIR(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
// Get the page relative to the start of the EFC controller, and the EFC controller to use
@@ -364,7 +370,8 @@ static bool ee_PageErase(uint16_t page) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_MSG("EEPROM Unlock failure for page ",page);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Unlock failure for page ",page);
return false;
}
@@ -387,7 +394,8 @@ static bool ee_PageErase(uint16_t page) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_MSG("EEPROM Erase failure for page ",page);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Erase failure for page ",page);
return false;
}
@@ -402,7 +410,8 @@ static bool ee_PageErase(uint16_t page) {
uint32_t * aligned_src = (uint32_t *) addrflash;
for (i = 0; i < PageSize >> 2; i++) {
if (*aligned_src++ != 0xFFFFFFFF) {
DEBUG_ECHO_MSG("EEPROM Verify Erase failure for page ",page);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Verify Erase failure for page ",page);
ee_Dump(page, (uint32_t *)addrflash);
return false;
}
@@ -912,7 +921,8 @@ static void ee_Init() {
// If all groups seem to be used, default to first group
if (curGroup >= GroupCount) curGroup = 0;
DEBUG_ECHO_MSG("EEPROM Current Group: ",curGroup);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Current Group: ",curGroup);
DEBUG_FLUSH();
// Now, validate that all the other group pages are empty
@@ -921,7 +931,8 @@ static void ee_Init() {
for (int page = 0; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on group ", grp);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on group ", grp);
DEBUG_FLUSH();
ee_PageErase(grp * PagesPerGroup + page);
}
@@ -937,13 +948,15 @@ static void ee_Init() {
}
}
DEBUG_ECHO_MSG("EEPROM Active page: ", curPage);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Active page: ", curPage);
DEBUG_FLUSH();
// Make sure the pages following the first clean one are also clean
for (int page = curPage + 1; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on active group ", curGroup);
DEBUG_ECHO_START();
DEBUG_ECHOLNPAIR("EEPROM Page ", page, " not clean on active group ", curGroup);
DEBUG_FLUSH();
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
ee_PageErase(curGroup * PagesPerGroup + page);

View File

@@ -1,9 +1,10 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
* Copyright (c) 2016 Victor Perez victor_pv@hotmail.com
*
* 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

View File

@@ -47,33 +47,21 @@ void endstop_ISR() { endstops.update(); }
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
TERN_(USE_X_MAX, _ATTACH(X_MAX_PIN));
TERN_(USE_X_MIN, _ATTACH(X_MIN_PIN));
TERN_(USE_Y_MAX, _ATTACH(Y_MAX_PIN));
TERN_(USE_Y_MIN, _ATTACH(Y_MIN_PIN));
TERN_(USE_Z_MAX, _ATTACH(Z_MAX_PIN));
TERN_(USE_Z_MIN, _ATTACH(Z_MIN_PIN));
TERN_(USE_X2_MAX, _ATTACH(X2_MAX_PIN));
TERN_(USE_X2_MIN, _ATTACH(X2_MIN_PIN));
TERN_(USE_Y2_MAX, _ATTACH(Y2_MAX_PIN));
TERN_(USE_Y2_MIN, _ATTACH(Y2_MIN_PIN));
TERN_(USE_Z2_MAX, _ATTACH(Z2_MAX_PIN));
TERN_(USE_Z2_MIN, _ATTACH(Z2_MIN_PIN));
TERN_(USE_Z3_MAX, _ATTACH(Z3_MAX_PIN));
TERN_(USE_Z3_MIN, _ATTACH(Z3_MIN_PIN));
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_X_MAX, _ATTACH(X_MAX_PIN));
TERN_(HAS_X_MIN, _ATTACH(X_MIN_PIN));
TERN_(HAS_Y_MAX, _ATTACH(Y_MAX_PIN));
TERN_(HAS_Y_MIN, _ATTACH(Y_MIN_PIN));
TERN_(HAS_Z_MAX, _ATTACH(Z_MAX_PIN));
TERN_(HAS_Z_MIN, _ATTACH(Z_MIN_PIN));
TERN_(HAS_X2_MAX, _ATTACH(X2_MAX_PIN));
TERN_(HAS_X2_MIN, _ATTACH(X2_MIN_PIN));
TERN_(HAS_Y2_MAX, _ATTACH(Y2_MAX_PIN));
TERN_(HAS_Y2_MIN, _ATTACH(Y2_MIN_PIN));
TERN_(HAS_Z2_MAX, _ATTACH(Z2_MAX_PIN));
TERN_(HAS_Z2_MIN, _ATTACH(Z2_MIN_PIN));
TERN_(HAS_Z3_MAX, _ATTACH(Z3_MAX_PIN));
TERN_(HAS_Z3_MIN, _ATTACH(Z3_MIN_PIN));
TERN_(HAS_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(HAS_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(HAS_Z_MIN_PROBE_PIN, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));
TERN_(USE_J_MIN, _ATTACH(J_MIN_PIN));
TERN_(USE_K_MAX, _ATTACH(K_MAX_PIN));
TERN_(USE_K_MIN, _ATTACH(K_MIN_PIN));
TERN_(USE_U_MAX, _ATTACH(U_MAX_PIN));
TERN_(USE_U_MIN, _ATTACH(U_MIN_PIN));
TERN_(USE_V_MAX, _ATTACH(V_MAX_PIN));
TERN_(USE_V_MIN, _ATTACH(V_MIN_PIN));
TERN_(USE_W_MAX, _ATTACH(W_MAX_PIN));
TERN_(USE_W_MIN, _ATTACH(W_MIN_PIN));
}

View File

@@ -189,12 +189,12 @@
*/
// UART
#define RXD 0
#define TXD 1
#define RXD DIO0
#define TXD DIO1
// TWI (I2C)
#define SCL 21
#define SDA 20
#define SCL DIO21
#define SDA DIO20
/**
* pins

View File

@@ -25,7 +25,7 @@
* is NOT used to directly toggle pins. The ISR writes to the pin assigned to
* that interrupt.
*
* All PWMs use the same repetition rate. The G2 needs about 10kHz min in order to
* All PWMs use the same repetition rate. The G2 needs about 10KHz min in order to
* not have obvious ripple on the Vref signals.
*
* The data structures are setup to minimize the computation done by the ISR which

View File

@@ -49,6 +49,7 @@ extern volatile uint32_t *SODR_A, *SODR_B, *CODR_A, *CODR_B;
#define PWM_MAP_INIT_ROW(IO,ZZ) { ZZ == 'A' ? SODR_A : SODR_B, ZZ == 'A' ? CODR_A : CODR_B, 1 << _PIN(IO) }
#define PWM_MAP_INIT { PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_X_PIN, 'B'), \
PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_Y_PIN, 'B'), \
PWM_MAP_INIT_ROW(MOTOR_CURRENT_PWM_Z_PIN, 'B'), \
@@ -62,7 +63,7 @@ extern PWM_map ISR_table[NUM_PWMS];
extern uint32_t motor_current_setting[3];
#define IR_BIT(p) (WITHIN(p, 0, 3) ? (p) : (p) + 4)
#define COPY_ACTIVE_TABLE() do{ for (uint8_t i = 0; i < 6; ++i) work_table[i] = active_table[i]; }while(0)
#define COPY_ACTIVE_TABLE() do{ LOOP_L_N(i, 6) work_table[i] = active_table[i]; }while(0)
#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

View File

@@ -168,6 +168,7 @@ const G2_PinDescription G2_g_APinDescription[] = {
{ PIOB, PIO_PB21, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 52
{ PIOB, PIO_PB14, ID_PIOB, PIO_OUTPUT_0, PIO_DEFAULT, PIN_ATTR_DIGITAL, NO_ADC, NO_ADC, NOT_ON_PWM, NOT_ON_TIMER }, // PIN 53
// 54 .. 65 - Analog pins
// ----------------------
{ PIOA, PIO_PA16X1_AD7, ID_PIOA, PIO_INPUT, PIO_DEFAULT, PIN_ATTR_ANALOG, ADC0, ADC7, NOT_ON_PWM, NOT_ON_TIMER }, // AD0

View File

@@ -20,3 +20,7 @@
*
*/
#pragma once
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/DUE."
#endif

View File

@@ -23,6 +23,6 @@
#if USE_FALLBACK_EEPROM
#define FLASH_EEPROM_EMULATION
#elif ANY(I2C_EEPROM, SPI_EEPROM)
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
#define USE_SHARED_EEPROM 1
#endif

View File

@@ -25,34 +25,6 @@
* Test Arduino Due specific configuration values for errors at compile-time.
*/
#if HAS_SPI_TFT || HAS_FSMC_TFT
#error "Sorry! TFT displays are not available for HAL/DUE."
#endif
/**
* Check for common serial pin conflicts
*/
#define CHECK_SERIAL_PIN(N) ( \
X_STOP_PIN == N || Y_STOP_PIN == N || Z_STOP_PIN == N \
|| X_MIN_PIN == N || Y_MIN_PIN == N || Z_MIN_PIN == N \
|| X_MAX_PIN == N || Y_MAX_PIN == N || Z_MAX_PIN == N \
|| X_STEP_PIN == N || Y_STEP_PIN == N || Z_STEP_PIN == N \
|| X_DIR_PIN == N || Y_DIR_PIN == N || Z_DIR_PIN == N \
|| X_ENA_PIN == N || Y_ENA_PIN == N || Z_ENA_PIN == N \
)
#if SERIAL_IN_USE(0) // D0-D1. No known conflicts.
#endif
#if SERIAL_IN_USE(1) && (CHECK_SERIAL_PIN(18) || CHECK_SERIAL_PIN(19))
#error "Serial Port 1 pin D18 and/or D19 conflicts with another pin on the board."
#endif
#if SERIAL_IN_USE(2) && (CHECK_SERIAL_PIN(16) || CHECK_SERIAL_PIN(17))
#error "Serial Port 2 pin D16 and/or D17 conflicts with another pin on the board."
#endif
#if SERIAL_IN_USE(3) && (CHECK_SERIAL_PIN(14) || CHECK_SERIAL_PIN(15))
#error "Serial Port 3 pin D14 and/or D15 conflicts with another pin on the board."
#endif
#undef CHECK_SERIAL_PIN
/**
* HARDWARE VS. SOFTWARE SPI COMPATIBILITY
*
@@ -68,25 +40,22 @@
* Usually the hardware SPI pins are only available to the LCD. This makes the DUE hard SPI used at the same time
* as the TMC2130 soft SPI the most common setup.
*/
#if HAS_MEDIA && HAS_DRIVER(TMC2130)
#define _IS_HW_SPI(P) (defined(TMC_SPI_##P) && (TMC_SPI_##P == SD_MOSI_PIN || TMC_SPI_##P == SD_MISO_PIN || TMC_SPI_##P == SD_SCK_PIN))
#if DISABLED(DUE_SOFTWARE_SPI) && ENABLED(TMC_USE_SW_SPI) && (_IS_HW_SPI(MOSI) || _IS_HW_SPI(MISO) || _IS_HW_SPI(SCK))
#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == SD_MOSI_PIN || TMC_SW_##P == SD_MISO_PIN || TMC_SW_##P == SD_SCK_PIN))
#if ENABLED(SDSUPPORT) && HAS_DRIVER(TMC2130)
#if ENABLED(TMC_USE_SW_SPI)
#if DISABLED(DUE_SOFTWARE_SPI) && (_IS_HW_SPI(MOSI) || _IS_HW_SPI(MISO) || _IS_HW_SPI(SCK))
#error "DUE hardware SPI is required but is incompatible with TMC2130 software SPI. Either disable TMC_USE_SW_SPI or use separate pins for the two SPIs."
#endif
#if ENABLED(DUE_SOFTWARE_SPI) && DISABLED(TMC_USE_SW_SPI)
#elif ENABLED(DUE_SOFTWARE_SPI)
#error "DUE software SPI is required but is incompatible with TMC2130 hardware SPI. Enable TMC_USE_SW_SPI to fix."
#endif
#undef _IS_HW_SPI
#endif
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported for HAL/DUE."
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on DUE."
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on the DUE platform."
#endif
#if USING_PULLDOWNS
#error "PULLDOWN pin mode is not available on DUE boards."
#endif

View File

@@ -2,9 +2,6 @@
* 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
@@ -53,7 +50,7 @@
* The net result is that both the g_pinStatus[pin] array and the PIO_OSR register
* needs to be looked at when determining if a pin is an input or an output.
*
* b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1kHz
* b) Due has only pins 6, 7, 8 & 9 enabled for PWMs. FYI - they run at 1KHz
*
* c) NUM_DIGITAL_PINS does not include the analog pins
*
@@ -64,12 +61,12 @@
#define NUMBER_PINS_TOTAL PINS_COUNT
#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin
#define PRINT_PORT(p)
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL ? 1 : 0)
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \
@@ -85,15 +82,14 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
|| pwm_status(pin));
}
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
uint32_t chan = g_APinDescription[pin].ulPWMChannel;
SERIAL_ECHOPGM("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
SERIAL_ECHOPAIR("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
}
}
void print_port(const pin_t) {}
/**
* DUE Board pin | PORT | Label
* ----------------+--------+-------

View File

@@ -24,7 +24,7 @@
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
*
* Available chip select pins for HW SPI are 4 10 52 77 87
* Available chip select pins for HW SPI are 4 10 52 77
*/
#if SDSS == 4 || SDSS == 10 || SDSS == 52 || SDSS == 77 || SDSS == 87
#if SDSS == 4

View File

@@ -1,9 +1,9 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* 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
*
* 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
@@ -42,7 +42,7 @@
// Private Variables
// ------------------------
const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TC0, 0, TC0_IRQn, 3}, // 0 - [servo timer5]
{ TC0, 1, TC1_IRQn, 0}, // 1
{ TC0, 2, TC2_IRQn, 2}, // 2 - stepper
@@ -66,9 +66,9 @@ const tTimerConfig timer_config[NUM_HARDWARE_TIMERS] = {
*/
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
Tc *tc = timer_config[timer_num].pTimerRegs;
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
uint32_t channel = timer_config[timer_num].channel;
Tc *tc = TimerConfig[timer_num].pTimerRegs;
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
uint32_t channel = TimerConfig[timer_num].channel;
// Disable interrupt, just in case it was already enabled
NVIC_DisableIRQ(irq);
@@ -86,20 +86,13 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
pmc_set_writeprotect(false);
pmc_enable_periph_clk((uint32_t)irq);
NVIC_SetPriority(irq, timer_config[timer_num].priority);
NVIC_SetPriority(irq, TimerConfig [timer_num].priority);
// wave mode, reset counter on match with RC,
TC_Configure(tc, channel,
TC_CMR_WAVE
| TC_CMR_WAVSEL_UP_RC
| (HAL_TIMER_PRESCALER == 2 ? TC_CMR_TCCLKS_TIMER_CLOCK1 : 0)
| (HAL_TIMER_PRESCALER == 8 ? TC_CMR_TCCLKS_TIMER_CLOCK2 : 0)
| (HAL_TIMER_PRESCALER == 32 ? TC_CMR_TCCLKS_TIMER_CLOCK3 : 0)
| (HAL_TIMER_PRESCALER == 128 ? TC_CMR_TCCLKS_TIMER_CLOCK4 : 0)
);
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK1);
// Set compare value
TC_SetRC(tc, channel, VARIANT_MCK / (HAL_TIMER_PRESCALER) / frequency);
TC_SetRC(tc, channel, VARIANT_MCK / 2 / frequency);
// And start timer
TC_Start(tc, channel);
@@ -112,12 +105,12 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
NVIC_EnableIRQ(irq);
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
NVIC_DisableIRQ(irq);
// We NEED memory barriers to ensure Interrupts are actually disabled!
@@ -132,7 +125,7 @@ static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
IRQn_Type irq = timer_config[timer_num].IRQ_Id;
IRQn_Type irq = TimerConfig[timer_num].IRQ_Id;
return NVIC_GetEnabledIRQ(irq);
}

View File

@@ -1,9 +1,8 @@
/**
* 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
* 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
@@ -36,20 +35,19 @@
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_PRESCALER 2
#define HAL_TIMER_RATE ((F_CPU) / (HAL_TIMER_PRESCALER)) // frequency of timers peripherals
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
#ifndef MF_TIMER_STEP
#define MF_TIMER_STEP 2 // Timer Index for Stepper
#ifndef STEP_TIMER_NUM
#define STEP_TIMER_NUM 2 // Timer Index for Stepper
#endif
#ifndef MF_TIMER_PULSE
#define MF_TIMER_PULSE MF_TIMER_STEP
#ifndef PULSE_TIMER_NUM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#endif
#ifndef MF_TIMER_TEMP
#define MF_TIMER_TEMP 4 // Timer Index for Temperature
#ifndef TEMP_TIMER_NUM
#define TEMP_TIMER_NUM 4 // Timer Index for Temperature
#endif
#ifndef MF_TIMER_TONE
#define MF_TIMER_TONE 6 // index of timer to use for beeper tones
#ifndef TONE_TIMER_NUM
#define TONE_TIMER_NUM 6 // index of timer to use for beeper tones
#endif
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
@@ -62,12 +60,12 @@ typedef uint32_t hal_timer_t;
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(STEP_TIMER_NUM)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(STEP_TIMER_NUM)
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(STEP_TIMER_NUM)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
#ifndef HAL_STEP_TIMER_ISR
#define HAL_STEP_TIMER_ISR() void TC2_Handler()
@@ -94,7 +92,7 @@ typedef struct {
// Public Variables
// ------------------------
extern const tTimerConfig timer_config[];
extern const tTimerConfig TimerConfig[];
// ------------------------
// Public functions
@@ -103,17 +101,17 @@ extern const tTimerConfig timer_config[];
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
const tTimerConfig * const pConfig = &timer_config[timer_num];
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC = compare;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &timer_config[timer_num];
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_RC;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &timer_config[timer_num];
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
return pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_CV;
}
@@ -122,9 +120,9 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
const tTimerConfig * const pConfig = &timer_config[timer_num];
const tTimerConfig * const pConfig = &TimerConfig[timer_num];
// Reading the status register clears the interrupt flag
pConfig->pTimerRegs->TC_CHANNEL[pConfig->channel].TC_SR;
}
#define HAL_timer_isr_epilogue(T) NOOP
#define HAL_timer_isr_epilogue(TIMER_NUM)

View File

@@ -4,8 +4,7 @@
# Windows: bossac.exe
# Other: leave unchanged
#
import pioutil
if pioutil.is_pio_build():
import platform
current_OS = platform.system()

View File

@@ -71,7 +71,7 @@
/* ------------------------------------------------------------------------ */
/**
* \page arduino_due_x_board_info "Arduino Due/X - Board information"
* \page arduino_due_x_board_info "Arduino Due/X - Board informations"
* This page lists several definition related to the board description.
*
*/

View File

@@ -142,6 +142,7 @@
*/
#define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack())
/**
* \brief Set aligned boundary.
*/
@@ -282,6 +283,7 @@ typedef double F64; //!< 64-bit floating-point number.
typedef uint32_t iram_size_t;
//! @}
/*! \name Status Types
*/
//! @{
@@ -289,6 +291,7 @@ typedef bool Status_bool_t; //!< Boolean status.
typedef U8 Status_t; //!< 8-bit-coded status.
//! @}
/*! \name Aliasing Aggregate Types
*/
//! @{
@@ -459,6 +462,7 @@ typedef struct
#endif
//! @}
#ifndef __ASSEMBLY__ // not for assembling.
//! \name Optimization Control
@@ -577,6 +581,7 @@ typedef struct
//! @}
/*! \name Zero-Bit Counting
*
* Under GCC, __builtin_clz and __builtin_ctz behave like macros when
@@ -687,6 +692,7 @@ typedef struct
//! @}
/*! \name Bit Reversing
*/
//! @{
@@ -726,6 +732,7 @@ typedef struct
//! @}
/*! \name Alignment
*/
//! @{
@@ -791,6 +798,7 @@ typedef struct
*/
#define Long_call(addr) ((*(void (*)(void))(addr))())
/*! \name MCU Endianism Handling
* ARM is MCU little endianism.
*/
@@ -860,6 +868,7 @@ typedef struct
#define CPU_TO_BE32(x) swap32(x)
//! @}
/*! \name Endianism Conversion
*
* The same considerations as for clz and ctz apply here but GCC's
@@ -946,6 +955,7 @@ typedef struct
//! @}
/*! \name Target Abstraction
*/
//! @{
@@ -987,6 +997,7 @@ typedef U8 Byte; //!< 8-bit unsigned integer.
#endif // #ifndef __ASSEMBLY__
#ifdef __ICCARM__
#define SHORTENUM __packed
#elif defined(__GNUC__)
@@ -1048,7 +1059,7 @@ static inline void convert_64_bit_to_byte_array(uint64_t value, uint8_t *data)
while (val_index < 8)
{
data[val_index++] = value & 0xFF;
value >>= 8;
value = value >> 8;
}
}

View File

@@ -81,6 +81,7 @@
#define LUN_0_NAME "\"SD/MMC Card\""
//! @}
/*! \name Actions Associated with Memory Accesses
*
* Write here the action to associate with each memory access.
@@ -111,4 +112,5 @@
#define GLOBAL_WR_PROTECT false //!< Management of a global write protection.
//! @}
#endif // _CONF_ACCESS_H_

View File

@@ -96,4 +96,5 @@
// - UPLL frequency: 480MHz
// - USB clock: 480 / 1 = 480MHz
#endif /* CONF_CLOCK_H_INCLUDED */

View File

@@ -88,6 +88,7 @@
#endif
//@}
/**
* USB Device Callbacks definitions (Optional)
* @{
@@ -100,7 +101,7 @@
#define USB_DEVICE_SPECIFIC_REQUEST() usb_task_other_requests()
//@}
#if HAS_MEDIA
#if ENABLED(SDSUPPORT)
/**
* USB Device low level configuration
* When only one interface is used, these configurations are defined by the class module.
@@ -149,6 +150,7 @@
//@}
/**
* USB Interface Configuration
* @{
@@ -183,7 +185,7 @@
//! Enable id string of interface to add an extra USB string
#define UDI_CDC_IAD_STRING_ID 4
#if HAS_MEDIA
#if ENABLED(SDSUPPORT)
/**
* USB CDC low level configuration
* In standalone these configurations are defined by the CDC module.
@@ -208,6 +210,7 @@
//@}
//@}
/**
* Configuration of MSC interface
* @{
@@ -242,6 +245,7 @@
//@}
/**
* Description of Composite Device
* @{

View File

@@ -68,6 +68,7 @@
#endif
#include "ctrl_access.h"
//_____ D E F I N I T I O N S ______________________________________________
#ifdef FREERTOS_USED
@@ -111,6 +112,7 @@ static xSemaphoreHandle ctrl_access_semphr = NULL;
#endif // FREERTOS_USED
#if MAX_LUN
/*! \brief Initializes an entry of the LUN descriptor table.
@@ -240,14 +242,17 @@ static const struct
#endif
#if GLOBAL_WR_PROTECT == true
bool g_wr_protect;
#endif
/*! \name Control Interface
*/
//! @{
#ifdef FREERTOS_USED
bool ctrl_access_init(void)
@@ -265,6 +270,7 @@ bool ctrl_access_init(void)
return true;
}
/*! \brief Locks accesses to LUNs.
*
* \return \c true if the access was successfully locked, else \c false.
@@ -282,6 +288,7 @@ static bool ctrl_access_lock(void)
#endif // FREERTOS_USED
U8 get_nb_lun(void)
{
#if MEM_USB == ENABLE
@@ -302,11 +309,13 @@ U8 get_nb_lun(void)
#endif
}
U8 get_cur_lun(void)
{
return LUN_ID_0;
}
Ctrl_status mem_test_unit_ready(U8 lun)
{
Ctrl_status status;
@@ -328,6 +337,7 @@ Ctrl_status mem_test_unit_ready(U8 lun)
return status;
}
Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector)
{
Ctrl_status status;
@@ -349,6 +359,7 @@ Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector)
return status;
}
U8 mem_sector_size(U8 lun)
{
U8 sector_size;
@@ -370,6 +381,7 @@ U8 mem_sector_size(U8 lun)
return sector_size;
}
bool mem_unload(U8 lun, bool unload)
{
bool unloaded;
@@ -421,6 +433,7 @@ bool mem_wr_protect(U8 lun)
return wr_protect;
}
bool mem_removal(U8 lun)
{
bool removal;
@@ -445,6 +458,7 @@ bool mem_removal(U8 lun)
return removal;
}
const char *mem_name(U8 lun)
{
#if MAX_LUN==0
@@ -461,14 +475,17 @@ const char *mem_name(U8 lun)
#endif
}
//! @}
#if ACCESS_USB == true
/*! \name MEM <-> USB Interface
*/
//! @{
Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector)
{
Ctrl_status status;
@@ -488,6 +505,7 @@ Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector)
return status;
}
Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector)
{
Ctrl_status status;
@@ -507,16 +525,19 @@ Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector)
return status;
}
//! @}
#endif // ACCESS_USB == true
#if ACCESS_MEM_TO_RAM == true
/*! \name MEM <-> RAM Interface
*/
//! @{
Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram)
{
Ctrl_status status;
@@ -543,6 +564,7 @@ Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram)
return status;
}
Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram)
{
Ctrl_status status;
@@ -569,16 +591,19 @@ Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram)
return status;
}
//! @}
#endif // ACCESS_MEM_TO_RAM == true
#if ACCESS_STREAM == true
/*! \name Streaming MEM <-> MEM Interface
*/
//! @{
#if ACCESS_MEM_TO_MEM == true
#include "fat.h"
@@ -600,18 +625,21 @@ Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_ad
#endif // ACCESS_MEM_TO_MEM == true
Ctrl_status stream_state(U8 id)
{
UNUSED(id);
return CTRL_GOOD;
}
U16 stream_stop(U8 id)
{
UNUSED(id);
return 0;
}
//! @}
#endif // ACCESS_STREAM

View File

@@ -56,6 +56,7 @@
* Support and FAQ: visit <a href="https://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _CTRL_ACCESS_H_
#define _CTRL_ACCESS_H_
@@ -88,6 +89,7 @@ typedef enum
CTRL_BUSY = FAIL + 2 //!< Memory not initialized or changed.
} Ctrl_status;
// FYI: Each Logical Unit Number (LUN) corresponds to a memory.
// Check LUN defines.
@@ -134,6 +136,7 @@ typedef enum
#define LUN_ID_USB (MAX_LUN) //!< First dynamic LUN (USB host mass storage).
//! @}
// Include LUN header files.
#if LUN_0 == ENABLE
#include LUN_0_INCLUDE
@@ -163,11 +166,13 @@ typedef enum
#include LUN_USB_INCLUDE
#endif
// Check the configuration of write protection in conf_access.h.
#ifndef GLOBAL_WR_PROTECT
#error GLOBAL_WR_PROTECT must be defined as true or false in conf_access.h
#endif
#if GLOBAL_WR_PROTECT == true
//! Write protect.
@@ -175,6 +180,7 @@ extern bool g_wr_protect;
#endif
/*! \name Control Interface
*/
//! @{
@@ -273,6 +279,7 @@ extern const char *mem_name(U8 lun);
//! @}
#if ACCESS_USB == true
/*! \name MEM <-> USB Interface
@@ -303,6 +310,7 @@ extern Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector);
#endif // ACCESS_USB == true
#if ACCESS_MEM_TO_RAM == true
/*! \name MEM <-> RAM Interface
@@ -333,6 +341,7 @@ extern Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram);
#endif // ACCESS_MEM_TO_RAM == true
#if ACCESS_STREAM == true
/*! \name Streaming MEM <-> MEM Interface

View File

@@ -108,23 +108,31 @@ struct genclk_config {
uint32_t ctrl;
};
static inline void genclk_config_defaults(struct genclk_config *p_cfg, uint32_t ul_id) {
static inline void genclk_config_defaults(struct genclk_config *p_cfg,
uint32_t ul_id)
{
ul_id = ul_id;
p_cfg->ctrl = 0;
}
static inline void genclk_config_read(struct genclk_config *p_cfg, uint32_t ul_id) {
static inline void genclk_config_read(struct genclk_config *p_cfg,
uint32_t ul_id)
{
p_cfg->ctrl = PMC->PMC_PCK[ul_id];
}
static inline void genclk_config_write(const struct genclk_config *p_cfg, uint32_t ul_id) {
static inline void genclk_config_write(const struct genclk_config *p_cfg,
uint32_t ul_id)
{
PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
}
//! \name Programmable Clock Source and Prescaler configuration
//@{
static inline void genclk_config_set_source(struct genclk_config *p_cfg, enum genclk_source e_src) {
static inline void genclk_config_set_source(struct genclk_config *p_cfg,
enum genclk_source e_src)
{
p_cfg->ctrl &= (~PMC_PCK_CSS_Msk);
switch (e_src) {
@@ -156,23 +164,29 @@ static inline void genclk_config_set_source(struct genclk_config *p_cfg, enum ge
}
}
static inline void genclk_config_set_divider(struct genclk_config *p_cfg, uint32_t e_divider) {
static inline void genclk_config_set_divider(struct genclk_config *p_cfg,
uint32_t e_divider)
{
p_cfg->ctrl &= ~PMC_PCK_PRES_Msk;
p_cfg->ctrl |= e_divider;
}
//@}
static inline void genclk_enable(const struct genclk_config *p_cfg, uint32_t ul_id) {
static inline void genclk_enable(const struct genclk_config *p_cfg,
uint32_t ul_id)
{
PMC->PMC_PCK[ul_id] = p_cfg->ctrl;
pmc_enable_pck(ul_id);
}
static inline void genclk_disable(uint32_t ul_id) {
static inline void genclk_disable(uint32_t ul_id)
{
pmc_disable_pck(ul_id);
}
static inline void genclk_enable_source(enum genclk_source e_src) {
static inline void genclk_enable_source(enum genclk_source e_src)
{
switch (e_src) {
case GENCLK_PCK_SRC_SLCK_RC:
if (!osc_is_ready(OSC_SLCK_32K_RC)) {

View File

@@ -57,6 +57,7 @@
#include "preprocessor.h"
//! Maximal number of repetitions supported by MREPEAT.
#define MREPEAT_LIMIT 256

View File

@@ -115,7 +115,8 @@ extern "C" {
#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator.
//@}
static inline void osc_enable(uint32_t ul_id) {
static inline void osc_enable(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
break;
@@ -128,6 +129,7 @@ static inline void osc_enable(uint32_t ul_id) {
pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS);
break;
case OSC_MAINCK_4M_RC:
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz);
break;
@@ -140,6 +142,7 @@ static inline void osc_enable(uint32_t ul_id) {
pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz);
break;
case OSC_MAINCK_XTAL:
pmc_switch_mainck_to_xtal(PMC_OSC_XTAL/*,
pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US,
@@ -154,7 +157,8 @@ static inline void osc_enable(uint32_t ul_id) {
}
}
static inline void osc_disable(uint32_t ul_id) {
static inline void osc_disable(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
case OSC_SLCK_32K_XTAL:
@@ -177,7 +181,8 @@ static inline void osc_disable(uint32_t ul_id) {
}
}
static inline bool osc_is_ready(uint32_t ul_id) {
static inline bool osc_is_ready(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
return 1;
@@ -197,7 +202,8 @@ static inline bool osc_is_ready(uint32_t ul_id) {
return 0;
}
static inline uint32_t osc_get_rate(uint32_t ul_id) {
static inline uint32_t osc_get_rate(uint32_t ul_id)
{
switch (ul_id) {
case OSC_SLCK_32K_RC:
return OSC_SLCK_32K_RC_HZ;
@@ -235,7 +241,8 @@ static inline uint32_t osc_get_rate(uint32_t ul_id) {
*
* \param id A number identifying the oscillator to wait for.
*/
static inline void osc_wait_ready(uint8_t id) {
static inline void osc_wait_ready(uint8_t id)
{
while (!osc_is_ready(id)) {
/* Do nothing */
}

View File

@@ -113,15 +113,15 @@ struct pll_config {
* is hidden in this implementation. Use mul as mul effective value.
*/
static inline void pll_config_init(struct pll_config *p_cfg,
enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul) {
enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul)
{
uint32_t vco_hz;
Assert(e_src < PLL_NR_SOURCES);
if (ul_div == 0 && ul_mul == 0) { /* Must only be true for UTMI PLL */
p_cfg->ctrl = CKGR_UCKR_UPLLCOUNT(PLL_COUNT);
}
else { /* PLLA */
} else { /* PLLA */
/* Calculate internal VCO frequency */
vco_hz = osc_get_rate(e_src) / ul_div;
Assert(vco_hz >= PLL_INPUT_MIN_HZ);
@@ -142,55 +142,68 @@ static inline void pll_config_init(struct pll_config *p_cfg,
CONFIG_PLL##pll_id##_DIV, \
CONFIG_PLL##pll_id##_MUL)
static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id) {
static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
p_cfg->ctrl = ul_pll_id == PLLA_ID ? PMC->CKGR_PLLAR : PMC->CKGR_UCKR;
if (ul_pll_id == PLLA_ID) {
p_cfg->ctrl = PMC->CKGR_PLLAR;
} else {
p_cfg->ctrl = PMC->CKGR_UCKR;
}
}
static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id) {
static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
pmc_disable_pllack(); // Always stop PLL first!
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl;
}
else
} else {
PMC->CKGR_UCKR = p_cfg->ctrl;
}
}
static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id) {
static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
pmc_disable_pllack(); // Always stop PLL first!
PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl;
}
else
} else {
PMC->CKGR_UCKR = p_cfg->ctrl | CKGR_UCKR_UPLLEN;
}
}
/**
* \note This will only disable the selected PLL, not the underlying oscillator (mainck).
*/
static inline void pll_disable(uint32_t ul_pll_id) {
static inline void pll_disable(uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID)
if (ul_pll_id == PLLA_ID) {
pmc_disable_pllack();
else
} else {
PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN;
}
static inline uint32_t pll_is_locked(uint32_t ul_pll_id) {
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID)
return pmc_is_locked_pllack();
else
return pmc_is_locked_upll();
}
static inline void pll_enable_source(enum pll_source e_src) {
static inline uint32_t pll_is_locked(uint32_t ul_pll_id)
{
Assert(ul_pll_id < NR_PLLS);
if (ul_pll_id == PLLA_ID) {
return pmc_is_locked_pllack();
} else {
return pmc_is_locked_upll();
}
}
static inline void pll_enable_source(enum pll_source e_src)
{
switch (e_src) {
case PLL_SRC_MAINCK_4M_RC:
case PLL_SRC_MAINCK_8M_RC:
@@ -207,11 +220,13 @@ static inline void pll_enable_source(enum pll_source e_src) {
}
}
static inline void pll_enable_config_defaults(unsigned int ul_pll_id) {
static inline void pll_enable_config_defaults(unsigned int ul_pll_id)
{
struct pll_config pllcfg;
if (pll_is_locked(ul_pll_id)) return; // Pll already running
if (pll_is_locked(ul_pll_id)) {
return; // Pll already running
}
switch (ul_pll_id) {
#ifdef CONFIG_PLL0_SOURCE
case 0:
@@ -249,10 +264,13 @@ static inline void pll_enable_config_defaults(unsigned int ul_pll_id) {
* \retval STATUS_OK The PLL is now locked.
* \retval ERR_TIMEOUT Timed out waiting for PLL to become locked.
*/
static inline int pll_wait_for_lock(unsigned int pll_id) {
static inline int pll_wait_for_lock(unsigned int pll_id)
{
Assert(pll_id < NR_PLLS);
while (!pll_is_locked(pll_id)) { /* Do nothing */ }
while (!pll_is_locked(pll_id)) {
/* Do nothing */
}
return 0;
}

View File

@@ -51,4 +51,5 @@
#include "stringz.h"
#include "mrepeat.h"
#endif // _PREPROCESSOR_H_

View File

@@ -57,6 +57,7 @@
#ifndef _SBC_PROTOCOL_H_
#define _SBC_PROTOCOL_H_
/**
* \ingroup usb_msc_protocol
* \defgroup usb_sbc_protocol SCSI Block Commands protocol definitions
@@ -86,6 +87,7 @@ enum scsi_sbc_mode {
SCSI_MS_MODE_CACHING = 0x08, //!< Caching mode page
};
//! \name SBC-2 Device-Specific Parameter
//@{
#define SCSI_MS_SBC_WP 0x80 //!< Write Protected

View File

@@ -6,7 +6,7 @@
#include "../../../inc/MarlinConfig.h"
#if HAS_MEDIA
#if ENABLED(SDSUPPORT)
#include "../../../sd/cardreader.h"
extern "C" {
@@ -138,5 +138,5 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
#endif // ACCESS_USB == true
#endif // HAS_MEDIA
#endif // SDSUPPORT
#endif // ARDUINO_ARCH_SAM

View File

@@ -45,6 +45,7 @@
* Support and FAQ: visit <a href="https://www.atmel.com/design-support/">Atmel Support</a>
*/
#ifndef _SD_MMC_SPI_MEM_H_
#define _SD_MMC_SPI_MEM_H_
@@ -62,15 +63,18 @@
#error sd_mmc_spi_mem.h is #included although SD_MMC_SPI_MEM is disabled
#endif
#include "ctrl_access.h"
//_____ D E F I N I T I O N S ______________________________________________
#define SD_MMC_REMOVED 0
#define SD_MMC_INSERTED 1
#define SD_MMC_REMOVING 2
//---- CONTROL FUNCTIONS ----
//---- CONTROL FONCTIONS ----
//!
//! @brief This function initializes the hw/sw resources required to drive the SD_MMC_SPI.
//!/
@@ -129,7 +133,8 @@ extern bool sd_mmc_spi_wr_protect(void);
//!
extern bool sd_mmc_spi_removal(void);
//---- ACCESS DATA FUNCTIONS ----
//---- ACCESS DATA FONCTIONS ----
#if ACCESS_USB == true
// Standard functions for open in read/write mode the device

View File

@@ -200,6 +200,7 @@ enum scsi_vpd_page_code {
#define SCSI_VPD_ID_TYPE_T10 1
/* Sense keys */
enum scsi_sense_key {
SCSI_SK_NO_SENSE = 0x0,
@@ -271,6 +272,7 @@ struct spc_control_page_info_execpt {
be32_t report_count;
};
enum scsi_spc_mode_sense_pc {
SCSI_MS_SENSE_PC_CURRENT = 0,
SCSI_MS_SENSE_PC_CHANGEABLE = 1,
@@ -278,15 +280,20 @@ enum scsi_spc_mode_sense_pc {
SCSI_MS_SENSE_PC_SAVED = 3,
};
static inline bool scsi_mode_sense_dbd_is_set(const uint8_t * cdb) {
static inline bool scsi_mode_sense_dbd_is_set(const uint8_t * cdb)
{
return (cdb[1] >> 3) & 1;
}
static inline uint8_t scsi_mode_sense_get_page_code(const uint8_t * cdb) {
static inline uint8_t scsi_mode_sense_get_page_code(const uint8_t * cdb)
{
return cdb[2] & 0x3F;
}
static inline uint8_t scsi_mode_sense_get_pc(const uint8_t * cdb) {
static inline uint8_t scsi_mode_sense_get_pc(const uint8_t * cdb)
{
return cdb[2] >> 6;
}

View File

@@ -212,6 +212,7 @@ extern "C" {
# define CONFIG_USBCLK_DIV
#endif
extern void sysclk_enable_usb(void);
extern void sysclk_disable_usb(void);

Some files were not shown because too many files have changed in this diff Show More