Compare commits

..

1 Commits

Author SHA1 Message Date
Scott Lahteine
d97dc10216 RC7 README 2016-08-21 00:58:10 -05:00
546 changed files with 61445 additions and 324201 deletions

20
.gitattributes vendored
View File

@@ -1,20 +0,0 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto
# Files with Unix line endings
*.c text eol=lf
*.cpp text eol=lf
*.h text eol=lf
*.ino text eol=lf
*.py text eol=lf
*.sh text eol=lf
*.scad text eol=lf
# Files with native line endings
# *.sln text
# Binary files
*.png binary
*.jpg binary
*.fon binary

1
.github/FUNDING.yml vendored
View File

@@ -1 +0,0 @@
custom: http://www.thinkyhead.com/donate-to-marlin

View File

@@ -1,43 +0,0 @@
---
name: Bug report
about: Report a bug in Marlin
title: "[BUG] (short description)"
labels: ''
assignees: ''
---
<!--
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md
Do you want to ask a question? Are you looking for support? Please don't post here. Instead please use one of the support links at https://github.com/MarlinFirmware/Marlin/issues/new/choose
Before filing an issue be sure to test the "bugfix" branches to see whether the issue has been resolved.
-->
### Bug Description
<!-- Description of the bug -->
### My Configurations
**Required:** Please include a ZIP file containing your `Configuration.h` and `Configuration_adv.h` files.
### Steps to Reproduce
<!-- Please describe the steps needed to reproduce the issue -->
1. [First Step]
2. [Second Step]
3. [and so on...]
**Expected behavior:** [What you expect to happen]
**Actual behavior:** [What actually happens]
#### Additional Information
* Provide pictures or links to videos that clearly demonstrate the issue.
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.

View File

@@ -1,17 +0,0 @@
blank_issues_enabled: false
contact_links:
- name: Marlin Documentation
url: http://marlinfw.org/
about: Lots of documentation on installing and using Marlin.
- name: MarlinFirmware Facebook group
url: https://www.facebook.com/groups/1049718498464482
about: Please ask and answer questions here.
- name: Marlin on Discord
url: https://discord.gg/n5NJ59y
about: Join the Discord server for support and discussion.
- name: Marlin Discussion Forum
url: http://forums.reprap.org/list.php?415
about: A searchable web forum hosted by RepRap dot org.
- name: Marlin Videos on YouTube
url: https://www.youtube.com/results?search_query=marlin+firmware
about: Tutorials and more from Marlin users all around the world. Great for new users!

View File

@@ -1,35 +0,0 @@
---
name: Feature request
about: Request a Feature
title: "[FR] (feature request title)"
labels: ''
assignees: ''
---
<!--
Have you read Marlin's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md
Do you want to ask a question? Are you looking for support? Please don't post here. Instead please use one of the support links at https://github.com/MarlinFirmware/Marlin/issues/new/choose
Before filing an issue be sure to test the "bugfix" branches to see whether the issue has been resolved.
-->
### Description
<!-- Description of the requested feature -->
### Feature Workflow
<!-- Please describe the feature's behavior, user interaction, etc. -->
1. [First Action]
2. [Second Action]
3. [and so on...]
#### Additional Information
* Provide pictures or links that demonstrate a similar feature or concept.
* See [How Can I Contribute](#how-can-i-contribute) for additional guidelines.

View File

@@ -1,46 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
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 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
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version]
[homepage]: https://contributor-covenant.org
[version]: https://contributor-covenant.org/version/1/4/

View File

@@ -1,144 +0,0 @@
# Contributing to Marlin
Thanks for your interest in contributing to Marlin Firmware!
The following is a set of guidelines for contributing to Marlin, hosted by the [MarlinFirmware Organization](https://github.com/MarlinFirmware) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a Pull Request.
#### Table Of Contents
[Code of Conduct](#code-of-conduct)
[I don't want to read this whole thing, I just have a question!!!](#i-dont-want-to-read-this-whole-thing-i-just-have-a-question)
[How Can I Contribute?](#how-can-i-contribute)
* [Reporting Bugs](#reporting-bugs)
* [Suggesting Features or Changes](#suggesting-features-or-changes)
* [Your First Code Contribution](#your-first-code-contribution)
* [Pull Requests](#pull-requests)
[Styleguides](#styleguides)
* [Git Commit Messages](#git-commit-messages)
* [C++ Coding Standards](#c++-coding-standards)
* [Documentation Styleguide](#documentation)
[Additional Notes](#additional-notes)
* [Issue and Pull Request Labels](#issue-and-pull-request-labels)
## 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 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.
We have a Message Board and a Facebook group where our knowledgable user community can provide helpful advice if you have questions.
* [Marlin RepRap forum](http://forums.reprap.org/list.php?415)
* [MarlinFirmware on Facebook](https://www.facebook.com/groups/1049718498464482/)
If chat is more your speed, you can join the MarlinFirmware Slack team:
* Join the Marlin Slack Team
* To obtain group access, please [send a request](http://www.thinkyhead.com/contact/9) to @thinkyhead.
* Even though Slack is a chat service, sometimes it takes several hours for community members to respond &mdash; please be patient!
* Use the `#general` channel for general questions or discussion about Marlin.
* Other channels exist for certain topics. Check the channel list.
## How Can I Contribute?
### Reporting Bugs
This section guides you through submitting a Bug Report for Marlin. Following these guidelines helps maintainers and the community understand your report, reproduce the behavior, and find related reports.
Before creating a Bug Report, please test the "nightly" development branch, as you might find out that you don't need to create one. When you are creating a Bug Report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](issue_template.md), the information it asks for helps us resolve issues faster.
> **Note:** Regressions can happen. If you find a **Closed** issue that seems like your issue, go ahead and open a new issue and include a link to the original issue in the body of your new one. All you need to create a link is the issue number, preceded by #. For example, #8888.
#### How Do I Submit A (Good) Bug Report?
Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Use the New Issue button to create an issue and provide the following information by filling in [the template](issue_template.md).
Explain the problem and include additional details to help maintainers reproduce the problem:
* **Use a clear and descriptive title** for the issue to identify the problem.
* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how you started Marlin, e.g. which command exactly you used in the terminal, or how you started Marlin otherwise. When listing steps, **don't just say what you did, but explain how you did it**. For example, if you moved the cursor to the end of a line, explain if you used the mouse, or a keyboard shortcut or an Marlin command, and if so which one?
* **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets or log output in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines).
* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior.
* **Explain which behavior you expected to see instead and why.**
* **Include detailed log output** especially for probing and leveling. See below for usage of `DEBUG_LEVELING_FEATURE`.
* **Include screenshots, links to videos, etc.** which clearly demonstrate the problem.
* **Include G-code** (if relevant) that reliably causes the problem to show itself.
* **If the problem wasn't triggered by a specific action**, describe what you were doing before the problem happened and share more information using the guidelines below.
Provide more context:
* **Can you reproduce the problem with a minimum of options enabled?**
* **Did the problem start happening recently** (e.g. after updating to a new version of Marlin) or was this always a problem?
* If the problem started happening recently, **can you reproduce the problem in an older version of Marlin?** What's the most recent version in which the problem doesn't happen? You can download older versions of Marlin from [the releases page](https://github.com/MarlinFirmware/Marlin/releases).
* **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens.
Include details about your configuration and environment:
* **Which version of Marlin are you using?** Marlin's exact version and build date can be seen in the startup message when a host connects to Marlin, or in the LCD Info menu (if enabled).
* **What kind of 3D Printer and electronics are you using**?
* **What kind of add-ons (probe, filament sensor) do you have**?
* **Include your Configuration files.** Make a ZIP file containing `Configuration.h` and `Configuration_adv.h` and drop it on your reply.
### Suggesting Features or Changes
This section guides you through submitting a suggestion for Marlin, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion and find related suggestions.
Before creating a suggestion, please check [this list](#before-submitting-a-suggestion) as you might find out that you don't need to create one. When you are creating an enhancement suggestion, please [include as many details as possible](#how-do-i-submit-a-good-enhancement-suggestion). Fill in [the template](issue_template.md), including the steps that you imagine you would take if the feature you're requesting existed.
#### Before Submitting a Feature Request
* **Check the [Marlin website](http://marlinfw.org/)** for tips — you might discover that the feature is already included. Most importantly, check if you're using [the latest version of Marlin](https://github.com/MarlinFirmware/Marlin/releases) and if you can get the desired behavior by changing [Marlin's config settings](http://marlinfw.org/docs/configuration/configuration.html).
* **Perform a [cursory search](https://github.com/MarlinFirmware/Marlin/issues?q=is%3Aissue)** to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
#### How Do I Submit A (Good) Feature Request?
Feature Requests are tracked as [GitHub issues](https://guides.github.com/features/issues/). Please follow these guidelines in your request:
* **Use a clear and descriptive title** for the issue to identify the suggestion.
* **Provide a step-by-step description of the requested feature** in as much detail as possible.
* **Provide specific examples to demonstrate the steps**.
* **Describe the current behavior** and **explain which behavior you expected to see instead** and why.
* **Include screenshots and links to videos** which demonstrate the feature or point out the part of Marlin to which the request is related.
* **Explain why this feature would be useful** to most Marlin users.
* **Name other firmwares that have this feature, if any.**
### Your First Code Contribution
Unsure where to begin contributing to Marlin? You can start by looking through these `good-first-issue` and `help-wanted` issues:
* [Beginner issues][good-first-issue] - issues which should only require a few lines of code, and a test or two.
* [Help Wanted issues][help-wanted] - issues which should be a bit more involved than `beginner` issues.
### Pull Requests
Pull Requests should always be targeted to working branches (e.g., `bugfix-1.1.x` and/or `bugfix-2.0.x`) and never to release branches (e.g., `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](http://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
* Fill in [the required template](pull_request_template.md).
* Don't include issue numbers in the PR title.
* Include pictures, diagrams, and links to videos in your Pull Request to demonstrate your changes, if needed.
* Follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website.
* Document new code with clear and concise comments.
* End all files with a newline.
## Styleguides
### Git Commit Messages
* Use the present tense ("Add feature" not "Added feature").
* Use the imperative mood ("Move cursor to..." not "Moves cursor to...").
* Limit the first line to 72 characters or fewer.
* Reference issues and Pull Requests liberally after the first line.
### C++ Coding Standards
* Please read and follow the [Coding Standards](http://marlinfw.org/docs/development/coding_standards.html) posted on our website. Failure to follow these guidelines will delay evaluation and acceptance of Pull Requests.
### Documentation
* Guidelines for documentation are still under development. In-general, be clear, concise, and to-the-point.

View File

@@ -1,16 +0,0 @@
# NO SUPPORT REQUESTS PLEASE
Support Requests posted here will be automatically closed!
This Issue Queue is for Marlin bug reports and development-related issues, and we prefer not to handle user-support questions here. See https://github.com/MarlinFirmware/Marlin/blob/1.1.x/.github/contributing.md#i-dont-want-to-read-this-whole-thing-i-just-have-a-question.
For best results getting help with configuration and troubleshooting, please use the following resources:
- RepRap.org Marlin Forum http://forums.reprap.org/list.php?415
- Tom's 3D Forums https://discuss.toms3d.org/
- Facebook Group "Marlin Firmware" https://www.facebook.com/groups/1049718498464482/
- Facebook Group "Marlin Firmware for 3D Printers" https://www.facebook.com/groups/3Dtechtalk/
- Marlin Configuration https://www.youtube.com/results?search_query=marlin+configuration on YouTube
- Marlin Discord server. Join link: https://discord.gg/n5NJ59y
After seeking help from the community, if the consensus points to to a bug in Marlin, then you should post a Bug Report at https://github.com/MarlinFirmware/Marlin/issues/new/choose).

View File

@@ -1,19 +0,0 @@
### Requirements
* Filling out this template is required. Pull Requests without a clear description may be closed at the maintainers' discretion.
### Description
<!--
We must be able to understand your proposed change from this description. If we can't understand what the code will do from this description, the Pull Request may be closed at the maintainers' discretion. Keep in mind that the maintainer reviewing this PR may not be familiar with or have worked with the code recently, so please walk us through the concepts.
-->
### Benefits
<!-- What does this fix or improve? -->
### Related Issues
<!-- Whether this fixes a bug or fulfills a feature request, please list any related Issues here. -->

37
.gitignore vendored Executable file → Normal file
View File

@@ -1,6 +1,6 @@
#
# Marlin 3D Printer Firmware
# Copyright (C) 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
# Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
#
# Based on Sprinter and grbl.
# Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
@@ -42,7 +42,7 @@ applet/
*.i
*.ii
*.swp
tags
#
# C++
@@ -52,7 +52,6 @@ tags
*.lo
*.o
*.obj
*.ino.cpp
# Precompiled Headers
*.gch
@@ -115,35 +114,3 @@ tags
# Debug files
*.dSYM/
*.su
# PlatformIO files/dirs
.pio*
.pioenvs
.piolibdeps
lib/readme.txt
#Visual Studio
*.sln
*.vcxproj
*.vcxproj.user
*.vcxproj.filters
Release/
Debug/
__vm/
.vs/
vc-fileutils.settings
#Visual Studio Code
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/*.db
#cmake
CMakeLists.txt
Marlin/CMakeLists.txt
CMakeListsPrivate.txt
#CLion
cmake-build-*

View File

@@ -1,6 +1,4 @@
dist: bionic
sudo: true
#
---
language: c
#
notifications:
@@ -13,7 +11,7 @@ before_install:
#
# Publish the buildroot script folder
- chmod +x ${TRAVIS_BUILD_DIR}/buildroot/bin/*
- export PATH=${TRAVIS_BUILD_DIR}/buildroot/bin/:${PATH}
- ln -s ${TRAVIS_BUILD_DIR}/buildroot/bin/ ~/bin
#
# Start fb X server
- "/sbin/start-stop-daemon --start --quiet --pidfile /tmp/custom_xvfb_1.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :1 -ac -screen 0 1280x1024x16"
@@ -22,10 +20,10 @@ before_install:
#
install:
#
# Install arduino 1.8.5
- wget http://downloads.arduino.cc/arduino-1.8.9-linux64.tar.xz
- tar xf arduino-1.8.9-linux64.tar.xz
- sudo mv arduino-1.8.9 /usr/local/share/arduino
# Install arduino 1.6.9
- wget http://downloads-02.arduino.cc/arduino-1.6.9-linux64.tar.xz
- tar xf arduino-1.6.9-linux64.tar.xz
- sudo mv arduino-1.6.9 /usr/local/share/arduino
- ln -s /usr/local/share/arduino/arduino ${TRAVIS_BUILD_DIR}/buildroot/bin/arduino
#
# Install: LiquidCrystal_I2C library
@@ -37,28 +35,15 @@ install:
- sudo mv LiquidTWI2 /usr/local/share/arduino/libraries/LiquidTWI2
#
# Install: Monochrome Graphics Library for LCDs and OLEDs
- git clone https://github.com/olikraus/U8glib_Arduino.git
- sudo mv U8glib_Arduino /usr/local/share/arduino/libraries/U8glib
- arduino --install-library "U8glib"
#
# Install: L6470 Stepper Motor Driver library
# - git clone https://github.com/ameyer/Arduino-L6470.git
# - sudo mv Arduino-L6470/L6470 /usr/local/share/arduino/libraries/L6470
- git clone https://github.com/ameyer/Arduino-L6470.git
- sudo mv Arduino-L6470/L6470 /usr/local/share/arduino/libraries/L6470
#
# Install: TMC26X Stepper Motor Controller library
# - git clone https://github.com/trinamic/TMC26XStepper.git
# - sudo mv TMC26XStepper /usr/local/share/arduino/libraries/TMC26XStepper
#
# Install: TMC2130 Stepper Motor Controller library
- git clone https://github.com/teemuatlut/TMC2130Stepper.git
- sudo mv TMC2130Stepper /usr/local/share/arduino/libraries/TMC2130Stepper
#
# Install: TMC2208 Stepper Motor Controller library
- git clone https://github.com/teemuatlut/TMC2208Stepper.git
- sudo mv TMC2208Stepper /usr/local/share/arduino/libraries/TMC2208Stepper
#
# Install: Adafruit Neopixel library
- git clone https://github.com/adafruit/Adafruit_NeoPixel.git
- sudo mv Adafruit_NeoPixel /usr/local/share/arduino/libraries/Adafruit_NeoPixel
- git clone https://github.com/trinamic/TMC26XStepper.git
- sudo mv TMC26XStepper /usr/local/share/arduino/libraries/TMC26XStepper
#
before_script:
#
@@ -81,94 +66,84 @@ script:
#
- build_marlin
#
# Test 2 extruders (one MAX6675) and heated bed on basic RAMPS 1.4
# Test a "Fix Mounted" Probe with Safe Homing, some arc options,
# linear bed leveling, M48, leveling debug, and firmware retraction.
# Test heated bed temperature sensor
#
- opt_set TEMP_SENSOR_BED 1
- build_marlin
#
# Test 2 extruders on basic RAMPS 1.4
#
- opt_set MOTHERBOARD BOARD_RAMPS_14_EEB
- opt_set EXTRUDERS 2
- opt_set TEMP_SENSOR_0 -2
- opt_set TEMP_SENSOR_1 1
- opt_set TEMP_SENSOR_BED 1
- opt_set POWER_SUPPLY 1
- opt_enable PIDTEMPBED FIX_MOUNTED_PROBE Z_SAFE_HOMING
- opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT EEPROM_SETTINGS PINS_DEBUGGING
- opt_enable BLINKM PCA9632 RGB_LED NEOPIXEL_LED AUTO_POWER_CONTROL NOZZLE_PARK_FEATURE FILAMENT_RUNOUT_SENSOR
- opt_enable AUTO_BED_LEVELING_LINEAR Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE
- opt_enable_adv ARC_P_CIRCLES ADVANCED_PAUSE_FEATURE CNC_WORKSPACE_PLANES CNC_COORDINATE_SYSTEMS POWER_LOSS_RECOVERY POWER_LOSS_PIN POWER_LOSS_STATE
- opt_enable_adv FWRETRACT MAX7219_DEBUG LED_CONTROL_MENU CASE_LIGHT_ENABLE CASE_LIGHT_USE_NEOPIXEL CODEPENDENT_XY_HOMING
- opt_set GRID_MAX_POINTS_X 16
- opt_set_adv FANMUX0_PIN 53
- build_marlin
#
# Test a probeless build of AUTO_BED_LEVELING_UBL, with lots of extruders
# Test 3 extruders on RUMBA (can use any board with >=3 extruders defined)
# Include a test for LIN_ADVANCE here also
#
- opt_set MOTHERBOARD BOARD_RUMBA
- opt_set EXTRUDERS 3
- opt_set TEMP_SENSOR_2 1
- opt_enable_adv LIN_ADVANCE
- build_marlin
#
# Test PIDTEMPBED
#
- restore_configs
- opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO
- opt_set EXTRUDERS 5
- opt_set TEMP_SENSOR_1 1
- opt_set TEMP_SENSOR_2 5
- opt_set TEMP_SENSOR_3 20
- opt_set TEMP_SENSOR_4 999
- opt_set TEMP_SENSOR_BED 1
- opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 DEBUG_LEVELING_FEATURE G26_MESH_EDITING ENABLE_LEVELING_FADE_HEIGHT SKEW_CORRECTION
- opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
- opt_enable_adv CUSTOM_USER_MENUS I2C_POSITION_ENCODERS BABYSTEPPING BABYSTEP_XY LIN_ADVANCE NANODLP_Z_SYNC QUICK_HOME JUNCTION_DEVIATION MAX7219_DEBUG
- opt_set_adv MAX7219_ROTATE 270
- opt_enable PIDTEMPBED
- build_marlin
#
# Add a Sled Z Probe, use UBL Cartesian moves, use Japanese language
# Test a "Fix Mounted" Probe along with Safe Homing
#
- opt_enable Z_PROBE_SLED SKEW_CORRECTION SKEW_CORRECTION_FOR_Z SKEW_CORRECTION_GCODE S_CURVE_ACCELERATION
- opt_set LCD_LANGUAGE kana_utf8
- opt_disable SEGMENT_LEVELED_MOVES
- opt_enable_adv BABYSTEP_ZPROBE_OFFSET DOUBLECLICK_FOR_Z_BABYSTEPPING
- restore_configs
- opt_enable FIX_MOUNTED_PROBE Z_SAFE_HOMING
- build_marlin
#
# ...with AUTO_BED_LEVELING_FEATURE, Z_MIN_PROBE_REPEATABILITY_TEST, & DEBUG_LEVELING_FEATURE
#
- opt_enable AUTO_BED_LEVELING_FEATURE Z_MIN_PROBE_REPEATABILITY_TEST DEBUG_LEVELING_FEATURE
- build_marlin
#
# Test a Sled Z Probe
#
- restore_configs
- opt_enable Z_PROBE_SLED
- build_marlin
#
# ...with AUTO_BED_LEVELING_FEATURE & DEBUG_LEVELING_FEATURE
#
- opt_enable AUTO_BED_LEVELING_FEATURE DEBUG_LEVELING_FEATURE
- build_marlin
#
# Test a Servo Probe
# ...with AUTO_BED_LEVELING_3POINT, DEBUG_LEVELING_FEATURE, EEPROM_SETTINGS, EEPROM_CHITCHAT, EXTENDED_CAPABILITIES_REPORT, and AUTO_REPORT_TEMPERATURES
#
- restore_configs
- opt_enable NUM_SERVOS Z_PROBE_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE
- opt_set NUM_SERVOS 1
- opt_enable AUTO_BED_LEVELING_3POINT DEBUG_LEVELING_FEATURE EEPROM_SETTINGS EEPROM_CHITCHAT
- opt_enable_adv NO_VOLUMETRICS EXTENDED_CAPABILITIES_REPORT AUTO_REPORT_TEMPERATURES AUTOTEMP G38_PROBE_TARGET
- opt_enable NUM_SERVOS Z_ENDSTOP_SERVO_NR Z_SERVO_ANGLES DEACTIVATE_SERVOS_AFTER_MOVE
- build_marlin
#
# ...with AUTO_BED_LEVELING_FEATURE & DEBUG_LEVELING_FEATURE
#
- opt_enable AUTO_BED_LEVELING_FEATURE DEBUG_LEVELING_FEATURE
- build_marlin
#
# Test MESH_BED_LEVELING feature, with LCD
#
- restore_configs
- opt_enable MESH_BED_LEVELING G26_MESH_EDITING MESH_G28_REST_ORIGIN LCD_BED_LEVELING ULTIMAKERCONTROLLER
- opt_enable MESH_BED_LEVELING MESH_G28_REST_ORIGIN MANUAL_BED_LEVELING ULTIMAKERCONTROLLER
- build_marlin
#
# Test MINIRAMBO for PWM_MOTOR_CURRENT
# PROBE_MANUALLY feature, with LCD support,
# ULTIMAKERCONTROLLER, FILAMENT_LCD_DISPLAY, FILAMENT_WIDTH_SENSOR,
# PRINTCOUNTER, NOZZLE_PARK_FEATURE, NOZZLE_CLEAN_FEATURE, PCA9632,
# Z_DUAL_ENDSTOPS, BEZIER_CURVE_SUPPORT, EXPERIMENTAL_I2CBUS,
# ADVANCED_PAUSE_FEATURE, ADVANCED_PAUSE_CONTINUOUS_PURGE, PARK_HEAD_ON_PAUSE, LCD_INFO_MENU, M114_DETAIL
# EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER,
# INCH_MODE_SUPPORT, TEMPERATURE_UNITS_SUPPORT
# Test EEPROM_SETTINGS, EEPROM_CHITCHAT, M100_FREE_MEMORY_WATCHER,
# INCH_MODE_SUPPORT, TEMPERATURE_UNITS_SUPPORT
#
- restore_configs
- opt_set MOTHERBOARD BOARD_MINIRAMBO
- opt_enable PROBE_MANUALLY AUTO_BED_LEVELING_BILINEAR G26_MESH_EDITING LCD_BED_LEVELING ULTIMAKERCONTROLLER
- opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER M100_FREE_MEMORY_DUMPER M100_FREE_MEMORY_CORRUPTOR INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT
- opt_enable ULTIMAKERCONTROLLER SDSUPPORT
- opt_enable PRINTCOUNTER NOZZLE_PARK_FEATURE NOZZLE_CLEAN_FEATURE PCA9632
- opt_enable_adv BEZIER_CURVE_SUPPORT EXPERIMENTAL_I2CBUS
- opt_enable_adv ADVANCED_PAUSE_FEATURE ADVANCED_PAUSE_CONTINUOUS_PURGE FILAMENT_LOAD_UNLOAD_GCODES PARK_HEAD_ON_PAUSE LCD_INFO_MENU M114_DETAIL
- opt_set_adv PWM_MOTOR_CURRENT {1300,1300,1250}
- opt_set_adv I2C_SLAVE_ADDRESS 63
- opt_enable EEPROM_SETTINGS EEPROM_CHITCHAT M100_FREE_MEMORY_WATCHER INCH_MODE_SUPPORT TEMPERATURE_UNITS_SUPPORT
- build_marlin
#
# Mixing Extruder with 5 steppers, Cyrillic
# Mixing Extruder
#
- restore_configs
- opt_set MOTHERBOARD BOARD_AZTEEG_X3_PRO
- opt_enable MIXING_EXTRUDER CR10_STOCKDISPLAY
- opt_set MIXING_STEPPERS 5
- opt_set LCD_LANGUAGE ru
- opt_enable MIXING_EXTRUDER
- opt_set MIXING_STEPPERS 2
- build_marlin
#
# Test DUAL_X_CARRIAGE
@@ -183,11 +158,11 @@ script:
#
# Test SPEAKER with BOARD_BQ_ZUM_MEGA_3D and BQ_LCD_SMART_CONTROLLER
#
#- restore_configs
#- opt_set MOTHERBOARD BOARD_BQ_ZUM_MEGA_3D
#- opt_set LCD_FEEDBACK_FREQUENCY_DURATION_MS 10
#- opt_set LCD_FEEDBACK_FREQUENCY_HZ 100
#- opt_enable BQ_LCD_SMART_CONTROLLER SPEAKER
- restore_configs
- opt_set MOTHERBOARD BOARD_BQ_ZUM_MEGA_3D
- opt_set LCD_FEEDBACK_FREQUENCY_DURATION_MS 10
- opt_set LCD_FEEDBACK_FREQUENCY_HZ 100
- opt_enable BQ_LCD_SMART_CONTROLLER SPEAKER
#
# Test SWITCHING_EXTRUDER
#
@@ -196,46 +171,98 @@ script:
- opt_set EXTRUDERS 2
- opt_enable NUM_SERVOS
- opt_set NUM_SERVOS 1
- opt_set TEMP_SENSOR_1 1
- opt_enable SWITCHING_EXTRUDER ULTIMAKERCONTROLLER
- build_marlin
#
# Test MINIRAMBO for PWM_MOTOR_CURRENT
#
- restore_configs
- opt_set MOTHERBOARD BOARD_MINIRAMBO
- build_marlin
#
# Test FILAMENT_CHANGE_FEATURE and LCD_INFO_MENU
#
- restore_configs
- opt_enable ULTIMAKERCONTROLLER
- opt_enable_adv FILAMENT_CHANGE_FEATURE LCD_INFO_MENU
- build_marlin
#
# Enable filament sensor
#
- restore_configs
- opt_enable FILAMENT_WIDTH_SENSOR
- build_marlin
#
# Enable filament sensor with LCD display
#
- opt_enable ULTIMAKERCONTROLLER FILAMENT_LCD_DISPLAY
- build_marlin
#
# Enable BEZIER_CURVE_SUPPORT
#
- restore_configs
- opt_enable_adv BEZIER_CURVE_SUPPORT
- build_marlin
#
# Enable COREXY
#
#- restore_configs
#- opt_enable COREXY
#- build_marlin
#
# Test many less common options
#
- restore_configs
- opt_enable COREYX
- opt_set_adv FAN_MIN_PWM 50
- opt_set_adv FAN_KICKSTART_TIME 100
- opt_set_adv XY_FREQUENCY_LIMIT 15
- opt_enable_adv SHOW_TEMP_ADC_VALUES HOME_Y_BEFORE_X EMERGENCY_PARSER FAN_KICKSTART_TIME
- opt_enable_adv ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED ADVANCED_OK
- opt_enable_adv VOLUMETRIC_DEFAULT_ON NO_WORKSPACE_OFFSETS ACTION_ON_KILL
- opt_enable_adv EXTRA_FAN_SPEED FWERETRACT Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS
- opt_enable_adv MENU_ADDAUTOSTART SDCARD_SORT_ALPHA
- opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER BABYSTEPPING DAC_MOTOR_CURRENT_DEFAULT
- opt_enable FILAMENT_LCD_DISPLAY FILAMENT_WIDTH_SENSOR
- opt_enable ENDSTOP_INTERRUPTS_FEATURE FAN_SOFT_PWM SDSUPPORT
- opt_enable USE_XMAX_PLUG
- opt_enable COREXY
- build_marlin
#
######## Other Standard LCD/Panels ##############
# Enable COREXZ
#
- restore_configs
- opt_enable COREXZ
- build_marlin
#
# Enable Z_DUAL_STEPPER_DRIVERS, Z_DUAL_ENDSTOPS
#
- restore_configs
- opt_enable_adv Z_DUAL_STEPPER_DRIVERS Z_DUAL_ENDSTOPS
- pins_set RAMPS X_MAX_PIN -1
- opt_set_adv Z2_MAX_PIN 2
- build_marlin
#
# Test PRINTCOUNTER
#
- restore_configs
- opt_enable PRINTCOUNTER
- build_marlin
#
# Test NOZZLE_PARK_FEATURE
#
- restore_configs
- opt_enable NOZZLE_PARK_FEATURE
- build_marlin
#
# Test NOZZLE_CLEAN_FEATURE
#
- restore_configs
- opt_enable NOZZLE_CLEAN_FEATURE
- build_marlin
#
#
######## STANDARD LCD/PANELS ##############
#
# ULTRA_LCD
#
#- restore_configs
#- opt_enable ULTRA_LCD
#- build_marlin
- restore_configs
- opt_enable ULTRA_LCD
- build_marlin
#
# DOGLCD
#
#- restore_configs
#- opt_enable DOGLCD
#- build_marlin
- restore_configs
- opt_enable DOGLCD
- build_marlin
#
# ULTIMAKERCONTROLLER
#
- restore_configs
- opt_enable ULTIMAKERCONTROLLER
- build_marlin
#
# MAKRPANEL
# Needs to use Melzi and Sanguino hardware
@@ -244,33 +271,22 @@ script:
#- opt_enable MAKRPANEL
#- build_marlin
#
# REPRAP_DISCOUNT_SMART_CONTROLLER, SDSUPPORT, BABYSTEPPING, RIGIDBOARD_V2, and DAC_MOTOR_CURRENT_DEFAULT
# REPRAP_DISCOUNT_SMART_CONTROLLER, SDSUPPORT, and BABYSTEPPING
#
#- restore_configs
#- opt_set MOTHERBOARD BOARD_RIGIDBOARD_V2
#- opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT BABYSTEPPING DAC_MOTOR_CURRENT_DEFAULT
#- build_marlin
# #
# G3D_PANEL with SDCARD_SORT_ALPHA and STATUS_MESSAGE_SCROLLING
- restore_configs
- opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT BABYSTEPPING
- build_marlin
#
#- restore_configs
#- opt_enable G3D_PANEL SDSUPPORT
#- opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES
#- opt_set_adv SDSORT_GCODE true
#- opt_set_adv SDSORT_USES_RAM true
#- opt_set_adv SDSORT_USES_STACK true
#- opt_set_adv SDSORT_CACHE_NAMES true
#- build_marlin
# G3D_PANEL
#
# REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER with LIGHTWEIGHT_UI
- restore_configs
- opt_enable G3D_PANEL SDSUPPORT
- build_marlin
#
# REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#
- restore_configs
- opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT
- opt_enable_adv SDCARD_SORT_ALPHA STATUS_MESSAGE_SCROLLING SCROLL_LONG_FILENAMES LIGHTWEIGHT_UI
- opt_set_adv SDSORT_GCODE true
- opt_set_adv SDSORT_USES_RAM true
- opt_set_adv SDSORT_USES_STACK true
- opt_set_adv SDSORT_CACHE_NAMES true
- build_marlin
#
# REPRAPWORLD_KEYPAD
@@ -282,9 +298,9 @@ script:
#
# RA_CONTROL_PANEL
#
#- restore_configs
#- opt_enable RA_CONTROL_PANEL PINS_DEBUGGING
#- build_marlin
- restore_configs
- opt_enable RA_CONTROL_PANEL
- build_marlin
#
######## I2C LCD/PANELS ##############
#
@@ -292,10 +308,10 @@ script:
# Most I2C configurations are failing at the moment because they require
# a different Liquid Crystal library "LiquidTWI2".
#
# LCD_SAINSMART_I2C_1602
# LCD_I2C_SAINSMART_YWROBOT
#
#- restore_configs
#- opt_enable LCD_SAINSMART_I2C_1602
#- opt_enable LCD_I2C_SAINSMART_YWROBOT
#- build_marlin
#
# LCD_I2C_PANELOLU2
@@ -312,43 +328,33 @@ script:
#
# LCM1602
#
#- restore_configs
#- opt_enable LCM1602
#- build_marlin
#
# Language files test with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#
#- restore_configs
#- opt_enable REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER SDSUPPORT
#- for lang in an bg ca zh_CN zh_TW cz da de el el-gr en es eu fi fr gl hr it jp-kana ko_KR nl pl pt pt-br ru sk tr uk test; do opt_set LCD_LANGUAGE $lang; echo "compile with language $lang ..."; build_marlin
#
#- restore_configs
#- opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER SDSUPPORT
#- for lang in an bg ca zh_CN zh_TW cz da de el el-gr en es eu fi fr gl hr it jp-kana ko_KR nl pl pt pt-br ru sk tr uk test; do opt_set LCD_LANGUAGE $lang; echo "compile with language $lang ..."; build_marlin
- restore_configs
- opt_enable LCM1602
- build_marlin
#
#
######## Example Configurations ##############
#
# BQ Hephestos 2
#- restore_configs
#- use_example_configs Hephestos_2
#- build_marlin
#
# Delta Config (generic) + ABL bilinear + PROBE_MANUALLY
- use_example_configs delta/generic
- opt_enable REPRAP_DISCOUNT_SMART_CONTROLLER DELTA_CALIBRATION_MENU AUTO_BED_LEVELING_BILINEAR PROBE_MANUALLY
- restore_configs
- use_example_configs Hephestos_2
- build_marlin
#
# Delta Config (generic) + UBL + ALLEN_KEY + OLED_PANEL_TINYBOY2 + EEPROM_SETTINGS
#
# Delta Config (generic)
- restore_configs
- use_example_configs delta/generic
- opt_enable AUTO_BED_LEVELING_UBL RESTORE_LEVELING_AFTER_G28 Z_PROBE_ALLEN_KEY EEPROM_SETTINGS EEPROM_CHITCHAT
- opt_enable OLED_PANEL_TINYBOY2 MESH_EDIT_GFX_OVERLAY
- build_marlin
#
# Delta Config (FLSUN AC because it's complex)
# Delta Config (generic) + ABL + ALLEN_KEY
#
- use_example_configs delta/FLSUN/auto_calibrate
- use_example_configs delta/generic
- opt_disable DISABLE_MIN_ENDSTOPS
- opt_enable AUTO_BED_LEVELING_FEATURE Z_PROBE_ALLEN_KEY
- build_marlin
#
# Delta Config (Mini Kossel)
#
- use_example_configs delta/kossel_mini
- build_marlin
#
# Makibox Config need to check board type for Teensy++ 2.0
@@ -356,25 +362,10 @@ script:
#- use_example_configs makibox
#- build_marlin
#
# SCARA with TMC2130
# SCARA Config
#
- use_example_configs SCARA
- opt_enable AUTO_BED_LEVELING_BILINEAR FIX_MOUNTED_PROBE USE_ZMIN_PLUG EEPROM_SETTINGS EEPROM_CHITCHAT ULTIMAKERCONTROLLER
- opt_set X_DRIVER_TYPE TMC2130
- opt_set Y_DRIVER_TYPE TMC2130
- opt_set Z_DRIVER_TYPE TMC2130
- opt_set E0_DRIVER_TYPE TMC2130
- opt_enable_adv MONITOR_DRIVER_STATUS STEALTHCHOP HYBRID_THRESHOLD SENSORLESS_HOMING
- build_marlin
#
# TMC2208 Config
#
- restore_configs
- opt_set X_DRIVER_TYPE TMC2208
- opt_set Y_DRIVER_TYPE TMC2208
- opt_set Z_DRIVER_TYPE TMC2208
- opt_set E0_DRIVER_TYPE TMC2208
- opt_enable_adv MONITOR_DRIVER_STATUS STEALTHCHOP HYBRID_THRESHOLD TMC_DEBUG
- opt_enable AUTO_BED_LEVELING_FEATURE FIX_MOUNTED_PROBE USE_ZMIN_PLUG
- build_marlin
#
# tvrrug Config need to check board type for sanguino atmega644p

View File

@@ -22,541 +22,298 @@
/**
* Conditionals_LCD.h
* Conditionals that need to be set before Configuration_adv.h or pins.h
* LCD Defines that depend on configuration but are not editable.
*/
#ifndef CONDITIONALS_LCD_H // Get the LCD defines which are needed first
#define CONDITIONALS_LCD_H
#define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT))
#define LCD_HAS_DIRECTIONAL_BUTTONS (BUTTON_EXISTS(UP) || BUTTON_EXISTS(DWN) || BUTTON_EXISTS(LFT) || BUTTON_EXISTS(RT))
#if ENABLED(CARTESIO_UI)
#define DOGLCD
#define ULTIPANEL
#define DEFAULT_LCD_CONTRAST 90
#define LCD_CONTRAST_MIN 60
#define LCD_CONTRAST_MAX 140
#elif ENABLED(MAKRPANEL)
#define U8GLIB_ST7565_64128N
#elif ENABLED(ZONESTAR_LCD)
#define REPRAPWORLD_KEYPAD
#define REPRAPWORLD_KEYPAD_MOVE_STEP 10.0
#define ADC_KEYPAD
#define ADC_KEY_NUM 8
#define ULTIPANEL
// this helps to implement ADC_KEYPAD menus
#define ENCODER_PULSES_PER_STEP 1
#define ENCODER_STEPS_PER_MENU_ITEM 1
#define ENCODER_FEEDRATE_DEADZONE 2
#define REVERSE_MENU_DIRECTION
#elif ENABLED(ANET_FULL_GRAPHICS_LCD)
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#elif ENABLED(BQ_LCD_SMART_CONTROLLER)
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#elif ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#if ENABLED(miniVIKI)
#define LCD_CONTRAST_MIN 75
#define LCD_CONTRAST_MAX 115
#define DEFAULT_LCD_CONTRAST 95
#define U8GLIB_ST7565_64128N
#elif ENABLED(VIKI2)
#define LCD_CONTRAST_MIN 0
#define LCD_CONTRAST_MAX 255
#define DEFAULT_LCD_CONTRAST 140
#define U8GLIB_ST7565_64128N
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define LCD_CONTRAST_MIN 90
#define LCD_CONTRAST_MAX 130
#define DEFAULT_LCD_CONTRAST 110
#define U8GLIB_LM6059_AF
#define SD_DETECT_INVERTED
#if ENABLED(CARTESIO_UI)
#define DOGLCD
#define ULTIPANEL
#define NEWPANEL
#define DEFAULT_LCD_CONTRAST 90
#define LCD_CONTRAST_MIN 60
#define LCD_CONTRAST_MAX 140
#endif
#elif ENABLED(OLED_PANEL_TINYBOY2)
#define U8GLIB_SSD1306
#define ULTIPANEL
#define REVERSE_ENCODER_DIRECTION
#define REVERSE_MENU_DIRECTION
#elif ENABLED(RA_CONTROL_PANEL)
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
#define DOGLCD
#define U8GLIB_ST7920
#define ULTIPANEL
#elif ENABLED(CR10_STOCKDISPLAY)
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#ifndef ST7920_DELAY_1
#define ST7920_DELAY_1 DELAY_NS(125)
#endif
#ifndef ST7920_DELAY_2
#define ST7920_DELAY_2 DELAY_NS(125)
#endif
#ifndef ST7920_DELAY_3
#define ST7920_DELAY_3 DELAY_NS(125)
#if ENABLED(MAKRPANEL) || ENABLED(MINIPANEL)
#define DOGLCD
#define ULTIPANEL
#define NEWPANEL
#define DEFAULT_LCD_CONTRAST 17
#endif
#elif ENABLED(MKS_12864OLED)
#if ENABLED(miniVIKI) || ENABLED(VIKI2) || ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for SPI LCD 128x64 (Controller ST7565R graphic Display Family)
#define ULTIMAKERCONTROLLER //as available from the Ultimaker online store.
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#define U8GLIB_SH1106
#if ENABLED(miniVIKI)
#define LCD_CONTRAST_MIN 75
#define LCD_CONTRAST_MAX 115
#define DEFAULT_LCD_CONTRAST 95
#elif ENABLED(VIKI2)
#define DEFAULT_LCD_CONTRAST 40
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
#define LCD_CONTRAST_MIN 90
#define LCD_CONTRAST_MAX 130
#define DEFAULT_LCD_CONTRAST 110
#define U8GLIB_LM6059_AF
#define SD_DETECT_INVERTED
#endif
#elif ENABLED(MKS_12864OLED_SSD1306)
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#define U8GLIB_SSD1306
#elif ENABLED(MKS_MINI_12864)
#define MINIPANEL
#endif
#if ENABLED(MAKRPANEL) || ENABLED(MINIPANEL)
#define DOGLCD
#define ULTIPANEL
#define DEFAULT_LCD_CONTRAST 17
#endif
#if ENABLED(ULTI_CONTROLLER)
#define U8GLIB_SSD1309
#define REVERSE_ENCODER_DIRECTION
#define LCD_RESET_PIN LCD_PINS_D6 // This controller need a reset pin
#define LCD_CONTRAST_MIN 0
#define LCD_CONTRAST_MAX 254
#define DEFAULT_LCD_CONTRAST 127
#define ENCODER_PULSES_PER_STEP 2
#define ENCODER_STEPS_PER_MENU_ITEM 2
#endif
// Generic support for SSD1306 / SSD1309 / SH1106 OLED based LCDs.
#if ENABLED(U8GLIB_SSD1306) || ENABLED(U8GLIB_SSD1309) || ENABLED(U8GLIB_SH1106)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for I2C LCD 128x64 (Controller SSD1306 / SSD1309 / SH1106 graphic Display Family)
#endif
#if ENABLED(PANEL_ONE) || ENABLED(U8GLIB_SH1106)
#define ULTIMAKERCONTROLLER
#elif ENABLED(MAKEBOARD_MINI_2_LINE_DISPLAY_1602)
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#define LCD_WIDTH 16
#define LCD_HEIGHT 2
#endif
#if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER) || ENABLED(LCD_FOR_MELZI) || ENABLED(SILVER_GATE_GLCD_CONTROLLER)
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if ENABLED(ULTIMAKERCONTROLLER) \
|| ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \
|| ENABLED(G3D_PANEL) \
|| ENABLED(RIGIDBOT_PANEL) \
|| ENABLED(ULTI_CONTROLLER)
#define ULTIPANEL
#endif
#if ENABLED(REPRAPWORLD_KEYPAD)
#define NEWPANEL
#if ENABLED(ULTIPANEL) && !defined(REPRAPWORLD_KEYPAD_MOVE_STEP)
#define REPRAPWORLD_KEYPAD_MOVE_STEP 1.0
#endif
#endif
/**
* I2C PANELS
*/
#if ENABLED(LCD_SAINSMART_I2C_1602) || ENABLED(LCD_SAINSMART_I2C_2004)
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTRA_LCD
#if ENABLED(LCD_SAINSMART_I2C_2004)
#define LCD_WIDTH 20
#define LCD_HEIGHT 4
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#endif
#elif ENABLED(LCD_I2C_PANELOLU2)
// Generic support for SSD1306 / SH1106 OLED based LCDs.
#if ENABLED(U8GLIB_SSD1306) || ENABLED(U8GLIB_SH1106)
#define ULTRA_LCD //general LCD support, also 16x2
#define DOGLCD // Support for I2C LCD 128x64 (Controller SSD1306 / SH1106 graphic Display Family)
#endif
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
#if ENABLED(PANEL_ONE) || ENABLED(U8GLIB_SH1106)
#define ULTIMAKERCONTROLLER
#endif
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (optional)
#define ULTIPANEL
#if ENABLED(BQ_LCD_SMART_CONTROLLER)
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
#elif ENABLED(LCD_I2C_VIKI)
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#ifndef LONG_FILENAME_HOST_SUPPORT
#define LONG_FILENAME_HOST_SUPPORT
#endif
#endif
#if ENABLED(REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER)
#define DOGLCD
#define U8GLIB_ST7920
#define REPRAP_DISCOUNT_SMART_CONTROLLER
#endif
#if ENABLED(ULTIMAKERCONTROLLER) \
|| ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER) \
|| ENABLED(G3D_PANEL) \
|| ENABLED(RIGIDBOT_PANEL) \
|| ENABLED(REPRAPWORLD_KEYPAD)
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(RA_CONTROL_PANEL)
#define LCD_I2C_TYPE_PCA8574
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
#define DOGLCD
#define U8GLIB_ST7920
#define ULTIPANEL
#define NEWPANEL
#endif
/**
* Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
*
* This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
* Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
* Note: The pause/stop/resume LCD button pin should be connected to the Arduino
* BTN_ENC pin (or set BTN_ENC to -1 if not used)
* I2C PANELS
*/
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER // Enable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define ULTIPANEL
#define ENCODER_FEEDRATE_DEADZONE 4
#if ENABLED(LCD_I2C_SAINSMART_YWROBOT)
// This uses the LiquidCrystal_I2C library ( https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home )
// Make sure it is placed in the Arduino libraries directory.
#define LCD_I2C_TYPE_PCF8575
#define LCD_I2C_ADDRESS 0x27 // I2C Address of the port expander
#define ULTIPANEL
#define NEWPANEL
#endif
#define STD_ENCODER_PULSES_PER_STEP 1
#define STD_ENCODER_STEPS_PER_MENU_ITEM 2
// PANELOLU2 LCD with status LEDs, separate encoder and click inputs
#if ENABLED(LCD_I2C_PANELOLU2)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD
#elif ENABLED(G3D_PANEL)
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 4
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#define STD_ENCODER_PULSES_PER_STEP 2
#define STD_ENCODER_STEPS_PER_MENU_ITEM 1
#define ULTIPANEL
#define NEWPANEL
#endif
#elif ENABLED(miniVIKI) || ENABLED(VIKI2) \
|| ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \
|| ENABLED(OLED_PANEL_TINYBOY2) \
|| ENABLED(BQ_LCD_SMART_CONTROLLER) \
|| ENABLED(LCD_I2C_PANELOLU2) \
|| ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
#define STD_ENCODER_PULSES_PER_STEP 4
#define STD_ENCODER_STEPS_PER_MENU_ITEM 1
#endif
// Panucatt VIKI LCD with status LEDs, integrated click & L/R/U/P buttons, separate encoder inputs
#if ENABLED(LCD_I2C_VIKI)
// This uses the LiquidTWI2 library v1.2.3 or later ( https://github.com/lincomatic/LiquidTWI2 )
// Make sure the LiquidTWI2 directory is placed in the Arduino or Sketchbook libraries subdirectory.
// Note: The pause/stop/resume LCD button pin should be connected to the Arduino
// BTN_ENC pin (or set BTN_ENC to -1 if not used)
#define LCD_I2C_TYPE_MCP23017
#define LCD_I2C_ADDRESS 0x20 // I2C Address of the port expander
#define LCD_USE_I2C_BUZZER //comment out to disable buzzer on LCD (requires LiquidTWI2 v1.2.3 or later)
#define ULTIPANEL
#define NEWPANEL
#ifndef STD_ENCODER_PULSES_PER_STEP
#define STD_ENCODER_PULSES_PER_STEP 5
#endif
#ifndef STD_ENCODER_STEPS_PER_MENU_ITEM
#define STD_ENCODER_STEPS_PER_MENU_ITEM 1
#endif
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP STD_ENCODER_PULSES_PER_STEP
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM STD_ENCODER_STEPS_PER_MENU_ITEM
#endif
#ifndef ENCODER_FEEDRATE_DEADZONE
#define ENCODER_FEEDRATE_DEADZONE 6
#endif
#define ENCODER_FEEDRATE_DEADZONE 4
// Shift register panels
// ---------------------
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
#ifndef ENCODER_PULSES_PER_STEP
#define ENCODER_PULSES_PER_STEP 1
#endif
#ifndef ENCODER_STEPS_PER_MENU_ITEM
#define ENCODER_STEPS_PER_MENU_ITEM 2
#endif
#endif
#if ENABLED(SAV_3DLCD)
#define SR_LCD_2W_NL // Non latching 2 wire shift register
#define ULTIPANEL
#endif
// Shift register panels
// ---------------------
// 2 wire Non-latching LCD SR from:
// https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/schematics#!shiftregister-connection
#if ENABLED(DOGLCD) // Change number of lines to match the DOG graphic display
#ifndef LCD_WIDTH
#ifdef LCD_WIDTH_OVERRIDE
#define LCD_WIDTH LCD_WIDTH_OVERRIDE
#else
#if ENABLED(SAV_3DLCD)
#define SR_LCD_2W_NL // Non latching 2 wire shift register
#define ULTIPANEL
#define NEWPANEL
#endif
#if ENABLED(DOGLCD) // Change number of lines to match the DOG graphic display
#ifndef LCD_WIDTH
#define LCD_WIDTH 22
#endif
#endif
#ifndef LCD_HEIGHT
#define LCD_HEIGHT 5
#endif
#endif
#if ENABLED(NO_LCD_MENUS)
#undef ULTIPANEL
#endif
#if ENABLED(ULTIPANEL)
#define NEWPANEL // Disable this if you actually have no click-encoder panel
#define ULTRA_LCD
#ifndef LCD_WIDTH
#define LCD_WIDTH 20
#endif
#ifndef LCD_HEIGHT
#define LCD_HEIGHT 4
#endif
#elif ENABLED(ULTRA_LCD) // no panel but just LCD
#ifndef LCD_WIDTH
#define LCD_WIDTH 16
#endif
#ifndef LCD_HEIGHT
#define LCD_HEIGHT 2
#endif
#endif
#if ENABLED(DOGLCD)
/* Custom characters defined in font dogm_font_data_Marlin_symbols.h / Marlin_symbols.fon */
// \x00 intentionally skipped to avoid problems in strings
#define LCD_STR_REFRESH "\x01"
#define LCD_STR_FOLDER "\x02"
#define LCD_STR_ARROW_RIGHT "\x03"
#define LCD_STR_UPLEVEL "\x04"
#define LCD_STR_CLOCK "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_BEDTEMP "\x07"
#define LCD_STR_THERMOMETER "\x08"
#define LCD_STR_DEGREE "\x09"
#define LCD_STR_SPECIAL_MAX '\x09'
// Maximum here is 0x1F because 0x20 is ' ' (space) and the normal charsets begin.
// Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here.
// Symbol characters
#define LCD_STR_FILAM_DIA "\xf8"
#define LCD_STR_FILAM_MUL "\xa4"
#else
// Custom characters defined in the first 8 characters of the LCD
#define LCD_BEDTEMP_CHAR 0x00 // Print only as a char. This will have 'unexpected' results when used in a string!
#define LCD_DEGREE_CHAR 0x01
#define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation
#define LCD_UPLEVEL_CHAR 0x03
#define LCD_STR_REFRESH "\x04"
#define LCD_STR_FOLDER "\x05"
#define LCD_FEEDRATE_CHAR 0x06
#define LCD_CLOCK_CHAR 0x07
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
#endif
/**
* Default LCD contrast for dogm-like LCD displays
*/
#if ENABLED(DOGLCD)
#define HAS_LCD_CONTRAST ( \
ENABLED(MAKRPANEL) \
|| ENABLED(CARTESIO_UI) \
|| ENABLED(VIKI2) \
|| ENABLED(miniVIKI) \
|| ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \
)
#if HAS_LCD_CONTRAST
#ifndef LCD_CONTRAST_MIN
#define LCD_CONTRAST_MIN 0
#endif
#ifndef LCD_CONTRAST_MAX
#define LCD_CONTRAST_MAX 63
#endif
#ifndef DEFAULT_LCD_CONTRAST
#define DEFAULT_LCD_CONTRAST 32
#ifndef LCD_HEIGHT
#define LCD_HEIGHT 5
#endif
#endif
#endif
// Boot screens
#if DISABLED(ULTRA_LCD)
#undef SHOW_BOOTSCREEN
#elif !defined(BOOTSCREEN_TIMEOUT)
#define BOOTSCREEN_TIMEOUT 2500
#endif
#if ENABLED(ULTIPANEL)
#define NEWPANEL //enable this if you have a click-encoder panel
#define ULTRA_LCD
#ifndef LCD_WIDTH
#define LCD_WIDTH 20
#endif
#ifndef LCD_HEIGHT
#define LCD_HEIGHT 4
#endif
#else //no panel but just LCD
#if ENABLED(ULTRA_LCD)
#ifndef LCD_WIDTH
#define LCD_WIDTH 16
#endif
#ifndef LCD_HEIGHT
#define LCD_HEIGHT 2
#endif
#endif
#endif
#define HAS_DEBUG_MENU (ENABLED(ULTIPANEL) && ENABLED(LCD_PROGRESS_BAR_TEST))
#if ENABLED(DOGLCD)
/* Custom characters defined in font dogm_font_data_Marlin_symbols.h / Marlin_symbols.fon */
// \x00 intentionally skipped to avoid problems in strings
#define LCD_STR_REFRESH "\x01"
#define LCD_STR_FOLDER "\x02"
#define LCD_STR_ARROW_RIGHT "\x03"
#define LCD_STR_UPLEVEL "\x04"
#define LCD_STR_CLOCK "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_BEDTEMP "\x07"
#define LCD_STR_THERMOMETER "\x08"
#define LCD_STR_DEGREE "\x09"
/**
* Extruders have some combination of stepper motors and hotends
* so we separate these concepts into the defines:
*
* EXTRUDERS - Number of Selectable Tools
* HOTENDS - Number of hotends, whether connected or separate
* E_STEPPERS - Number of actual E stepper motors
* E_MANUAL - Number of E steppers for LCD move options
*
*/
#if ENABLED(SWITCHING_EXTRUDER) // One stepper for every two EXTRUDERS
#if EXTRUDERS > 4
#define E_STEPPERS 3
#elif EXTRUDERS > 2
#define E_STEPPERS 2
#define LCD_STR_SPECIAL_MAX '\x09'
// Maximum here is 0x1f because 0x20 is ' ' (space) and the normal charsets begin.
// Better stay below 0x10 because DISPLAY_CHARSET_HD44780_WESTERN begins here.
#else
#define E_STEPPERS 1
/* Custom characters defined in the first 8 characters of the LCD */
#define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string!
#define LCD_STR_DEGREE "\x01"
#define LCD_STR_THERMOMETER "\x02"
#define LCD_STR_UPLEVEL "\x03"
#define LCD_STR_REFRESH "\x04"
#define LCD_STR_FOLDER "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_CLOCK "\x07"
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
#endif
#if DISABLED(SWITCHING_NOZZLE)
#define HOTENDS E_STEPPERS
/**
* Default LCD contrast for dogm-like LCD displays
*/
#if ENABLED(DOGLCD)
#define HAS_LCD_CONTRAST ( \
ENABLED(MAKRPANEL) \
|| ENABLED(CARTESIO_UI) \
|| ENABLED(VIKI2) \
|| ENABLED(miniVIKI) \
|| ENABLED(ELB_FULL_GRAPHIC_CONTROLLER) \
)
#if HAS_LCD_CONTRAST
#ifndef LCD_CONTRAST_MIN
#define LCD_CONTRAST_MIN 0
#endif
#ifndef LCD_CONTRAST_MAX
#define LCD_CONTRAST_MAX 63
#endif
#ifndef DEFAULT_LCD_CONTRAST
#define DEFAULT_LCD_CONTRAST 32
#endif
#endif
#endif
#define E_MANUAL EXTRUDERS
#elif ENABLED(MIXING_EXTRUDER)
#define E_STEPPERS MIXING_STEPPERS
#define E_MANUAL 1
#else
#define E_STEPPERS EXTRUDERS
#define E_MANUAL EXTRUDERS
#endif
// No inactive extruders with MK2_MULTIPLEXER or SWITCHING_NOZZLE
#if ENABLED(MK2_MULTIPLEXER) || ENABLED(SWITCHING_NOZZLE)
#undef DISABLE_INACTIVE_EXTRUDER
#endif
// MK2 Multiplexer forces SINGLENOZZLE
#if ENABLED(MK2_MULTIPLEXER)
#define SINGLENOZZLE
#endif
#if ENABLED(SINGLENOZZLE) || ENABLED(MIXING_EXTRUDER) // One hotend, one thermistor, no XY offset
#undef HOTENDS
#define HOTENDS 1
#undef TEMP_SENSOR_1_AS_REDUNDANT
#undef HOTEND_OFFSET_X
#undef HOTEND_OFFSET_Y
#endif
#ifndef HOTENDS
#define HOTENDS EXTRUDERS
#endif
#define DO_SWITCH_EXTRUDER (ENABLED(SWITCHING_EXTRUDER) && (DISABLED(SWITCHING_NOZZLE) || SWITCHING_EXTRUDER_SERVO_NR != SWITCHING_NOZZLE_SERVO_NR))
/**
* DISTINCT_E_FACTORS affects how some E factors are accessed
*/
#if ENABLED(DISTINCT_E_FACTORS) && E_STEPPERS > 1
#define XYZE_N (XYZ + E_STEPPERS)
#if ENABLED(HANGPRINTER)
#define NUM_AXIS_N (ABCD + E_STEPPERS)
#else
#define NUM_AXIS_N (XYZ + E_STEPPERS)
#ifndef BOOTSCREEN_TIMEOUT
#define BOOTSCREEN_TIMEOUT 2500
#endif
#define E_AXIS_N (E_AXIS + extruder)
#else
#undef DISTINCT_E_FACTORS
#define XYZE_N XYZE
#if ENABLED(HANGPRINTER)
#define NUM_AXIS_N ABCDE
#else
#define NUM_AXIS_N XYZE
/**
* Extruders have some combination of stepper motors and hotends
* so we separate these concepts into the defines:
*
* EXTRUDERS - Number of Selectable Tools
* HOTENDS - Number of hotends, whether connected or separate
* E_STEPPERS - Number of actual E stepper motors
* TOOL_E_INDEX - Index to use when getting/setting the tool state
*
*/
#if ENABLED(SINGLENOZZLE) // One hotend, multi-extruder
#define HOTENDS 1
#define E_STEPPERS EXTRUDERS
#define E_MANUAL EXTRUDERS
#define TOOL_E_INDEX current_block->active_extruder
#undef TEMP_SENSOR_1_AS_REDUNDANT
#undef HOTEND_OFFSET_X
#undef HOTEND_OFFSET_Y
#elif ENABLED(SWITCHING_EXTRUDER) // One E stepper, unified E axis, two hotends
#define HOTENDS EXTRUDERS
#define E_STEPPERS 1
#define E_MANUAL 1
#define TOOL_E_INDEX 0
#ifndef HOTEND_OFFSET_Z
#define HOTEND_OFFSET_Z { 0 }
#endif
#elif ENABLED(MIXING_EXTRUDER) // Multi-stepper, unified E axis, one hotend
#define HOTENDS 1
#define E_STEPPERS MIXING_STEPPERS
#define E_MANUAL 1
#define TOOL_E_INDEX 0
#else // One stepper, E axis, and hotend per tool
#define HOTENDS EXTRUDERS
#define E_STEPPERS EXTRUDERS
#define E_MANUAL EXTRUDERS
#define TOOL_E_INDEX current_block->active_extruder
#endif
#define E_AXIS_N E_AXIS
#endif
/**
* The BLTouch Probe emulates a servo probe
* and uses "special" angles for its state.
*/
#if ENABLED(BLTOUCH)
#ifndef Z_PROBE_SERVO_NR
#define Z_PROBE_SERVO_NR 0
#endif
#ifndef NUM_SERVOS
#define NUM_SERVOS (Z_PROBE_SERVO_NR + 1)
#endif
#undef DEACTIVATE_SERVOS_AFTER_MOVE
#if NUM_SERVOS == 1
#undef SERVO_DELAY
#define SERVO_DELAY { 50 }
#endif
#ifndef BLTOUCH_DELAY
#define BLTOUCH_DELAY 375
#endif
#undef Z_SERVO_ANGLES
#define Z_SERVO_ANGLES { BLTOUCH_DEPLOY, BLTOUCH_STOW }
#define BLTOUCH_ANGLES { BLTOUCH_DEPLOY, BLTOUCH_STOW }
#define BLTOUCH_DEPLOY 10
#define BLTOUCH_SW_MODE 60
#define BLTOUCH_STOW 90
#define BLTOUCH_SELFTEST 120
#define BLTOUCH_MODE_STORE 130
#define BLTOUCH_5V_MODE 140
#define BLTOUCH_OD_MODE 150
#define BLTOUCH_RESET 160
/**
* The following commands require different minimum delays.
*
* 500ms required for a reliable Reset.
*
* 750ms required for Deploy/Stow, otherwise the alarm state
* will not be seen until the following move command.
*/
#ifndef BLTOUCH_SET5V_DELAY
#define BLTOUCH_SET5V_DELAY 150
#endif
#ifndef BLTOUCH_SETOD_DELAY
#define BLTOUCH_SETOD_DELAY 150
#endif
#ifndef BLTOUCH_MODE_STORE_DELAY
#define BLTOUCH_MODE_STORE_DELAY 150
#endif
#ifndef BLTOUCH_DEPLOY_DELAY
#define BLTOUCH_DEPLOY_DELAY 750
#endif
#ifndef BLTOUCH_STOW_DELAY
#define BLTOUCH_STOW_DELAY 750
#endif
#ifndef BLTOUCH_RESET_DELAY
#define BLTOUCH_RESET_DELAY 500
#endif
#define _TEST_BLTOUCH(P) (READ(P##_PIN) != P##_ENDSTOP_INVERTING)
// Always disable probe pin inverting for BLTouch
#undef Z_MIN_PROBE_ENDSTOP_INVERTING
#define Z_MIN_PROBE_ENDSTOP_INVERTING false
#if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
#undef Z_MIN_ENDSTOP_INVERTING
#define Z_MIN_ENDSTOP_INVERTING Z_MIN_PROBE_ENDSTOP_INVERTING
#define TEST_BLTOUCH() _TEST_BLTOUCH(Z_MIN)
#else
#define TEST_BLTOUCH() _TEST_BLTOUCH(Z_MIN_PROBE)
#endif
#endif
/**
* Set a flag for a servo probe
*/
#define HAS_Z_SERVO_PROBE (defined(Z_PROBE_SERVO_NR) && Z_PROBE_SERVO_NR >= 0)
/**
* Set flags for enabled probes
*/
#define HAS_BED_PROBE (ENABLED(FIX_MOUNTED_PROBE) || ENABLED(Z_PROBE_ALLEN_KEY) || HAS_Z_SERVO_PROBE || ENABLED(Z_PROBE_SLED) || ENABLED(SOLENOID_PROBE))
#define PROBE_SELECTED (HAS_BED_PROBE || ENABLED(PROBE_MANUALLY) || ENABLED(MESH_BED_LEVELING))
#if !HAS_BED_PROBE
// Clear probe pin settings when no probe is selected
#undef Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN
#undef Z_MIN_PROBE_ENDSTOP
#elif ENABLED(Z_PROBE_ALLEN_KEY)
// Extra test for Allen Key Probe
#define PROBE_IS_TRIGGERED_WHEN_STOWED_TEST
#endif
#define HOMING_Z_WITH_PROBE (HAS_BED_PROBE && Z_HOME_DIR < 0 && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN))
#define HAS_SOFTWARE_ENDSTOPS (ENABLED(MIN_SOFTWARE_ENDSTOPS) || ENABLED(MAX_SOFTWARE_ENDSTOPS))
#define HAS_RESUME_CONTINUE (ENABLED(NEWPANEL) || ENABLED(EMERGENCY_PARSER))
#define HAS_COLOR_LEDS (ENABLED(BLINKM) || ENABLED(RGB_LED) || ENABLED(RGBW_LED) || ENABLED(PCA9632) || ENABLED(NEOPIXEL_LED))
#define USE_MARLINSERIAL !(defined(__AVR__) && defined(USBCON))
#endif // CONDITIONALS_LCD_H
#endif //CONDITIONALS_LCD_H

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,920 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Marlin Firmware -- G26 - Mesh Validation Tool
*/
#include "MarlinConfig.h"
#if ENABLED(G26_MESH_VALIDATION)
#include "Marlin.h"
#include "planner.h"
#include "stepper.h"
#include "temperature.h"
#include "ultralcd.h"
#include "parser.h"
#include "serial.h"
#include "bitmap_flags.h"
#if ENABLED(MESH_BED_LEVELING)
#include "mesh_bed_leveling.h"
#elif ENABLED(AUTO_BED_LEVELING_UBL)
#include "ubl.h"
#endif
#define EXTRUSION_MULTIPLIER 1.0
#define RETRACTION_MULTIPLIER 1.0
#define PRIME_LENGTH 10.0
#define OOZE_AMOUNT 0.3
#define INTERSECTION_CIRCLE_RADIUS 5
#define CROSSHAIRS_SIZE 3
#if CROSSHAIRS_SIZE >= INTERSECTION_CIRCLE_RADIUS
#error "CROSSHAIRS_SIZE must be less than INTERSECTION_CIRCLE_RADIUS."
#endif
#define G26_OK false
#define G26_ERR true
/**
* G26 Mesh Validation Tool
*
* G26 is a Mesh Validation Tool intended to provide support for the Marlin Unified Bed Leveling System.
* In order to fully utilize and benefit from the Marlin Unified Bed Leveling System an accurate Mesh must
* be defined. G29 is designed to allow the user to quickly validate the correctness of her Mesh. It will
* first heat the bed and nozzle. It will then print lines and circles along the Mesh Cell boundaries and
* the intersections of those lines (respectively).
*
* This action allows the user to immediately see where the Mesh is properly defined and where it needs to
* be edited. The command will generate the Mesh lines closest to the nozzle's starting position. Alternatively
* the user can specify the X and Y position of interest with command parameters. This allows the user to
* focus on a particular area of the Mesh where attention is needed.
*
* B # Bed Set the Bed Temperature. If not specified, a default of 60 C. will be assumed.
*
* C Current When searching for Mesh Intersection points to draw, use the current nozzle location
* as the base for any distance comparison.
*
* D Disable Disable the Unified Bed Leveling System. In the normal case the user is invoking this
* command to see how well a Mesh as been adjusted to match a print surface. In order to do
* this the Unified Bed Leveling System is turned on by the G26 command. The D parameter
* alters the command's normal behaviour and disables the Unified Bed Leveling System even if
* it is on.
*
* H # Hotend Set the Nozzle Temperature. If not specified, a default of 205 C. will be assumed.
*
* F # Filament Used to specify the diameter of the filament being used. If not specified
* 1.75mm filament is assumed. If you are not getting acceptable results by using the
* 'correct' numbers, you can scale this number up or down a little bit to change the amount
* of filament that is being extruded during the printing of the various lines on the bed.
*
* K Keep-On Keep the heaters turned on at the end of the command.
*
* L # Layer Layer height. (Height of nozzle above bed) If not specified .20mm will be used.
*
* O # Ooooze How much your nozzle will Ooooze filament while getting in position to print. This
* is over kill, but using this parameter will let you get the very first 'circle' perfect
* so you have a trophy to peel off of the bed and hang up to show how perfectly you have your
* Mesh calibrated. If not specified, a filament length of .3mm is assumed.
*
* P # Prime Prime the nozzle with specified length of filament. If this parameter is not
* given, no prime action will take place. If the parameter specifies an amount, that much
* will be purged before continuing. If no amount is specified the command will start
* purging filament until the user provides an LCD Click and then it will continue with
* printing the Mesh. You can carefully remove the spent filament with a needle nose
* pliers while holding the LCD Click wheel in a depressed state. If you do not have
* an LCD, you must specify a value if you use P.
*
* Q # Multiplier Retraction Multiplier. Normally not needed. Retraction defaults to 1.0mm and
* un-retraction is at 1.2mm These numbers will be scaled by the specified amount
*
* R # Repeat Prints the number of patterns given as a parameter, starting at the current location.
* If a parameter isn't given, every point will be printed unless G26 is interrupted.
* This works the same way that the UBL G29 P4 R parameter works.
*
* NOTE: If you do not have an LCD, you -must- specify R. This is to ensure that you are
* aware that there's some risk associated with printing without the ability to abort in
* cases where mesh point Z value may be inaccurate. As above, if you do not include a
* parameter, every point will be printed.
*
* S # Nozzle Used to control the size of nozzle diameter. If not specified, a .4mm nozzle is assumed.
*
* U # Random Randomize the order that the circles are drawn on the bed. The search for the closest
* undrawn cicle is still done. But the distance to the location for each circle has a
* random number of the size specified added to it. Specifying S50 will give an interesting
* deviation from the normal behaviour on a 10 x 10 Mesh.
*
* X # X Coord. Specify the starting location of the drawing activity.
*
* Y # Y Coord. Specify the starting location of the drawing activity.
*/
// External references
extern Planner planner;
// Private functions
static uint16_t circle_flags[16], horizontal_mesh_line_flags[16], vertical_mesh_line_flags[16];
float g26_e_axis_feedrate = 0.025,
random_deviation = 0.0;
static bool g26_retracted = false; // Track the retracted state of the nozzle so mismatched
// retracts/recovers won't result in a bad state.
static float g26_extrusion_multiplier,
g26_retraction_multiplier,
g26_layer_height,
g26_prime_length,
g26_x_pos, g26_y_pos;
static int16_t g26_bed_temp,
g26_hotend_temp;
static int8_t g26_prime_flag;
#if ENABLED(ULTIPANEL)
/**
* If the LCD is clicked, cancel, wait for release, return true
*/
bool user_canceled() {
if (!is_lcd_clicked()) return false; // Return if the button isn't pressed
lcd_setstatusPGM(PSTR("Mesh Validation Stopped."), 99);
#if ENABLED(ULTIPANEL)
lcd_quick_feedback(true);
#endif
wait_for_release();
return true;
}
bool exit_from_g26() {
lcd_setstatusPGM(PSTR("Leaving G26"), -1);
wait_for_release();
return G26_ERR;
}
#endif
void G26_line_to_destination(const float &feed_rate) {
const float save_feedrate = feedrate_mm_s;
feedrate_mm_s = feed_rate;
prepare_move_to_destination(); // will ultimately call ubl.line_to_destination_cartesian or ubl.prepare_linear_move_to for UBL_SEGMENTED
feedrate_mm_s = save_feedrate;
}
void move_to(const float &rx, const float &ry, const float &z, const float &e_delta) {
float feed_value;
static float last_z = -999.99;
bool has_xy_component = (rx != current_position[X_AXIS] || ry != current_position[Y_AXIS]); // Check if X or Y is involved in the movement.
if (z != last_z) {
last_z = z;
feed_value = planner.max_feedrate_mm_s[Z_AXIS]/(3.0); // Base the feed rate off of the configured Z_AXIS feed rate
destination[X_AXIS] = current_position[X_AXIS];
destination[Y_AXIS] = current_position[Y_AXIS];
destination[Z_AXIS] = z; // We know the last_z==z or we wouldn't be in this block of code.
destination[E_CART] = current_position[E_CART];
G26_line_to_destination(feed_value);
set_destination_from_current();
}
// Check if X or Y is involved in the movement.
// Yes: a 'normal' movement. No: a retract() or recover()
feed_value = has_xy_component ? PLANNER_XY_FEEDRATE() / 10.0 : planner.max_feedrate_mm_s[E_AXIS] / 1.5;
if (g26_debug_flag) SERIAL_ECHOLNPAIR("in move_to() feed_value for XY:", feed_value);
destination[X_AXIS] = rx;
destination[Y_AXIS] = ry;
destination[E_CART] += e_delta;
G26_line_to_destination(feed_value);
set_destination_from_current();
}
FORCE_INLINE void move_to(const float where[XYZE], const float &de) { move_to(where[X_AXIS], where[Y_AXIS], where[Z_AXIS], de); }
void retract_filament(const float where[XYZE]) {
if (!g26_retracted) { // Only retract if we are not already retracted!
g26_retracted = true;
move_to(where, -1.0 * g26_retraction_multiplier);
}
}
void recover_filament(const float where[XYZE]) {
if (g26_retracted) { // Only un-retract if we are retracted.
move_to(where, 1.2 * g26_retraction_multiplier);
g26_retracted = false;
}
}
/**
* Prime the nozzle if needed. Return true on error.
*/
inline bool prime_nozzle() {
#if ENABLED(ULTIPANEL)
float Total_Prime = 0.0;
if (g26_prime_flag == -1) { // The user wants to control how much filament gets purged
lcd_external_control = true;
lcd_setstatusPGM(PSTR("User-Controlled Prime"), 99);
lcd_chirp();
set_destination_from_current();
recover_filament(destination); // Make sure G26 doesn't think the filament is retracted().
while (!is_lcd_clicked()) {
lcd_chirp();
destination[E_CART] += 0.25;
#ifdef PREVENT_LENGTHY_EXTRUDE
Total_Prime += 0.25;
if (Total_Prime >= EXTRUDE_MAXLENGTH) return G26_ERR;
#endif
G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
set_destination_from_current();
planner.synchronize(); // Without this synchronize, the purge is more consistent,
// but because the planner has a buffer, we won't be able
// to stop as quickly. So we put up with the less smooth
// action to give the user a more responsive 'Stop'.
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
}
wait_for_release();
lcd_setstatusPGM(PSTR("Done Priming"), 99);
lcd_quick_feedback(true);
lcd_external_control = false;
}
else
#endif
{
#if ENABLED(ULTRA_LCD)
lcd_setstatusPGM(PSTR("Fixed Length Prime."), 99);
lcd_quick_feedback(true);
#endif
set_destination_from_current();
destination[E_CART] += g26_prime_length;
G26_line_to_destination(planner.max_feedrate_mm_s[E_AXIS] / 15.0);
set_destination_from_current();
retract_filament(destination);
}
return G26_OK;
}
mesh_index_pair find_closest_circle_to_print(const float &X, const float &Y) {
float closest = 99999.99;
mesh_index_pair return_val;
return_val.x_index = return_val.y_index = -1;
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
if (!is_bitmap_set(circle_flags, i, j)) {
const float mx = _GET_MESH_X(i), // We found a circle that needs to be printed
my = _GET_MESH_Y(j);
// Get the distance to this intersection
float f = HYPOT(X - mx, Y - my);
// It is possible that we are being called with the values
// to let us find the closest circle to the start position.
// But if this is not the case, add a small weighting to the
// distance calculation to help it choose a better place to continue.
f += HYPOT(g26_x_pos - mx, g26_y_pos - my) / 15.0;
// Add in the specified amount of Random Noise to our search
if (random_deviation > 1.0)
f += random(0.0, random_deviation);
if (f < closest) {
closest = f; // We found a closer location that is still
return_val.x_index = i; // un-printed --- save the data for it
return_val.y_index = j;
return_val.distance = closest;
}
}
}
}
bitmap_set(circle_flags, return_val.x_index, return_val.y_index); // Mark this location as done.
return return_val;
}
/**
* print_line_from_here_to_there() takes two cartesian coordinates and draws a line from one
* to the other. But there are really three sets of coordinates involved. The first coordinate
* is the present location of the nozzle. We don't necessarily want to print from this location.
* We first need to move the nozzle to the start of line segment where we want to print. Once
* there, we can use the two coordinates supplied to draw the line.
*
* Note: Although we assume the first set of coordinates is the start of the line and the second
* set of coordinates is the end of the line, it does not always work out that way. This function
* optimizes the movement to minimize the travel distance before it can start printing. This saves
* a lot of time and eliminates a lot of nonsensical movement of the nozzle. However, it does
* cause a lot of very little short retracement of th nozzle when it draws the very first line
* segment of a 'circle'. The time this requires is very short and is easily saved by the other
* cases where the optimization comes into play.
*/
void print_line_from_here_to_there(const float &sx, const float &sy, const float &sz, const float &ex, const float &ey, const float &ez) {
const float dx_s = current_position[X_AXIS] - sx, // find our distance from the start of the actual line segment
dy_s = current_position[Y_AXIS] - sy,
dist_start = HYPOT2(dx_s, dy_s), // We don't need to do a sqrt(), we can compare the distance^2
// to save computation time
dx_e = current_position[X_AXIS] - ex, // find our distance from the end of the actual line segment
dy_e = current_position[Y_AXIS] - ey,
dist_end = HYPOT2(dx_e, dy_e),
line_length = HYPOT(ex - sx, ey - sy);
// If the end point of the line is closer to the nozzle, flip the direction,
// moving from the end to the start. On very small lines the optimization isn't worth it.
if (dist_end < dist_start && (INTERSECTION_CIRCLE_RADIUS) < ABS(line_length))
return print_line_from_here_to_there(ex, ey, ez, sx, sy, sz);
// Decide whether to retract & bump
if (dist_start > 2.0) {
retract_filament(destination);
//todo: parameterize the bump height with a define
move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + 0.500, 0.0); // Z bump to minimize scraping
move_to(sx, sy, sz + 0.500, 0.0); // Get to the starting point with no extrusion while bumped
}
move_to(sx, sy, sz, 0.0); // Get to the starting point with no extrusion / un-Z bump
const float e_pos_delta = line_length * g26_e_axis_feedrate * g26_extrusion_multiplier;
recover_filament(destination);
move_to(ex, ey, ez, e_pos_delta); // Get to the ending point with an appropriate amount of extrusion
}
inline bool look_for_lines_to_connect() {
float sx, sy, ex, ey;
for (uint8_t i = 0; i < GRID_MAX_POINTS_X; i++) {
for (uint8_t j = 0; j < GRID_MAX_POINTS_Y; j++) {
#if ENABLED(ULTIPANEL)
if (user_canceled()) return true; // Check if the user wants to stop the Mesh Validation
#endif
if (i < GRID_MAX_POINTS_X) { // We can't connect to anything to the right than GRID_MAX_POINTS_X.
// This is already a half circle because we are at the edge of the bed.
if (is_bitmap_set(circle_flags, i, j) && is_bitmap_set(circle_flags, i + 1, j)) { // check if we can do a line to the left
if (!is_bitmap_set(horizontal_mesh_line_flags, i, j)) {
//
// We found two circles that need a horizontal line to connect them
// Print it!
//
sx = _GET_MESH_X( i ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // right edge
ex = _GET_MESH_X(i + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // left edge
sx = constrain(sx, X_MIN_POS + 1, X_MAX_POS - 1);
sy = ey = constrain(_GET_MESH_Y(j), Y_MIN_POS + 1, Y_MAX_POS - 1);
ex = constrain(ex, X_MIN_POS + 1, X_MAX_POS - 1);
if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) {
if (g26_debug_flag) {
SERIAL_ECHOPAIR(" Connecting with horizontal line (sx=", sx);
SERIAL_ECHOPAIR(", sy=", sy);
SERIAL_ECHOPAIR(") -> (ex=", ex);
SERIAL_ECHOPAIR(", ey=", ey);
SERIAL_CHAR(')');
SERIAL_EOL();
//debug_current_and_destination(PSTR("Connecting horizontal line."));
}
print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
}
bitmap_set(horizontal_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if we skipped it
}
}
if (j < GRID_MAX_POINTS_Y) { // We can't connect to anything further back than GRID_MAX_POINTS_Y.
// This is already a half circle because we are at the edge of the bed.
if (is_bitmap_set(circle_flags, i, j) && is_bitmap_set(circle_flags, i, j + 1)) { // check if we can do a line straight down
if (!is_bitmap_set( vertical_mesh_line_flags, i, j)) {
//
// We found two circles that need a vertical line to connect them
// Print it!
//
sy = _GET_MESH_Y( j ) + (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // top edge
ey = _GET_MESH_Y(j + 1) - (INTERSECTION_CIRCLE_RADIUS - (CROSSHAIRS_SIZE)); // bottom edge
sx = ex = constrain(_GET_MESH_X(i), X_MIN_POS + 1, X_MAX_POS - 1);
sy = constrain(sy, Y_MIN_POS + 1, Y_MAX_POS - 1);
ey = constrain(ey, Y_MIN_POS + 1, Y_MAX_POS - 1);
if (position_is_reachable(sx, sy) && position_is_reachable(ex, ey)) {
if (g26_debug_flag) {
SERIAL_ECHOPAIR(" Connecting with vertical line (sx=", sx);
SERIAL_ECHOPAIR(", sy=", sy);
SERIAL_ECHOPAIR(") -> (ex=", ex);
SERIAL_ECHOPAIR(", ey=", ey);
SERIAL_CHAR(')');
SERIAL_EOL();
#if ENABLED(AUTO_BED_LEVELING_UBL)
debug_current_and_destination(PSTR("Connecting vertical line."));
#endif
}
print_line_from_here_to_there(sx, sy, g26_layer_height, ex, ey, g26_layer_height);
}
bitmap_set(vertical_mesh_line_flags, i, j); // Mark it as done so we don't do it again, even if skipped
}
}
}
}
}
}
return false;
}
/**
* Turn on the bed and nozzle heat and
* wait for them to get up to temperature.
*/
inline bool turn_on_heaters() {
millis_t next = millis() + 5000UL;
#if HAS_HEATED_BED
#if ENABLED(ULTRA_LCD)
if (g26_bed_temp > 25) {
lcd_setstatusPGM(PSTR("G26 Heating Bed."), 99);
lcd_quick_feedback(true);
#if ENABLED(ULTIPANEL)
lcd_external_control = true;
#endif
#endif
thermalManager.setTargetBed(g26_bed_temp);
while (ABS(thermalManager.degBed() - g26_bed_temp) > 3) {
#if ENABLED(ULTIPANEL)
if (is_lcd_clicked()) return exit_from_g26();
#endif
if (ELAPSED(millis(), next)) {
next = millis() + 5000UL;
thermalManager.print_heaterstates();
SERIAL_EOL();
}
idle();
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
}
#if ENABLED(ULTRA_LCD)
}
lcd_setstatusPGM(PSTR("G26 Heating Nozzle."), 99);
lcd_quick_feedback(true);
#endif
#endif
// Start heating the nozzle and wait for it to reach temperature.
thermalManager.setTargetHotend(g26_hotend_temp, 0);
while (ABS(thermalManager.degHotend(0) - g26_hotend_temp) > 3) {
#if ENABLED(ULTIPANEL)
if (is_lcd_clicked()) return exit_from_g26();
#endif
if (ELAPSED(millis(), next)) {
next = millis() + 5000UL;
thermalManager.print_heaterstates();
SERIAL_EOL();
}
idle();
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
}
#if ENABLED(ULTRA_LCD)
lcd_reset_status();
lcd_quick_feedback(true);
#endif
return G26_OK;
}
float valid_trig_angle(float d) {
while (d > 360.0) d -= 360.0;
while (d < 0.0) d += 360.0;
return d;
}
/**
* G26: Mesh Validation Pattern generation.
*
* Used to interactively edit the mesh by placing the
* nozzle in a problem area and doing a G29 P4 R command.
*
* Parameters:
*
* B Bed Temperature
* C Continue from the Closest mesh point
* D Disable leveling before starting
* F Filament diameter
* H Hotend Temperature
* K Keep heaters on when completed
* L Layer Height
* O Ooze extrusion length
* P Prime length
* Q Retraction multiplier
* R Repetitions (number of grid points)
* S Nozzle Size (diameter) in mm
* U Random deviation (50 if no value given)
* X X position
* Y Y position
*/
void gcode_G26() {
SERIAL_ECHOLNPGM("G26 command started. Waiting for heater(s).");
// Don't allow Mesh Validation without homing first,
// or if the parameter parsing did not go OK, abort
if (axis_unhomed_error()) return;
g26_extrusion_multiplier = EXTRUSION_MULTIPLIER;
g26_retraction_multiplier = RETRACTION_MULTIPLIER;
g26_layer_height = MESH_TEST_LAYER_HEIGHT;
g26_prime_length = PRIME_LENGTH;
g26_bed_temp = MESH_TEST_BED_TEMP;
g26_hotend_temp = MESH_TEST_HOTEND_TEMP;
g26_prime_flag = 0;
float g26_nozzle = MESH_TEST_NOZZLE_SIZE,
g26_filament_diameter = DEFAULT_NOMINAL_FILAMENT_DIA,
g26_ooze_amount = parser.linearval('O', OOZE_AMOUNT);
bool g26_continue_with_closest = parser.boolval('C'),
g26_keep_heaters_on = parser.boolval('K');
if (parser.seenval('B')) {
g26_bed_temp = parser.value_celsius();
if (g26_bed_temp && !WITHIN(g26_bed_temp, 40, 140)) {
SERIAL_PROTOCOLLNPGM("?Specified bed temperature not plausible (40-140C).");
return;
}
}
if (parser.seenval('L')) {
g26_layer_height = parser.value_linear_units();
if (!WITHIN(g26_layer_height, 0.0, 2.0)) {
SERIAL_PROTOCOLLNPGM("?Specified layer height not plausible.");
return;
}
}
if (parser.seen('Q')) {
if (parser.has_value()) {
g26_retraction_multiplier = parser.value_float();
if (!WITHIN(g26_retraction_multiplier, 0.05, 15.0)) {
SERIAL_PROTOCOLLNPGM("?Specified Retraction Multiplier not plausible.");
return;
}
}
else {
SERIAL_PROTOCOLLNPGM("?Retraction Multiplier must be specified.");
return;
}
}
if (parser.seenval('S')) {
g26_nozzle = parser.value_float();
if (!WITHIN(g26_nozzle, 0.1, 1.0)) {
SERIAL_PROTOCOLLNPGM("?Specified nozzle size not plausible.");
return;
}
}
if (parser.seen('P')) {
if (!parser.has_value()) {
#if ENABLED(ULTIPANEL)
g26_prime_flag = -1;
#else
SERIAL_PROTOCOLLNPGM("?Prime length must be specified when not using an LCD.");
return;
#endif
}
else {
g26_prime_flag++;
g26_prime_length = parser.value_linear_units();
if (!WITHIN(g26_prime_length, 0.0, 25.0)) {
SERIAL_PROTOCOLLNPGM("?Specified prime length not plausible.");
return;
}
}
}
if (parser.seenval('F')) {
g26_filament_diameter = parser.value_linear_units();
if (!WITHIN(g26_filament_diameter, 1.0, 4.0)) {
SERIAL_PROTOCOLLNPGM("?Specified filament size not plausible.");
return;
}
}
g26_extrusion_multiplier *= sq(1.75) / sq(g26_filament_diameter); // If we aren't using 1.75mm filament, we need to
// scale up or down the length needed to get the
// same volume of filament
g26_extrusion_multiplier *= g26_filament_diameter * sq(g26_nozzle) / sq(0.3); // Scale up by nozzle size
if (parser.seenval('H')) {
g26_hotend_temp = parser.value_celsius();
if (!WITHIN(g26_hotend_temp, 165, 280)) {
SERIAL_PROTOCOLLNPGM("?Specified nozzle temperature not plausible.");
return;
}
}
if (parser.seen('U')) {
randomSeed(millis());
// This setting will persist for the next G26
random_deviation = parser.has_value() ? parser.value_float() : 50.0;
}
int16_t g26_repeats;
#if ENABLED(ULTIPANEL)
g26_repeats = parser.intval('R', GRID_MAX_POINTS + 1);
#else
if (!parser.seen('R')) {
SERIAL_PROTOCOLLNPGM("?(R)epeat must be specified when not using an LCD.");
return;
}
else
g26_repeats = parser.has_value() ? parser.value_int() : GRID_MAX_POINTS + 1;
#endif
if (g26_repeats < 1) {
SERIAL_PROTOCOLLNPGM("?(R)epeat value not plausible; must be at least 1.");
return;
}
g26_x_pos = parser.seenval('X') ? RAW_X_POSITION(parser.value_linear_units()) : current_position[X_AXIS];
g26_y_pos = parser.seenval('Y') ? RAW_Y_POSITION(parser.value_linear_units()) : current_position[Y_AXIS];
if (!position_is_reachable(g26_x_pos, g26_y_pos)) {
SERIAL_PROTOCOLLNPGM("?Specified X,Y coordinate out of bounds.");
return;
}
/**
* Wait until all parameters are verified before altering the state!
*/
set_bed_leveling_enabled(!parser.seen('D'));
if (current_position[Z_AXIS] < Z_CLEARANCE_BETWEEN_PROBES) {
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
set_current_from_destination();
}
if (turn_on_heaters() != G26_OK) goto LEAVE;
current_position[E_CART] = 0.0;
sync_plan_position_e();
if (g26_prime_flag && prime_nozzle() != G26_OK) goto LEAVE;
/**
* Bed is preheated
*
* Nozzle is at temperature
*
* Filament is primed!
*
* It's "Show Time" !!!
*/
ZERO(circle_flags);
ZERO(horizontal_mesh_line_flags);
ZERO(vertical_mesh_line_flags);
// Move nozzle to the specified height for the first layer
set_destination_from_current();
destination[Z_AXIS] = g26_layer_height;
move_to(destination, 0.0);
move_to(destination, g26_ooze_amount);
#if ENABLED(ULTIPANEL)
lcd_external_control = true;
#endif
//debug_current_and_destination(PSTR("Starting G26 Mesh Validation Pattern."));
#if DISABLED(ARC_SUPPORT)
/**
* Pre-generate radius offset values at 30 degree intervals to reduce CPU load.
*/
#define A_INT 30
#define _ANGS (360 / A_INT)
#define A_CNT (_ANGS / 2)
#define _IND(A) ((A + _ANGS * 8) % _ANGS)
#define _COS(A) (trig_table[_IND(A) % A_CNT] * (_IND(A) >= A_CNT ? -1 : 1))
#define _SIN(A) (-_COS((A + A_CNT / 2) % _ANGS))
#if A_CNT & 1
#error "A_CNT must be a positive value. Please change A_INT."
#endif
float trig_table[A_CNT];
for (uint8_t i = 0; i < A_CNT; i++)
trig_table[i] = INTERSECTION_CIRCLE_RADIUS * cos(RADIANS(i * A_INT));
#endif // !ARC_SUPPORT
mesh_index_pair location;
do {
location = g26_continue_with_closest
? find_closest_circle_to_print(current_position[X_AXIS], current_position[Y_AXIS])
: find_closest_circle_to_print(g26_x_pos, g26_y_pos); // Find the closest Mesh Intersection to where we are now.
if (location.x_index >= 0 && location.y_index >= 0) {
const float circle_x = _GET_MESH_X(location.x_index),
circle_y = _GET_MESH_Y(location.y_index);
// If this mesh location is outside the printable_radius, skip it.
if (!position_is_reachable(circle_x, circle_y)) continue;
// Determine where to start and end the circle,
// which is always drawn counter-clockwise.
const uint8_t xi = location.x_index, yi = location.y_index;
const bool f = yi == 0, r = xi >= GRID_MAX_POINTS_X - 1, b = yi >= GRID_MAX_POINTS_Y - 1;
#if ENABLED(ARC_SUPPORT)
#define ARC_LENGTH(quarters) (INTERSECTION_CIRCLE_RADIUS * M_PI * (quarters) / 2)
float sx = circle_x + INTERSECTION_CIRCLE_RADIUS, // default to full circle
ex = circle_x + INTERSECTION_CIRCLE_RADIUS,
sy = circle_y, ey = circle_y,
arc_length = ARC_LENGTH(4);
// Figure out where to start and end the arc - we always print counterclockwise
if (xi == 0) { // left edge
sx = f ? circle_x + INTERSECTION_CIRCLE_RADIUS : circle_x;
ex = b ? circle_x + INTERSECTION_CIRCLE_RADIUS : circle_x;
sy = f ? circle_y : circle_y - INTERSECTION_CIRCLE_RADIUS;
ey = b ? circle_y : circle_y + INTERSECTION_CIRCLE_RADIUS;
arc_length = (f || b) ? ARC_LENGTH(1) : ARC_LENGTH(2);
}
else if (r) { // right edge
sx = b ? circle_x - INTERSECTION_CIRCLE_RADIUS : circle_x;
ex = f ? circle_x - INTERSECTION_CIRCLE_RADIUS : circle_x;
sy = b ? circle_y : circle_y + INTERSECTION_CIRCLE_RADIUS;
ey = f ? circle_y : circle_y - INTERSECTION_CIRCLE_RADIUS;
arc_length = (f || b) ? ARC_LENGTH(1) : ARC_LENGTH(2);
}
else if (f) {
sx = circle_x + INTERSECTION_CIRCLE_RADIUS;
ex = circle_x - INTERSECTION_CIRCLE_RADIUS;
sy = ey = circle_y;
arc_length = ARC_LENGTH(2);
}
else if (b) {
sx = circle_x - INTERSECTION_CIRCLE_RADIUS;
ex = circle_x + INTERSECTION_CIRCLE_RADIUS;
sy = ey = circle_y;
arc_length = ARC_LENGTH(2);
}
const float arc_offset[2] = {
circle_x - sx,
circle_y - sy
};
const float dx_s = current_position[X_AXIS] - sx, // find our distance from the start of the actual circle
dy_s = current_position[Y_AXIS] - sy,
dist_start = HYPOT2(dx_s, dy_s);
const float endpoint[XYZE] = {
ex, ey,
g26_layer_height,
current_position[E_CART] + (arc_length * g26_e_axis_feedrate * g26_extrusion_multiplier)
};
if (dist_start > 2.0) {
retract_filament(destination);
//todo: parameterize the bump height with a define
move_to(current_position[X_AXIS], current_position[Y_AXIS], current_position[Z_AXIS] + 0.500, 0.0); // Z bump to minimize scraping
move_to(sx, sy, g26_layer_height + 0.500, 0.0); // Get to the starting point with no extrusion while bumped
}
move_to(sx, sy, g26_layer_height, 0.0); // Get to the starting point with no extrusion / un-Z bump
recover_filament(destination);
const float save_feedrate = feedrate_mm_s;
feedrate_mm_s = PLANNER_XY_FEEDRATE() / 10.0;
plan_arc(endpoint, arc_offset, false); // Draw a counter-clockwise arc
feedrate_mm_s = save_feedrate;
set_destination_from_current();
#if ENABLED(ULTIPANEL)
if (user_canceled()) goto LEAVE; // Check if the user wants to stop the Mesh Validation
#endif
#else // !ARC_SUPPORT
int8_t start_ind = -2, end_ind = 9; // Assume a full circle (from 5:00 to 5:00)
if (xi == 0) { // Left edge? Just right half.
start_ind = f ? 0 : -3; // 03:00 to 12:00 for front-left
end_ind = b ? 0 : 2; // 06:00 to 03:00 for back-left
}
else if (r) { // Right edge? Just left half.
start_ind = b ? 6 : 3; // 12:00 to 09:00 for front-right
end_ind = f ? 5 : 8; // 09:00 to 06:00 for back-right
}
else if (f) { // Front edge? Just back half.
start_ind = 0; // 03:00
end_ind = 5; // 09:00
}
else if (b) { // Back edge? Just front half.
start_ind = 6; // 09:00
end_ind = 11; // 03:00
}
for (int8_t ind = start_ind; ind <= end_ind; ind++) {
#if ENABLED(ULTIPANEL)
if (user_canceled()) goto LEAVE; // Check if the user wants to stop the Mesh Validation
#endif
float rx = circle_x + _COS(ind), // For speed, these are now a lookup table entry
ry = circle_y + _SIN(ind),
xe = circle_x + _COS(ind + 1),
ye = circle_y + _SIN(ind + 1);
#if IS_KINEMATIC
// Check to make sure this segment is entirely on the bed, skip if not.
if (!position_is_reachable(rx, ry) || !position_is_reachable(xe, ye)) continue;
#else // not, we need to skip
rx = constrain(rx, X_MIN_POS + 1, X_MAX_POS - 1); // This keeps us from bumping the endstops
ry = constrain(ry, Y_MIN_POS + 1, Y_MAX_POS - 1);
xe = constrain(xe, X_MIN_POS + 1, X_MAX_POS - 1);
ye = constrain(ye, Y_MIN_POS + 1, Y_MAX_POS - 1);
#endif
print_line_from_here_to_there(rx, ry, g26_layer_height, xe, ye, g26_layer_height);
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
}
#endif // !ARC_SUPPORT
if (look_for_lines_to_connect()) goto LEAVE;
}
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
} while (--g26_repeats && location.x_index >= 0 && location.y_index >= 0);
LEAVE:
lcd_setstatusPGM(PSTR("Leaving G26"), -1);
retract_filament(destination);
destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES;
//debug_current_and_destination(PSTR("ready to do Z-Raise."));
move_to(destination, 0); // Raise the nozzle
//debug_current_and_destination(PSTR("done doing Z-Raise."));
destination[X_AXIS] = g26_x_pos; // Move back to the starting position
destination[Y_AXIS] = g26_y_pos;
//destination[Z_AXIS] = Z_CLEARANCE_BETWEEN_PROBES; // Keep the nozzle where it is
move_to(destination, 0); // Move back to the starting position
//debug_current_and_destination(PSTR("done doing X/Y move."));
#if ENABLED(ULTIPANEL)
lcd_external_control = false; // Give back control of the LCD Panel!
#endif
if (!g26_keep_heaters_on) {
#if HAS_HEATED_BED
thermalManager.setTargetBed(0);
#endif
thermalManager.setTargetHotend(0, 0);
}
}
#endif // G26_MESH_VALIDATION

View File

@@ -1,337 +0,0 @@
/* **************************************************************************
Marlin 3D Printer Firmware
Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
/**
* Description: HAL for __AVR__
*/
#ifndef _HAL_AVR_H_
#define _HAL_AVR_H_
// --------------------------------------------------------------------------
// Includes
// --------------------------------------------------------------------------
#include "fastio.h"
#include <stdint.h>
#include <Arduino.h>
#include <util/delay.h>
#include <avr/eeprom.h>
#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include <avr/io.h>
// --------------------------------------------------------------------------
// Defines
// --------------------------------------------------------------------------
//#define analogInputToDigitalPin(IO) IO
// Bracket code that shouldn't be interrupted
#ifndef CRITICAL_SECTION_START
#define CRITICAL_SECTION_START unsigned char _sreg = SREG; cli()
#define CRITICAL_SECTION_END SREG = _sreg
#endif
#define ISRS_ENABLED() TEST(SREG, SREG_I)
#define ENABLE_ISRS() sei()
#define DISABLE_ISRS() cli()
// --------------------------------------------------------------------------
// Types
// --------------------------------------------------------------------------
typedef uint16_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFF
typedef int8_t pin_t;
#define HAL_SERVO_LIB Servo
// --------------------------------------------------------------------------
// Public Variables
// --------------------------------------------------------------------------
//extern uint8_t MCUSR;
// --------------------------------------------------------------------------
// Public functions
// --------------------------------------------------------------------------
//void cli(void);
//void _delay_ms(const int delay);
inline void HAL_clear_reset_source(void) { MCUSR = 0; }
inline uint8_t HAL_get_reset_source(void) { return MCUSR; }
// eeprom
//void eeprom_write_byte(unsigned char *pos, unsigned char value);
//unsigned char eeprom_read_byte(unsigned char *pos);
// timers
#define HAL_TIMER_RATE ((F_CPU) / 8) // i.e., 2MHz or 2.5MHz
#define STEP_TIMER_NUM 1
#define TEMP_TIMER_NUM 0
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#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) // Cannot be of type double
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define ENABLE_STEPPER_DRIVER_INTERRUPT() SBI(TIMSK1, OCIE1A)
#define DISABLE_STEPPER_DRIVER_INTERRUPT() CBI(TIMSK1, OCIE1A)
#define STEPPER_ISR_ENABLED() TEST(TIMSK1, OCIE1A)
#define ENABLE_TEMPERATURE_INTERRUPT() SBI(TIMSK0, OCIE0B)
#define DISABLE_TEMPERATURE_INTERRUPT() CBI(TIMSK0, OCIE0B)
#define TEMPERATURE_ISR_ENABLED() TEST(TIMSK0, OCIE0B)
FORCE_INLINE void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
UNUSED(frequency);
switch (timer_num) {
case STEP_TIMER_NUM:
// waveform generation = 0100 = CTC
SET_WGM(1, CTC_OCRnA);
// output mode = 00 (disconnected)
SET_COMA(1, NORMAL);
// Set the timer pre-scaler
// Generally we use a divider of 8, resulting in a 2MHz timer
// frequency on a 16MHz MCU. If you are going to change this, be
// sure to regenerate speed_lookuptable.h with
// create_speed_lookuptable.py
SET_CS(1, PRESCALER_8); // CS 2 = 1/8 prescaler
// Init Stepper ISR to 122 Hz for quick starting
// (F_CPU) / (STEPPER_TIMER_PRESCALE) / frequency
OCR1A = 0x4000;
TCNT1 = 0;
break;
case TEMP_TIMER_NUM:
// Use timer0 for temperature measurement
// Interleave temperature interrupt with millies interrupt
OCR0B = 128;
break;
}
}
#define TIMER_OCR_1 OCR1A
#define TIMER_COUNTER_1 TCNT1
#define TIMER_OCR_0 OCR0A
#define TIMER_COUNTER_0 TCNT0
#define _CAT(a, ...) a ## __VA_ARGS__
#define HAL_timer_set_compare(timer, compare) (_CAT(TIMER_OCR_, timer) = compare)
#define HAL_timer_get_compare(timer) _CAT(TIMER_OCR_, timer)
#define HAL_timer_get_count(timer) _CAT(TIMER_COUNTER_, timer)
/**
* On AVR there is no hardware prioritization and preemption of
* interrupts, so this emulates it. The UART has first priority
* (otherwise, characters will be lost due to UART overflow).
* Then: Stepper, Endstops, Temperature, and -finally- all others.
*/
#define HAL_timer_isr_prologue(TIMER_NUM)
#define HAL_timer_isr_epilogue(TIMER_NUM)
/* 18 cycles maximum latency */
#define HAL_STEP_TIMER_ISR \
extern "C" void TIMER1_COMPA_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER1_COMPA_vect_bottom (void) asm ("TIMER1_COMPA_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER1_COMPA_vect (void) { \
__asm__ __volatile__ ( \
A("push r16") /* 2 Save R16 */ \
A("in r16, __SREG__") /* 1 Get SREG */ \
A("push r16") /* 2 Save SREG into stack */ \
A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("push r16") /* 2 Save TIMSK0 into the stack */ \
A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16") /* 2 And set the new value */ \
A("lds r16, %[timsk1]") /* 2 Load into R0 the stepper timer Interrupt mask register [TIMSK1] */ \
A("andi r16,~%[msk1]") /* 1 Disable the stepper ISR */ \
A("sts %[timsk1], r16") /* 2 And set the new value */ \
A("push r16") /* 2 Save TIMSK1 into stack */ \
A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
A("push r16") /* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C") /* 1 Get EIND register */ \
A("push r0") /* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
A("push r30") \
A("push r31") \
A("clr r1") /* C runtime expects this register to be 0 */ \
A("call TIMER1_COMPA_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("pop r31") \
A("pop r30") \
A("pop r27") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16") /* 1 Restore EIND register */ \
A("pop r16") /* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
A("pop r16") /* 2 Get the original TIMSK1 value but with stepper ISR disabled */ \
A("ori r16,%[msk1]") /* 1 Reenable the stepper ISR */ \
A("cli") /* 1 Disable global interrupts - Reenabling Stepper ISR can reenter amd temperature can reenter, and we want that, if it happens, after this ISR has ended */ \
A("sts %[timsk1], r16") /* 2 And restore the old value - This reenables the stepper ISR */ \
A("pop r16") /* 2 Get the temperature timer Interrupt mask register [TIMSK0] */ \
A("sts %[timsk0], r16") /* 2 And restore the old value - This reenables the temperature ISR */ \
A("pop r16") /* 2 Get the old SREG value */ \
A("out __SREG__, r16") /* 1 And restore the SREG value */ \
A("pop r16") /* 2 Restore R16 value */ \
A("reti") /* 4 Return from interrupt */ \
: \
: [timsk0] "i" ((uint16_t)&TIMSK0), \
[timsk1] "i" ((uint16_t)&TIMSK1), \
[msk0] "M" ((uint8_t)(1<<OCIE0B)),\
[msk1] "M" ((uint8_t)(1<<OCIE1A)) \
: \
); \
} \
void TIMER1_COMPA_vect_bottom(void)
/* 14 cycles maximum latency */
#define HAL_TEMP_TIMER_ISR \
extern "C" void TIMER0_COMPB_vect (void) __attribute__ ((signal, naked, used, externally_visible)); \
extern "C" void TIMER0_COMPB_vect_bottom(void) asm ("TIMER0_COMPB_vect_bottom") __attribute__ ((used, externally_visible, noinline)); \
void TIMER0_COMPB_vect (void) { \
__asm__ __volatile__ ( \
A("push r16") /* 2 Save R16 */ \
A("in r16, __SREG__") /* 1 Get SREG */ \
A("push r16") /* 2 Save SREG into stack */ \
A("lds r16, %[timsk0]") /* 2 Load into R0 the Temperature timer Interrupt mask register */ \
A("andi r16,~%[msk0]") /* 1 Disable the temperature ISR */ \
A("sts %[timsk0], r16") /* 2 And set the new value */ \
A("sei") /* 1 Enable global interrupts - It is safe, as the temperature ISR is disabled, so we cannot reenter it */ \
A("push r16") /* 2 Save TIMSK0 into stack */ \
A("in r16, 0x3B") /* 1 Get RAMPZ register */ \
A("push r16") /* 2 Save RAMPZ into stack */ \
A("in r16, 0x3C") /* 1 Get EIND register */ \
A("push r0") /* C runtime can modify all the following registers without restoring them */ \
A("push r1") \
A("push r18") \
A("push r19") \
A("push r20") \
A("push r21") \
A("push r22") \
A("push r23") \
A("push r24") \
A("push r25") \
A("push r26") \
A("push r27") \
A("push r30") \
A("push r31") \
A("clr r1") /* C runtime expects this register to be 0 */ \
A("call TIMER0_COMPB_vect_bottom") /* Call the bottom handler - No inlining allowed, otherwise registers used are not saved */ \
A("pop r31") \
A("pop r30") \
A("pop r27") \
A("pop r26") \
A("pop r25") \
A("pop r24") \
A("pop r23") \
A("pop r22") \
A("pop r21") \
A("pop r20") \
A("pop r19") \
A("pop r18") \
A("pop r1") \
A("pop r0") \
A("out 0x3C, r16") /* 1 Restore EIND register */ \
A("pop r16") /* 2 Get the original RAMPZ register value */ \
A("out 0x3B, r16") /* 1 Restore RAMPZ register to its original value */ \
A("pop r16") /* 2 Get the original TIMSK0 value but with temperature ISR disabled */ \
A("ori r16,%[msk0]") /* 1 Enable temperature ISR */ \
A("cli") /* 1 Disable global interrupts - We must do this, as we will reenable the temperature ISR, and we don't want to reenter this handler until the current one is done */ \
A("sts %[timsk0], r16") /* 2 And restore the old value */ \
A("pop r16") /* 2 Get the old SREG */ \
A("out __SREG__, r16") /* 1 And restore the SREG value */ \
A("pop r16") /* 2 Restore R16 */ \
A("reti") /* 4 Return from interrupt */ \
: \
: [timsk0] "i"((uint16_t)&TIMSK0), \
[msk0] "M" ((uint8_t)(1<<OCIE0B)) \
: \
); \
} \
void TIMER0_COMPB_vect_bottom(void)
// ADC
#ifdef DIDR2
#define HAL_ANALOG_SELECT(pin) do{ if (pin < 8) SBI(DIDR0, pin); else SBI(DIDR2, pin & 0x07); }while(0)
#else
#define HAL_ANALOG_SELECT(pin) do{ SBI(DIDR0, pin); }while(0)
#endif
inline void HAL_adc_init(void) {
ADCSRA = _BV(ADEN) | _BV(ADSC) | _BV(ADIF) | 0x07;
DIDR0 = 0;
#ifdef DIDR2
DIDR2 = 0;
#endif
}
#define SET_ADMUX_ADCSRA(pin) ADMUX = _BV(REFS0) | (pin & 0x07); SBI(ADCSRA, ADSC)
#ifdef MUX5
#define HAL_START_ADC(pin) if (pin > 7) ADCSRB = _BV(MUX5); else ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#else
#define HAL_START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
#define HAL_READ_ADC() ADC
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
#define GET_PIN_MAP_PIN(index) index
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#define HAL_SENSITIVE_PINS 0, 1
#endif // _HAL_AVR_H_

File diff suppressed because it is too large Load Diff

View File

@@ -1,342 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef I2CPOSENC_H
#define I2CPOSENC_H
#include "MarlinConfig.h"
#if ENABLED(I2C_POSITION_ENCODERS)
#include "enum.h"
#include "macros.h"
#include "types.h"
#include <Wire.h>
//=========== Advanced / Less-Common Encoder Configuration Settings ==========
#define I2CPE_EC_THRESH_PROPORTIONAL // if enabled adjusts the error correction threshold
// proportional to the current speed of the axis allows
// for very small error margin at low speeds without
// stuttering due to reading latency at high speeds
#define I2CPE_DEBUG // enable encoder-related debug serial echos
#define I2CPE_REBOOT_TIME 5000 // time we wait for an encoder module to reboot
// after changing address.
#define I2CPE_MAG_SIG_GOOD 0
#define I2CPE_MAG_SIG_MID 1
#define I2CPE_MAG_SIG_BAD 2
#define I2CPE_MAG_SIG_NF 255
#define I2CPE_REQ_REPORT 0
#define I2CPE_RESET_COUNT 1
#define I2CPE_SET_ADDR 2
#define I2CPE_SET_REPORT_MODE 3
#define I2CPE_CLEAR_EEPROM 4
#define I2CPE_LED_PAR_MODE 10
#define I2CPE_LED_PAR_BRT 11
#define I2CPE_LED_PAR_RATE 14
#define I2CPE_REPORT_DISTANCE 0
#define I2CPE_REPORT_STRENGTH 1
#define I2CPE_REPORT_VERSION 2
// Default I2C addresses
#define I2CPE_PRESET_ADDR_X 30
#define I2CPE_PRESET_ADDR_Y 31
#define I2CPE_PRESET_ADDR_Z 32
#define I2CPE_PRESET_ADDR_E 33
#define I2CPE_DEF_AXIS X_AXIS
#define I2CPE_DEF_ADDR I2CPE_PRESET_ADDR_X
// Error event counter; tracks how many times there is an error exceeding a certain threshold
#define I2CPE_ERR_CNT_THRESH 3.00
#define I2CPE_ERR_CNT_DEBOUNCE_MS 2000
#if ENABLED(I2CPE_ERR_ROLLING_AVERAGE)
#define I2CPE_ERR_ARRAY_SIZE 32
#define I2CPE_ERR_PRST_ARRAY_SIZE 10
#endif
// Error Correction Methods
#define I2CPE_ECM_NONE 0
#define I2CPE_ECM_MICROSTEP 1
#define I2CPE_ECM_PLANNER 2
#define I2CPE_ECM_STALLDETECT 3
// Encoder types
#define I2CPE_ENC_TYPE_ROTARY 0
#define I2CPE_ENC_TYPE_LINEAR 1
// Parser
#define I2CPE_PARSE_ERR 1
#define I2CPE_PARSE_OK 0
#define LOOP_PE(VAR) LOOP_L_N(VAR, I2CPE_ENCODER_CNT)
#define CHECK_IDX() do{ if (!WITHIN(idx, 0, I2CPE_ENCODER_CNT - 1)) return; }while(0)
typedef union {
volatile int32_t val = 0;
uint8_t bval[4];
} i2cLong;
class I2CPositionEncoder {
private:
AxisEnum encoderAxis = I2CPE_DEF_AXIS;
uint8_t i2cAddress = I2CPE_DEF_ADDR,
ecMethod = I2CPE_DEF_EC_METHOD,
type = I2CPE_DEF_TYPE,
H = I2CPE_MAG_SIG_NF; // Magnetic field strength
int encoderTicksPerUnit = I2CPE_DEF_ENC_TICKS_UNIT,
stepperTicks = I2CPE_DEF_TICKS_REV,
errorCount = 0,
errorPrev = 0;
float ecThreshold = I2CPE_DEF_EC_THRESH;
bool homed = false,
trusted = false,
initialised = false,
active = false,
invert = false,
ec = true;
int32_t zeroOffset = 0,
lastPosition = 0,
position;
millis_t lastPositionTime = 0,
nextErrorCountTime = 0,
lastErrorTime;
#if ENABLED(I2CPE_ERR_ROLLING_AVERAGE)
uint8_t errIdx = 0, errPrstIdx = 0;
int err[I2CPE_ERR_ARRAY_SIZE] = { 0 },
errPrst[I2CPE_ERR_PRST_ARRAY_SIZE] = { 0 };
#endif
public:
void init(const uint8_t address, const AxisEnum axis);
void reset();
void update();
void set_homed();
int32_t get_raw_count();
FORCE_INLINE float mm_from_count(const int32_t count) {
switch (type) {
default: return -1;
case I2CPE_ENC_TYPE_LINEAR:
return count / encoderTicksPerUnit;
case I2CPE_ENC_TYPE_ROTARY:
return (count * stepperTicks) / (encoderTicksPerUnit * planner.axis_steps_per_mm[encoderAxis]);
}
}
FORCE_INLINE float get_position_mm() { return mm_from_count(get_position()); }
FORCE_INLINE int32_t get_position() { return get_raw_count() - zeroOffset; }
int32_t get_axis_error_steps(const bool report);
float get_axis_error_mm(const bool report);
void calibrate_steps_mm(const uint8_t iter);
bool passes_test(const bool report);
bool test_axis(void);
FORCE_INLINE int get_error_count(void) { return errorCount; }
FORCE_INLINE void set_error_count(const int newCount) { errorCount = newCount; }
FORCE_INLINE uint8_t get_address() { return i2cAddress; }
FORCE_INLINE void set_address(const uint8_t addr) { i2cAddress = addr; }
FORCE_INLINE bool get_active(void) { return active; }
FORCE_INLINE void set_active(const bool a) { active = a; }
FORCE_INLINE void set_inverted(const bool i) { invert = i; }
FORCE_INLINE AxisEnum get_axis() { return encoderAxis; }
FORCE_INLINE bool get_ec_enabled() { return ec; }
FORCE_INLINE void set_ec_enabled(const bool enabled) { ec = enabled; }
FORCE_INLINE uint8_t get_ec_method() { return ecMethod; }
FORCE_INLINE void set_ec_method(const byte method) { ecMethod = method; }
FORCE_INLINE float get_ec_threshold() { return ecThreshold; }
FORCE_INLINE void set_ec_threshold(const float newThreshold) { ecThreshold = newThreshold; }
FORCE_INLINE int get_encoder_ticks_mm() {
switch (type) {
default: return 0;
case I2CPE_ENC_TYPE_LINEAR:
return encoderTicksPerUnit;
case I2CPE_ENC_TYPE_ROTARY:
return (int)((encoderTicksPerUnit / stepperTicks) * planner.axis_steps_per_mm[encoderAxis]);
}
}
FORCE_INLINE int get_ticks_unit() { return encoderTicksPerUnit; }
FORCE_INLINE void set_ticks_unit(const int ticks) { encoderTicksPerUnit = ticks; }
FORCE_INLINE uint8_t get_type() { return type; }
FORCE_INLINE void set_type(const byte newType) { type = newType; }
FORCE_INLINE int get_stepper_ticks() { return stepperTicks; }
FORCE_INLINE void set_stepper_ticks(const int ticks) { stepperTicks = ticks; }
};
class I2CPositionEncodersMgr {
private:
static bool I2CPE_anyaxis;
static uint8_t I2CPE_addr, I2CPE_idx;
public:
static void init(void);
// consider only updating one endoder per call / tick if encoders become too time intensive
static void update(void) { LOOP_PE(i) encoders[i].update(); }
static void homed(const AxisEnum axis) {
LOOP_PE(i)
if (encoders[i].get_axis() == axis) encoders[i].set_homed();
}
static void report_position(const int8_t idx, const bool units, const bool noOffset);
static void report_status(const int8_t idx) {
CHECK_IDX();
SERIAL_ECHOPAIR("Encoder ",idx);
SERIAL_ECHOPGM(": ");
encoders[idx].get_raw_count();
encoders[idx].passes_test(true);
}
static void report_error(const int8_t idx) {
CHECK_IDX();
encoders[idx].get_axis_error_steps(true);
}
static void test_axis(const int8_t idx) {
CHECK_IDX();
encoders[idx].test_axis();
}
static void calibrate_steps_mm(const int8_t idx, const int iterations) {
CHECK_IDX();
encoders[idx].calibrate_steps_mm(iterations);
}
static void change_module_address(const uint8_t oldaddr, const uint8_t newaddr);
static void report_module_firmware(const uint8_t address);
static void report_error_count(const int8_t idx, const AxisEnum axis) {
CHECK_IDX();
SERIAL_ECHOPAIR("Error count on ", axis_codes[axis]);
SERIAL_ECHOLNPAIR(" axis is ", encoders[idx].get_error_count());
}
static void reset_error_count(const int8_t idx, const AxisEnum axis) {
CHECK_IDX();
encoders[idx].set_error_count(0);
SERIAL_ECHOPAIR("Error count on ", axis_codes[axis]);
SERIAL_ECHOLNPGM(" axis has been reset.");
}
static void enable_ec(const int8_t idx, const bool enabled, const AxisEnum axis) {
CHECK_IDX();
encoders[idx].set_ec_enabled(enabled);
SERIAL_ECHOPAIR("Error correction on ", axis_codes[axis]);
SERIAL_ECHOPGM(" axis is ");
serialprintPGM(encoders[idx].get_ec_enabled() ? PSTR("en") : PSTR("dis"));
SERIAL_ECHOLNPGM("abled.");
}
static void set_ec_threshold(const int8_t idx, const float newThreshold, const AxisEnum axis) {
CHECK_IDX();
encoders[idx].set_ec_threshold(newThreshold);
SERIAL_ECHOPAIR("Error correct threshold for ", axis_codes[axis]);
SERIAL_ECHOPAIR_F(" axis set to ", newThreshold);
SERIAL_ECHOLNPGM("mm.");
}
static void get_ec_threshold(const int8_t idx, const AxisEnum axis) {
CHECK_IDX();
const float threshold = encoders[idx].get_ec_threshold();
SERIAL_ECHOPAIR("Error correct threshold for ", axis_codes[axis]);
SERIAL_ECHOPAIR_F(" axis is ", threshold);
SERIAL_ECHOLNPGM("mm.");
}
static int8_t idx_from_axis(const AxisEnum axis) {
LOOP_PE(i)
if (encoders[i].get_axis() == axis) return i;
return -1;
}
static int8_t idx_from_addr(const uint8_t addr) {
LOOP_PE(i)
if (encoders[i].get_address() == addr) return i;
return -1;
}
static int8_t parse();
static void M860();
static void M861();
static void M862();
static void M863();
static void M864();
static void M865();
static void M866();
static void M867();
static void M868();
static void M869();
static I2CPositionEncoder encoders[I2CPE_ENCODER_CNT];
};
extern I2CPositionEncodersMgr I2CPEM;
FORCE_INLINE static void gcode_M860() { I2CPEM.M860(); }
FORCE_INLINE static void gcode_M861() { I2CPEM.M861(); }
FORCE_INLINE static void gcode_M862() { I2CPEM.M862(); }
FORCE_INLINE static void gcode_M863() { I2CPEM.M863(); }
FORCE_INLINE static void gcode_M864() { I2CPEM.M864(); }
FORCE_INLINE static void gcode_M865() { I2CPEM.M865(); }
FORCE_INLINE static void gcode_M866() { I2CPEM.M866(); }
FORCE_INLINE static void gcode_M867() { I2CPEM.M867(); }
FORCE_INLINE static void gcode_M868() { I2CPEM.M868(); }
FORCE_INLINE static void gcode_M869() { I2CPEM.M869(); }
#endif //I2C_POSITION_ENCODERS
#endif //I2CPOSENC_H

View File

@@ -22,311 +22,227 @@
/**
* M100 Free Memory Watcher
*
*
* This code watches the free memory block between the bottom of the heap and the top of the stack.
* This memory block is initialized and watched via the M100 command.
*
* M100 I Initializes the free memory block and prints vitals statistics about the area
*
* M100 F Identifies how much of the free memory block remains free and unused. It also
* detects and reports any corruption within the free memory block that may have
* happened due to errant firmware.
*
* M100 D Does a hex display of the free memory block along with a flag for any errant
* data that does not match the expected value.
*
* M100 C x Corrupts x locations within the free memory block. This is useful to check the
* correctness of the M100 F and M100 D commands.
*
* Also, there are two support functions that can be called from a developer's C code.
*
* uint16_t check_for_free_memory_corruption(const char * const ptr);
* void M100_dump_routine(const char * const title, const char *start, const char *end);
*
* Initial version by Roxy-3D
*
* M100 I Initializes the free memory block and prints vitals statistics about the area
* M100 F Identifies how much of the free memory block remains free and unused. It also
* detects and reports any corruption within the free memory block that may have
* happened due to errant firmware.
* M100 D Does a hex display of the free memory block along with a flag for any errant
* data that does not match the expected value.
* M100 C x Corrupts x locations within the free memory block. This is useful to check the
* correctness of the M100 F and M100 D commands.
*
* Initial version by Roxy-3DPrintBoard
*/
#include "MarlinConfig.h"
#if ENABLED(M100_FREE_MEMORY_WATCHER)
#define M100_FREE_MEMORY_DUMPER // Enable for the `M100 D` Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Enable for the `M100 C` Corrupt sub-command
#define M100_FREE_MEMORY_DUMPER // Comment out to remove Dump sub-command
#define M100_FREE_MEMORY_CORRUPTOR // Comment out to remove Corrupt sub-command
#include "Marlin.h"
#include "parser.h"
#include "hex_print_routines.h"
#define TEST_BYTE ((char) 0xE5)
#if ENABLED(M100_FREE_MEMORY_WATCHER)
extern char* __brkval;
extern size_t __heap_start, __heap_end, __flp;
extern char __bss_end;
//
// Utility functions
// Utility functions used by M100 to get its work done.
//
#define END_OF_HEAP() (__brkval ? __brkval : &__bss_end)
int check_for_free_memory_corruption(const char * const title);
char* top_of_stack();
void prt_hex_nibble(unsigned int);
void prt_hex_byte(unsigned int);
void prt_hex_word(unsigned int);
int how_many_E5s_are_here(char*);
void gcode_M100() {
static bool m100_not_initialized = true;
char* sp, *ptr;
int i, j, n;
//
// M100 D dumps the free memory block from __brkval to the stack pointer.
// malloc() eats memory from the start of the block and the stack grows
// up from the bottom of the block. Solid 0xE5's indicate nothing has
// used that memory yet. There should not be anything but 0xE5's within
// the block of 0xE5's. If there is, that would indicate memory corruption
// probably caused by bad pointers. Any unexpected values will be flagged in
// the right hand column to help spotting them.
//
#if ENABLED(M100_FREE_MEMORY_DUMPER) // Disable to remove Dump sub-command
if (code_seen('D')) {
ptr = __brkval ? __brkval : &__bss_end;
//
// We want to start and end the dump on a nice 16 byte boundry even though
// the values we are using are not 16 byte aligned.
//
SERIAL_ECHOPGM("\nbss_end : ");
prt_hex_word((unsigned int) ptr);
ptr = (char*)((unsigned long) ptr & 0xfff0);
sp = top_of_stack();
SERIAL_ECHOPGM("\nStack Pointer : ");
prt_hex_word((unsigned int) sp);
SERIAL_EOL;
sp = (char*)((unsigned long) sp | 0x000f);
n = sp - ptr;
//
// This is the main loop of the Dump command.
//
while (ptr < sp) {
prt_hex_word((unsigned int) ptr); // Print the address
SERIAL_CHAR(':');
for (i = 0; i < 16; i++) { // and 16 data bytes
prt_hex_byte(*(ptr + i));
SERIAL_CHAR(' ');
}
SERIAL_CHAR('|'); // now show where non 0xE5's are
for (i = 0; i < 16; i++) {
if (*(ptr + i) == (char)0xe5)
SERIAL_CHAR(' ');
else
SERIAL_CHAR('?');
}
SERIAL_EOL;
ptr += 16;
}
return;
}
#endif
//
// M100 F requests the code to return the number of free bytes in the memory pool along with
// other vital statistics that define the memory pool.
//
if (code_seen('F')) {
#if 0
int max_addr = (int) __brkval ? __brkval : &__bss_end;
int max_cnt = 0;
#endif
int block_cnt = 0;
ptr = __brkval ? __brkval : &__bss_end;
sp = top_of_stack();
n = sp - ptr;
// Scan through the range looking for the biggest block of 0xE5's we can find
for (i = 0; i < n; i++) {
if (*(ptr + i) == (char)0xe5) {
j = how_many_E5s_are_here(ptr + i);
if (j > 8) {
SERIAL_ECHOPAIR("Found ", j);
SERIAL_ECHOPGM(" bytes free at 0x");
prt_hex_word((int) ptr + i);
SERIAL_EOL;
i += j;
block_cnt++;
}
#if 0
if (j > max_cnt) { // We don't do anything with this information yet
max_cnt = j; // but we do know where the biggest free memory block is.
max_addr = (int) ptr + i;
}
#endif
}
}
if (block_cnt > 1)
SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
return;
}
//
// M100 C x Corrupts x locations in the free memory pool and reports the locations of the corruption.
// This is useful to check the correctness of the M100 D and the M100 F commands.
//
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if (code_seen('C')) {
int x = code_value_int(); // x gets the # of locations to corrupt within the memory pool
SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
ptr = __brkval ? __brkval : &__bss_end;
SERIAL_ECHOPAIR("\nbss_end : ", ptr);
ptr += 8;
sp = top_of_stack();
SERIAL_ECHOPAIR("\nStack Pointer : ", sp);
SERIAL_ECHOLNPGM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
j = n / (x + 1);
for (i = 1; i <= x; i++) {
*(ptr + (i * j)) = i;
SERIAL_ECHOPGM("\nCorrupting address: 0x");
prt_hex_word((unsigned int)(ptr + (i * j)));
}
SERIAL_ECHOLNPGM("\n");
return;
}
#endif
//
// M100 I Initializes the free memory pool so it can be watched and prints vital
// statistics that define the free memory pool.
//
if (m100_not_initialized || code_seen('I')) { // If no sub-command is specified, the first time
SERIAL_ECHOLNPGM("Initializing free memory block.\n"); // this happens, it will Initialize.
ptr = __brkval ? __brkval : &__bss_end; // Repeated M100 with no sub-command will not destroy the
SERIAL_ECHOPAIR("\nbss_end : ", ptr); // state of the initialized free memory pool.
ptr += 8;
sp = top_of_stack();
SERIAL_ECHOPAIR("\nStack Pointer : ", sp);
SERIAL_ECHOLNPGM("\n");
n = sp - ptr - 64; // -64 just to keep us from finding interrupt activity that
// has altered the stack.
SERIAL_ECHO(n);
SERIAL_ECHOLNPGM(" bytes of memory initialized.\n");
for (i = 0; i < n; i++)
*(ptr + i) = (char)0xe5;
for (i = 0; i < n; i++) {
if (*(ptr + i) != (char)0xe5) {
SERIAL_ECHOPAIR("? address : ", ptr + i);
SERIAL_ECHOPAIR("=", *(ptr + i));
SERIAL_ECHOLNPGM("\n");
}
}
m100_not_initialized = false;
return;
}
return;
}
// top_of_stack() returns the location of a variable on its stack frame. The value returned is above
// the stack once the function returns to the caller.
// Location of a variable on its stack frame. Returns a value above
// the stack (once the function returns to the caller).
char* top_of_stack() {
char x;
return &x + 1; // x is pulled on return;
}
// Count the number of test bytes at the specified location.
int16_t count_test_bytes(const char * const ptr) {
for (uint16_t i = 0; i < 32000; i++)
if (((char) ptr[i]) != TEST_BYTE)
return i - 1;
//
// 3 support routines to print hex numbers. We can print a nibble, byte and word
//
void prt_hex_nibble(unsigned int n) {
if (n <= 9)
SERIAL_ECHO(n);
else
SERIAL_ECHO((char)('A' + n - 10));
}
void prt_hex_byte(unsigned int b) {
prt_hex_nibble((b & 0xf0) >> 4);
prt_hex_nibble(b & 0x0f);
}
void prt_hex_word(unsigned int w) {
prt_hex_byte((w & 0xff00) >> 8);
prt_hex_byte(w & 0x0ff);
}
// how_many_E5s_are_here() is a utility function to easily find out how many 0xE5's are
// at the specified location. Having this logic as a function simplifies the search code.
//
int how_many_E5s_are_here(char* p) {
int n;
for (n = 0; n < 32000; n++) {
if (*(p + n) != (char)0xe5)
return n - 1;
}
return -1;
}
//
// M100 sub-commands
//
#if ENABLED(M100_FREE_MEMORY_DUMPER)
/**
* M100 D
* Dump the free memory block from __brkval to the stack pointer.
* malloc() eats memory from the start of the block and the stack grows
* up from the bottom of the block. Solid test bytes indicate nothing has
* used that memory yet. There should not be anything but test bytes within
* the block. If so, it may indicate memory corruption due to a bad pointer.
* Unexpected bytes are flagged in the right column.
*/
void dump_free_memory(const char *ptr, const char *sp) {
//
// Start and end the dump on a nice 16 byte boundary
// (even though the values are not 16-byte aligned).
//
ptr = (char *)((uint16_t)ptr & 0xFFF0); // Align to 16-byte boundary
sp = (char *)((uint16_t)sp | 0x000F); // Align sp to the 15th byte (at or above sp)
// Dump command main loop
while (ptr < sp) {
print_hex_word((uint16_t)ptr); // Print the address
SERIAL_CHAR(':');
for (uint8_t i = 0; i < 16; i++) { // and 16 data bytes
if (i == 8) SERIAL_CHAR('-');
print_hex_byte(ptr[i]);
SERIAL_CHAR(' ');
}
safe_delay(25);
SERIAL_CHAR('|'); // Point out non test bytes
for (uint8_t i = 0; i < 16; i++) {
char ccc = (char)ptr[i]; // cast to char before automatically casting to char on assignment, in case the compiler is broken
if (&ptr[i] >= (const char*)command_queue && &ptr[i] < (const char*)(command_queue + sizeof(command_queue))) { // Print out ASCII in the command buffer area
if (!WITHIN(ccc, ' ', 0x7E)) ccc = ' ';
}
else { // If not in the command buffer area, flag bytes that don't match the test byte
ccc = (ccc == TEST_BYTE) ? ' ' : '?';
}
SERIAL_CHAR(ccc);
}
SERIAL_EOL();
ptr += 16;
safe_delay(25);
idle();
}
}
void M100_dump_routine(const char * const title, const char *start, const char *end) {
SERIAL_ECHOLN(title);
//
// Round the start and end locations to produce full lines of output
//
start = (char*)((uint16_t) start & 0xFFF0);
end = (char*)((uint16_t) end | 0x000F);
dump_free_memory(start, end);
}
#endif // M100_FREE_MEMORY_DUMPER
/**
* M100 F
* Return the number of free bytes in the memory pool,
* with other vital statistics defining the pool.
*/
void free_memory_pool_report(char * const ptr, const int16_t size) {
int16_t max_cnt = -1, block_cnt = 0;
char *max_addr = NULL;
// Find the longest block of test bytes in the buffer
for (int16_t i = 0; i < size; i++) {
char *addr = ptr + i;
if (*addr == TEST_BYTE) {
const int16_t j = count_test_bytes(addr);
if (j > 8) {
SERIAL_ECHOPAIR("Found ", j);
SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(addr));
if (j > max_cnt) {
max_cnt = j;
max_addr = addr;
}
i += j;
block_cnt++;
}
}
}
if (block_cnt > 1) {
SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
SERIAL_ECHOPAIR("\nLargest free block is ", max_cnt);
SERIAL_ECHOLNPAIR(" bytes at ", hex_address(max_addr));
}
SERIAL_ECHOLNPAIR("check_for_free_memory_corruption() = ", check_for_free_memory_corruption("M100 F "));
}
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
/**
* M100 C<num>
* Corrupt <num> locations in the free memory pool and report the corrupt addresses.
* This is useful to check the correctness of the M100 D and the M100 F commands.
*/
void corrupt_free_memory(char *ptr, const uint16_t size) {
ptr += 8;
const uint16_t near_top = top_of_stack() - ptr - 250, // -250 to avoid interrupt activity that's altered the stack.
j = near_top / (size + 1);
SERIAL_ECHOLNPGM("Corrupting free memory block.\n");
for (uint16_t i = 1; i <= size; i++) {
char * const addr = ptr + i * j;
*addr = i;
SERIAL_ECHOPAIR("\nCorrupting address: ", hex_address(addr));
}
SERIAL_EOL();
}
#endif // M100_FREE_MEMORY_CORRUPTOR
/**
* M100 I
* Init memory for the M100 tests. (Automatically applied on the first M100.)
*/
void init_free_memory(char *ptr, int16_t size) {
SERIAL_ECHOLNPGM("Initializing free memory block.\n\n");
size -= 250; // -250 to avoid interrupt activity that's altered the stack.
if (size < 0) {
SERIAL_ECHOLNPGM("Unable to initialize.\n");
return;
}
ptr += 8; // move a few bytes away from the heap just because we don't want
// to be altering memory that close to it.
memset(ptr, TEST_BYTE, size);
SERIAL_ECHO(size);
SERIAL_ECHOLNPGM(" bytes of memory initialized.\n");
for (int16_t i = 0; i < size; i++) {
if (ptr[i] != TEST_BYTE) {
SERIAL_ECHOPAIR("? address : ", hex_address(ptr + i));
SERIAL_ECHOLNPAIR("=", hex_byte(ptr[i]));
SERIAL_EOL();
}
}
}
/**
* M100: Free Memory Check
*/
void gcode_M100() {
SERIAL_ECHOPAIR("\n__brkval : ", hex_address(__brkval));
SERIAL_ECHOPAIR("\n__bss_end : ", hex_address(&__bss_end));
char *ptr = END_OF_HEAP(), *sp = top_of_stack();
SERIAL_ECHOPAIR("\nstart of free space : ", hex_address(ptr));
SERIAL_ECHOLNPAIR("\nStack Pointer : ", hex_address(sp));
// Always init on the first invocation of M100
static bool m100_not_initialized = true;
if (m100_not_initialized || parser.seen('I')) {
m100_not_initialized = false;
init_free_memory(ptr, sp - ptr);
}
#if ENABLED(M100_FREE_MEMORY_DUMPER)
if (parser.seen('D'))
return dump_free_memory(ptr, sp);
#endif
if (parser.seen('F'))
return free_memory_pool_report(ptr, sp - ptr);
#if ENABLED(M100_FREE_MEMORY_CORRUPTOR)
if (parser.seen('C'))
return corrupt_free_memory(ptr, parser.value_int());
#endif
}
int check_for_free_memory_corruption(const char * const title) {
SERIAL_ECHO(title);
char *ptr = END_OF_HEAP(), *sp = top_of_stack();
int n = sp - ptr;
SERIAL_ECHOPAIR("\nfmc() n=", n);
SERIAL_ECHOPAIR("\n&__brkval: ", hex_address(&__brkval));
SERIAL_ECHOPAIR("=", hex_address(__brkval));
SERIAL_ECHOPAIR("\n__bss_end: ", hex_address(&__bss_end));
SERIAL_ECHOPAIR(" sp=", hex_address(sp));
if (sp < ptr) {
SERIAL_ECHOPGM(" sp < Heap ");
// SET_INPUT_PULLUP(63); // if the developer has a switch wired up to their controller board
// safe_delay(5); // this code can be enabled to pause the display as soon as the
// while ( READ(63)) // malfunction is detected. It is currently defaulting to a switch
// idle(); // being on pin-63 which is unassigend and available on most controller
// safe_delay(20); // boards.
// while ( !READ(63))
// idle();
safe_delay(20);
#ifdef M100_FREE_MEMORY_DUMPER
M100_dump_routine(" Memory corruption detected with sp<Heap\n", (char*)0x1B80, (char*)0x21FF);
#endif
}
// Scan through the range looking for the biggest block of 0xE5's we can find
int block_cnt = 0;
for (int i = 0; i < n; i++) {
if (ptr[i] == TEST_BYTE) {
int16_t j = count_test_bytes(ptr + i);
if (j > 8) {
// SERIAL_ECHOPAIR("Found ", j);
// SERIAL_ECHOLNPAIR(" bytes free at ", hex_address(ptr + i));
i += j;
block_cnt++;
SERIAL_ECHOPAIR(" (", block_cnt);
SERIAL_ECHOPAIR(") found=", j);
SERIAL_ECHOPGM(" ");
}
}
}
SERIAL_ECHOPAIR(" block_found=", block_cnt);
if (block_cnt != 1 || __brkval != 0x0000)
SERIAL_ECHOLNPGM("\nMemory Corruption detected in free memory area.");
if (block_cnt == 0) // Make sure the special case of no free blocks shows up as an
block_cnt = -1; // error to the calling code!
SERIAL_ECHOPGM(" return=");
if (block_cnt == 1) {
SERIAL_CHAR('0'); // if the block_cnt is 1, nothing has broken up the free memory
SERIAL_EOL(); // area and it is appropriate to say 'no corruption'.
return 0;
}
SERIAL_ECHOLNPGM("true");
return block_cnt;
}
#endif // M100_FREE_MEMORY_WATCHER
#endif

View File

@@ -1,4 +1,4 @@
# Marlin Firmware Arduino Project Makefile
# Sprinter Arduino Project Makefile
#
# Makefile Based on:
# Arduino 0011 Makefile
@@ -33,29 +33,10 @@
# 5. Type "make upload", reset your Arduino board, and press enter to
# upload your program to the Arduino board.
#
# Note that all settings at the top of this file can be overriden from
# the command line with, for example, "make HARDWARE_MOTHERBOARD=71"
#
# To compile for RAMPS (atmega2560) with Arduino 1.6.9 at root/arduino you would use...
#
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino
#
# To compile and upload simply add "upload" to the end of the line...
#
# make ARDUINO_VERSION=10609 AVR_TOOLS_PATH=/root/arduino/hardware/tools/avr/bin/ \
# HARDWARE_MOTHERBOARD=33 ARDUINO_INSTALL_DIR=/root/arduino upload
#
# If uploading doesn't work try adding the parameter "AVRDUDE_PROGRAMMER=wiring" or
# start upload manually (using stk500) like so:
#
# avrdude -C /root/arduino/hardware/tools/avr/etc/avrdude.conf -v -p m2560 -c stk500 \
# -U flash:w:applet/Marlin.hex:i -P /dev/ttyUSB0
#
# Or, try disconnecting USB to power down and then reconnecting before running avrdude.
#
# Note that all settings are set with ?=, this means you can override them
# from the commandline with "make HARDWARE_MOTHERBOARD=71" for example
# This defines the board to compile for (see boards.h for your board's ID)
# This defined the board you are compiling for (see boards.h for the options)
HARDWARE_MOTHERBOARD ?= 11
# Arduino source install directory, and version number
@@ -69,7 +50,7 @@ AVR_TOOLS_PATH ?=
#Programmer configuration
UPLOAD_RATE ?= 57600
AVRDUDE_PROGRAMMER ?= arduino
# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
# on most linuxes this will be /dev/ttyACM0 or /dev/ttyACM1
UPLOAD_PORT ?= /dev/ttyUSB0
#Directory used to build files in, contains all the build files, from object files to the final hex file
@@ -82,13 +63,6 @@ LIQUID_TWI2 ?= 0
# this defines if Wire is needed
WIRE ?= 0
# this defines if U8GLIB is needed (may require RELOC_WORKAROUND)
U8GLIB ?= 1
# this defines whether to add a workaround for the avr-gcc relocation bug
# https://www.stix.id.au/wiki/AVR_relocation_truncations_workaround
RELOC_WORKAROUND ?= 1
############################################################################
# Below here nothing should be changed...
@@ -96,297 +70,153 @@ RELOC_WORKAROUND ?= 1
# HARDWARE_VARIANT = "arduino", "Sanguino", "Gen7", ...
# MCU = "atmega1280", "Mega2560", "atmega2560", "atmega644p", ...
ifeq ($(HARDWARE_MOTHERBOARD),0)
# No motherboard selected
#
# RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560
#
# MEGA/RAMPS up to 1.2
else ifeq ($(HARDWARE_MOTHERBOARD),3)
# RAMPS 1.3 (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),33)
# RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),34)
# RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),35)
# RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),36)
# RAMPS 1.3 (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),38)
# RAMPS 1.4 (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),43)
# RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),44)
# RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),45)
# RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),46)
# RAMPS 1.4 (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),48)
# RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),143)
# RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),144)
# RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),145)
# RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),146)
# RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),148)
#
# RAMPS Derivatives - ATmega1280, ATmega2560
#
# 3Drag Controller
else ifeq ($(HARDWARE_MOTHERBOARD),77)
# Velleman K8200 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),78)
# Velleman K8400 Controller (derived from 3Drag Controller)
else ifeq ($(HARDWARE_MOTHERBOARD),79)
# 2PrintBeta BAM&DICE with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),401)
# 2PrintBeta BAM&DICE Due with STK drivers
else ifeq ($(HARDWARE_MOTHERBOARD),402)
# MKS BASE v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),40)
# MKS v1.5 with Allegro A4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),405)
# MKS BASE 1.0 with Heroic HR4982 stepper drivers
else ifeq ($(HARDWARE_MOTHERBOARD),41)
# MKS GEN v1.3 or 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),47)
# MKS GEN L
else ifeq ($(HARDWARE_MOTHERBOARD),53)
# zrib V2.0 control board (Chinese knock off RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),504)
# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),37)
# Invent-A-Part RigidBoard
else ifeq ($(HARDWARE_MOTHERBOARD),42)
# Invent-A-Part RigidBoard V2
else ifeq ($(HARDWARE_MOTHERBOARD),52)
# Sainsmart 2-in-1 board
else ifeq ($(HARDWARE_MOTHERBOARD),49)
# Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),7)
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
else ifeq ($(HARDWARE_MOTHERBOARD),71)
MCU ?= atmega1280
# Azteeg X3
else ifeq ($(HARDWARE_MOTHERBOARD),67)
# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),68)
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
else ifeq ($(HARDWARE_MOTHERBOARD),72)
# Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),80)
# bq ZUM Mega 3D
else ifeq ($(HARDWARE_MOTHERBOARD),503)
# MakeBoard Mini v2.1.2 is a control board sold by MicroMake
else ifeq ($(HARDWARE_MOTHERBOARD),431)
# TriGorilla Anycubic version 1.3 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),343)
# TriGorilla Anycubic version 1.4 based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),443)
# Creality: Ender-4, CR-8
else ifeq ($(HARDWARE_MOTHERBOARD),243)
#
# Other ATmega1280, ATmega2560
#
# Cartesio CN Controls V11
else ifeq ($(HARDWARE_MOTHERBOARD),111)
# Cartesio CN Controls V12
else ifeq ($(HARDWARE_MOTHERBOARD),112)
# Cheaptronic v1.0
else ifeq ($(HARDWARE_MOTHERBOARD),2)
# Cheaptronic v2.0
else ifeq ($(HARDWARE_MOTHERBOARD),21)
# Makerbot Mightyboard Revision E
else ifeq ($(HARDWARE_MOTHERBOARD),200)
# Megatronics
else ifeq ($(HARDWARE_MOTHERBOARD),70)
# Megatronics v2.0
else ifeq ($(HARDWARE_MOTHERBOARD),701)
# Megatronics v3.0
else ifeq ($(HARDWARE_MOTHERBOARD),703)
# Megatronics v3.1
else ifeq ($(HARDWARE_MOTHERBOARD),704)
# Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),301)
# Mini-Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),302)
# Mini-Rambo 1.0a
else ifeq ($(HARDWARE_MOTHERBOARD),303)
# Einsy Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),304)
# Einsy Retro
else ifeq ($(HARDWARE_MOTHERBOARD),305)
# Elefu Ra Board (v3)
else ifeq ($(HARDWARE_MOTHERBOARD),21)
# Leapfrog
else ifeq ($(HARDWARE_MOTHERBOARD),999)
# Mega controller
else ifeq ($(HARDWARE_MOTHERBOARD),310)
# abee Scoovo X9H
else ifeq ($(HARDWARE_MOTHERBOARD),321)
# Geeetech GT2560 Rev. A
else ifeq ($(HARDWARE_MOTHERBOARD),74)
# Geeetech GT2560 Rev. A+ (with auto level probe)
else ifeq ($(HARDWARE_MOTHERBOARD),75)
#
# ATmega1281, ATmega2561
#
else ifeq ($(HARDWARE_MOTHERBOARD),702)
MCU ?= atmega1281
else ifeq ($(HARDWARE_MOTHERBOARD),25)
MCU ?= atmega1281
#
# Sanguinololu and Derivatives - ATmega644P, ATmega1284P
#
# Sanguinololu < 1.2
else ifeq ($(HARDWARE_MOTHERBOARD),6)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Sanguinololu 1.2 and above
else ifeq ($(HARDWARE_MOTHERBOARD),62)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Melzi
else ifeq ($(HARDWARE_MOTHERBOARD),63)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Melzi with ATmega1284 (MaKr3d version)
else ifeq ($(HARDWARE_MOTHERBOARD),66)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Melzi Creality3D board (for CR-10 etc)
else ifeq ($(HARDWARE_MOTHERBOARD),89)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Melzi Malyan M150 board
else ifeq ($(HARDWARE_MOTHERBOARD),92)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Tronxy X5S
else ifeq ($(HARDWARE_MOTHERBOARD),505)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# STB V1.1
else ifeq ($(HARDWARE_MOTHERBOARD),64)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Azteeg X1
else ifeq ($(HARDWARE_MOTHERBOARD),65)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Anet 1.0 (Melzi clone)
else ifeq ($(HARDWARE_MOTHERBOARD),69)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
#
# Other ATmega644P, ATmega644, ATmega1284P
#
# Gen3 Monolithic Electronics
else ifeq ($(HARDWARE_MOTHERBOARD),22)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Gen3+
else ifeq ($(HARDWARE_MOTHERBOARD),9)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
# Gen6
else ifeq ($(HARDWARE_MOTHERBOARD),5)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
# Gen6 deluxe
else ifeq ($(HARDWARE_MOTHERBOARD),51)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
# Gen7 custom (Alfons3 Version)
else ifeq ($(HARDWARE_MOTHERBOARD),10)
#Gen7
ifeq ($(HARDWARE_MOTHERBOARD),10)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644
F_CPU ?= 20000000
# Gen7 v1.1, v1.2
else ifeq ($(HARDWARE_MOTHERBOARD),11)
else ifeq ($(HARDWARE_MOTHERBOARD),11)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
F_CPU ?= 20000000
# Gen7 v1.3
else ifeq ($(HARDWARE_MOTHERBOARD),12)
else ifeq ($(HARDWARE_MOTHERBOARD),12)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega644p
F_CPU ?= 20000000
# Gen7 v1.4
else ifeq ($(HARDWARE_MOTHERBOARD),13)
else ifeq ($(HARDWARE_MOTHERBOARD),13)
HARDWARE_VARIANT ?= Gen7
MCU ?= atmega1284p
F_CPU ?= 20000000
# Alpha OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),90)
HARDWARE_VARIANT ?= SanguinoA
MCU ?= atmega644
# Final OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),91)
HARDWARE_VARIANT ?= Sanguino
#RAMPS
else ifeq ($(HARDWARE_MOTHERBOARD),3)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),33)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),34)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),35)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),36)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),38)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),43)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),44)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),45)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),46)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),48)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
#Gen6
else ifeq ($(HARDWARE_MOTHERBOARD),5)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
# Sethi 3D_1
else ifeq ($(HARDWARE_MOTHERBOARD),20)
HARDWARE_VARIANT ?= Sanguino
else ifeq ($(HARDWARE_MOTHERBOARD),51)
HARDWARE_VARIANT ?= Gen6
MCU ?= atmega644p
#
# Teensyduino - AT90USB1286, AT90USB1286P
#
#Sanguinololu
else ifeq ($(HARDWARE_MOTHERBOARD),6)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),62)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),63)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
else ifeq ($(HARDWARE_MOTHERBOARD),65)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
else ifeq ($(HARDWARE_MOTHERBOARD),66)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
else ifeq ($(HARDWARE_MOTHERBOARD),69)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
# Teensylu
else ifeq ($(HARDWARE_MOTHERBOARD),8)
#Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),7)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),71)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega1280
#Teensylu
else ifeq ($(HARDWARE_MOTHERBOARD),8)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Printrboard (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),81)
else ifeq ($(HARDWARE_MOTHERBOARD),81)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Printrboard Revision F (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),811)
else ifeq ($(HARDWARE_MOTHERBOARD),811)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Brainwave (AT90USB646)
else ifeq ($(HARDWARE_MOTHERBOARD),82)
else ifeq ($(HARDWARE_MOTHERBOARD),82)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb646
# Brainwave Pro (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),83)
else ifeq ($(HARDWARE_MOTHERBOARD),83)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# SAV Mk-I (AT90USB1286)
else ifeq ($(HARDWARE_MOTHERBOARD),84)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make
else ifeq ($(HARDWARE_MOTHERBOARD),85)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
# 5DPrint D8 Driver Board
else ifeq ($(HARDWARE_MOTHERBOARD),88)
else ifeq ($(HARDWARE_MOTHERBOARD),84)
HARDWARE_VARIANT ?= Teensy
MCU ?= at90usb1286
#Gen3+
else ifeq ($(HARDWARE_MOTHERBOARD),9)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#Gen3 Monolithic Electronics
else ifeq ($(HARDWARE_MOTHERBOARD),22)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#Megatronics
else ifeq ($(HARDWARE_MOTHERBOARD),70)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
#Alpha OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),90)
HARDWARE_VARIANT ?= SanguinoA
MCU ?= atmega644
#Final OMCA board
else ifeq ($(HARDWARE_MOTHERBOARD),91)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
#Rambo
else ifeq ($(HARDWARE_MOTHERBOARD),301)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
# Azteeg
else ifeq ($(HARDWARE_MOTHERBOARD),67)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
else ifeq ($(HARDWARE_MOTHERBOARD),68)
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
endif
# Be sure to regenerate speed_lookuptable.h with create_speed_lookuptable.py
@@ -394,14 +224,20 @@ endif
# Set to 16Mhz if not yet set.
F_CPU ?= 16000000
# Set to arduino, ATmega2560 if not yet set.
HARDWARE_VARIANT ?= arduino
MCU ?= atmega2560
# Arduino contained the main source code for the Arduino
# Libraries, the "hardware variant" are for boards
# that derives from that, and their source are present in
# the main Marlin source directory
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Sanguino))
HARDWARE_DIR = $(ARDUINO_INSTALL_DIR)/hardware
else
ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
HARDWARE_DIR = ../ArduinoAddons/Arduino_1.x.x
else
HARDWARE_DIR = ../ArduinoAddons/Arduino_0.xx
endif
endif
HARDWARE_SRC = $(HARDWARE_DIR)/marlin/avr/cores/arduino
TARGET = $(notdir $(CURDIR))
@@ -411,11 +247,10 @@ TARGET = $(notdir $(CURDIR))
VPATH = .
VPATH += $(BUILD_DIR)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/cores/arduino
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/libraries/SPI/src
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/LiquidCrystal/src
VPATH += $(HARDWARE_SRC)
ifeq ($(HARDWARE_VARIANT), $(filter $(HARDWARE_VARIANT),arduino Teensy Sanguino))
VPATH += $(HARDWARE_DIR)/marlin/avr/libraries/LiquidCrystal/src
VPATH += $(HARDWARE_DIR)/marlin/avr/libraries/SPI
ifeq ($(LIQUID_TWI2), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
@@ -425,17 +260,22 @@ ifeq ($(WIRE), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Wire/utility
endif
ifeq ($(NEOPIXEL), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/Adafruit_NeoPixel
else
VPATH += $(HARDWARE_DIR)/libraries/LiquidCrystal
VPATH += $(HARDWARE_DIR)/libraries/SPI
ifeq ($(LIQUID_TWI2), 1)
VPATH += $(HARDWARE_DIR)/libraries/Wire
VPATH += $(HARDWARE_DIR)/libraries/Wire/utility
VPATH += $(HARDWARE_DIR)/libraries/LiquidTWI2
endif
ifeq ($(WIRE), 1)
VPATH += $(HARDWARE_DIR)/libraries/Wire
VPATH += $(HARDWARE_DIR)/libraries/Wire/utility
endif
ifeq ($(U8GLIB), 1)
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib
VPATH += $(ARDUINO_INSTALL_DIR)/libraries/U8glib/utility
endif
ifeq ($(HARDWARE_VARIANT), arduino)
HARDWARE_SUB_VARIANT ?= mega
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/avr/variants/$(HARDWARE_SUB_VARIANT)
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/arduino/variants/$(HARDWARE_SUB_VARIANT)
else
ifeq ($(HARDWARE_VARIANT), Sanguino)
VPATH += $(HARDWARE_DIR)/marlin/avr/variants/sanguino
@@ -452,11 +292,12 @@ ifeq ($(HARDWARE_VARIANT), Teensy)
SRC = wiring.c
VPATH += $(ARDUINO_INSTALL_DIR)/hardware/teensy/cores/teensy
endif
CXXSRC = WMath.cpp WString.cpp Print.cpp SPI.cpp Tone.cpp
CXXSRC += $(wildcard *.cpp)
ifeq ($(NEOPIXEL), 1)
CXXSRC += Adafruit_NeoPixel.cpp
endif
CXXSRC = WMath.cpp WString.cpp Print.cpp Marlin_main.cpp \
MarlinSerial.cpp Sd2Card.cpp SdBaseFile.cpp SdFatUtil.cpp \
SdFile.cpp SdVolume.cpp planner.cpp stepper.cpp \
temperature.cpp cardreader.cpp configuration_store.cpp \
watchdog.cpp SPI.cpp servo.cpp Tone.cpp ultralcd.cpp digipot_mcp4451.cpp \
dac_mcp4728.cpp vector_3.cpp qr_solve.cpp buzzer.cpp
ifeq ($(LIQUID_TWI2), 0)
CXXSRC += LiquidCrystal.cpp
else
@@ -469,15 +310,6 @@ SRC += twi.c
CXXSRC += Wire.cpp
endif
ifeq ($(U8GLIB), 1)
SRC += u8g_ll_api.c u8g_bitmap.c u8g_clip.c u8g_com_null.c u8g_delay.c u8g_page.c u8g_pb.c u8g_pb16h1.c u8g_rect.c u8g_state.c u8g_font.c u8g_font_data.c
endif
ifeq ($(RELOC_WORKAROUND), 1)
LD_PREFIX=-nodefaultlibs
LD_SUFFIX=-lm -lgcc -lc -lgcc -L$(ARDUINO_INSTALL_DIR)/hardware/tools/avr/avr/lib/avr6 -l$(MCU)
endif
#Check for Arduino 1.0.0 or higher and use the correct source files for that version
ifeq ($(shell [ $(ARDUINO_VERSION) -ge 100 ] && echo true), true)
CXXSRC += main.cpp
@@ -525,22 +357,25 @@ endif
CINCS = ${addprefix -I ,${VPATH}}
CXXINCS = ${addprefix -I ,${VPATH}}
# Compiler flag to set the C/CPP Standard level.
CSTANDARD = -std=gnu99
CXXSTANDARD = -std=gnu++11
# Compiler flag to set the C Standard level.
# c89 - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99 - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
#CSTANDARD = -std=gnu99
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -w -fsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -ffunction-sections -fdata-sections -flto \
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -w -ffunction-sections -fdata-sections \
-DARDUINO=$(ARDUINO_VERSION)
ifneq ($(HARDWARE_MOTHERBOARD),)
CTUNING += -DMOTHERBOARD=${HARDWARE_MOTHERBOARD}
endif
#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
CEXTRA = -fno-use-cxa-atexit -fno-threadsafe-statics
CEXTRA = -fno-use-cxa-atexit
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING) $(CSTANDARD)
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) -Wall $(CEXTRA) $(CTUNING) $(CXXSTANDARD)
CFLAGS := $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CEXTRA) $(CTUNING)
CXXFLAGS := $(CDEFS) $(CINCS) -O$(OPT) -Wall $(CEXTRA) $(CTUNING)
#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
LDFLAGS = -lm
@@ -655,7 +490,7 @@ extcoff: $(TARGET).elf
# Link: create ELF output file from library.
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
$(Pecho) " CXX $@"
$P $(CC) $(LD_PREFIX) $(ALL_CXXFLAGS) -Wl,--gc-sections,--relax -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
$P $(CC) $(ALL_CXXFLAGS) -Wl,--gc-sections -o $@ -L. $(OBJ) $(LDFLAGS)
$(BUILD_DIR)/%.o: %.c Configuration.h Configuration_adv.h $(MAKEFILE)
$(Pecho) " CC $<"

View File

@@ -29,66 +29,129 @@
#include <inttypes.h>
#include <util/delay.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/interrupt.h>
#include "MarlinConfig.h"
#ifdef DEBUG_GCODE_PARSER
#include "parser.h"
#endif
#include "enum.h"
#include "types.h"
#include "fastio.h"
#include "utility.h"
#include "serial.h"
#ifdef USBCON
#include "HardwareSerial.h"
#if ENABLED(BLUETOOTH)
#define MYSERIAL bluetoothSerial
#else
#define MYSERIAL Serial
#endif // BLUETOOTH
#else
#include "MarlinSerial.h"
#define MYSERIAL customizedSerial
#endif
#include "WString.h"
#if ENABLED(PRINTCOUNTER)
#include "printcounter.h"
#else
#include "stopwatch.h"
#endif
#define SERIAL_CHAR(x) MYSERIAL.write(x)
#define SERIAL_EOL SERIAL_CHAR('\n')
#define SERIAL_PROTOCOLCHAR(x) SERIAL_CHAR(x)
#define SERIAL_PROTOCOL(x) MYSERIAL.print(x)
#define SERIAL_PROTOCOL_F(x,y) MYSERIAL.print(x,y)
#define SERIAL_PROTOCOLPGM(x) serialprintPGM(PSTR(x))
#define SERIAL_PROTOCOLLN(x) do{ MYSERIAL.print(x); SERIAL_EOL; }while(0)
#define SERIAL_PROTOCOLLNPGM(x) do{ serialprintPGM(PSTR(x "\n")); }while(0)
#define SERIAL_PROTOCOLPAIR(name, value) SERIAL_ECHOPAIR(name, value)
extern const char errormagic[] PROGMEM;
extern const char echomagic[] PROGMEM;
#define SERIAL_ERROR_START serialprintPGM(errormagic)
#define SERIAL_ERROR(x) SERIAL_PROTOCOL(x)
#define SERIAL_ERRORPGM(x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_ERRORLN(x) SERIAL_PROTOCOLLN(x)
#define SERIAL_ERRORLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_ECHO_START serialprintPGM(echomagic)
#define SERIAL_ECHO(x) SERIAL_PROTOCOL(x)
#define SERIAL_ECHOPGM(x) SERIAL_PROTOCOLPGM(x)
#define SERIAL_ECHOLN(x) SERIAL_PROTOCOLLN(x)
#define SERIAL_ECHOLNPGM(x) SERIAL_PROTOCOLLNPGM(x)
#define SERIAL_ECHOPAIR(name,value) (serial_echopair_P(PSTR(name),(value)))
void serial_echopair_P(const char* s_P, char v);
void serial_echopair_P(const char* s_P, int v);
void serial_echopair_P(const char* s_P, long v);
void serial_echopair_P(const char* s_P, float v);
void serial_echopair_P(const char* s_P, double v);
void serial_echopair_P(const char* s_P, unsigned long v);
FORCE_INLINE void serial_echopair_P(const char* s_P, uint8_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, uint16_t v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, bool v) { serial_echopair_P(s_P, (int)v); }
FORCE_INLINE void serial_echopair_P(const char* s_P, void *v) { serial_echopair_P(s_P, (unsigned long)v); }
// Things to write to serial from Program memory. Saves 400 to 2k of RAM.
FORCE_INLINE void serialprintPGM(const char* str) {
char ch;
while ((ch = pgm_read_byte(str))) {
MYSERIAL.write(ch);
str++;
}
}
void idle(
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#if ENABLED(FILAMENT_CHANGE_FEATURE)
bool no_stepper_sleep = false // pass true to keep steppers from disabling on timeout
#endif
);
void manage_inactivity(const bool ignore_stepper_queue=false);
extern const char axis_codes[XYZE];
void manage_inactivity(bool ignore_stepper_queue = false);
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
extern bool extruder_duplication_enabled;
#endif
#if HAS_X2_ENABLE
#define enable_X() do{ X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); }while(0)
#define disable_X() do{ X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); CBI(axis_known_position, X_AXIS); }while(0)
#define enable_x() do{ X_ENABLE_WRITE( X_ENABLE_ON); X2_ENABLE_WRITE( X_ENABLE_ON); }while(0)
#define disable_x() do{ X_ENABLE_WRITE(!X_ENABLE_ON); X2_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }while(0)
#elif HAS_X_ENABLE
#define enable_X() X_ENABLE_WRITE( X_ENABLE_ON)
#define disable_X() do{ X_ENABLE_WRITE(!X_ENABLE_ON); CBI(axis_known_position, X_AXIS); }while(0)
#define enable_x() X_ENABLE_WRITE( X_ENABLE_ON)
#define disable_x() do{ X_ENABLE_WRITE(!X_ENABLE_ON); axis_known_position[X_AXIS] = false; }while(0)
#else
#define enable_X() NOOP
#define disable_X() NOOP
#define enable_x() NOOP
#define disable_x() NOOP
#endif
#if HAS_Y2_ENABLE
#define enable_Y() do{ Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }while(0)
#define disable_Y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); CBI(axis_known_position, Y_AXIS); }while(0)
#define enable_y() do{ Y_ENABLE_WRITE( Y_ENABLE_ON); Y2_ENABLE_WRITE(Y_ENABLE_ON); }while(0)
#define disable_y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); Y2_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }while(0)
#elif HAS_Y_ENABLE
#define enable_Y() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define disable_Y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); CBI(axis_known_position, Y_AXIS); }while(0)
#define enable_y() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define disable_y() do{ Y_ENABLE_WRITE(!Y_ENABLE_ON); axis_known_position[Y_AXIS] = false; }while(0)
#else
#define enable_Y() NOOP
#define disable_Y() NOOP
#define enable_y() NOOP
#define disable_y() NOOP
#endif
#if HAS_Z2_ENABLE
#define enable_Z() do{ Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }while(0)
#define disable_Z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); CBI(axis_known_position, Z_AXIS); }while(0)
#define enable_z() do{ Z_ENABLE_WRITE( Z_ENABLE_ON); Z2_ENABLE_WRITE(Z_ENABLE_ON); }while(0)
#define disable_z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); Z2_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }while(0)
#elif HAS_Z_ENABLE
#define enable_Z() Z_ENABLE_WRITE( Z_ENABLE_ON)
#define disable_Z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); CBI(axis_known_position, Z_AXIS); }while(0)
#define enable_z() Z_ENABLE_WRITE( Z_ENABLE_ON)
#define disable_z() do{ Z_ENABLE_WRITE(!Z_ENABLE_ON); axis_known_position[Z_AXIS] = false; }while(0)
#else
#define enable_Z() NOOP
#define disable_Z() NOOP
#define enable_z() NOOP
#define disable_z() NOOP
#endif
#if ENABLED(MIXING_EXTRUDER)
@@ -96,135 +159,79 @@ extern const char axis_codes[XYZE];
/**
* Mixing steppers synchronize their enable (and direction) together
*/
#if MIXING_STEPPERS > 4
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); E4_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); E4_ENABLE_WRITE(!E_ENABLE_ON); }
#elif MIXING_STEPPERS > 3
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); }
#if MIXING_STEPPERS > 3
#define enable_e0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); E3_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); E3_ENABLE_WRITE(!E_ENABLE_ON); }
#elif MIXING_STEPPERS > 2
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); }
#define enable_e0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); E2_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); E2_ENABLE_WRITE(!E_ENABLE_ON); }
#else
#define enable_E0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_E0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); }
#define enable_e0() { E0_ENABLE_WRITE( E_ENABLE_ON); E1_ENABLE_WRITE( E_ENABLE_ON); }
#define disable_e0() { E0_ENABLE_WRITE(!E_ENABLE_ON); E1_ENABLE_WRITE(!E_ENABLE_ON); }
#endif
#define enable_E1() NOOP
#define disable_E1() NOOP
#define enable_E2() NOOP
#define disable_E2() NOOP
#define enable_E3() NOOP
#define disable_E3() NOOP
#define enable_E4() NOOP
#define disable_E4() NOOP
#define enable_e1() NOOP
#define disable_e1() NOOP
#define enable_e2() NOOP
#define disable_e2() NOOP
#define enable_e3() NOOP
#define disable_e3() NOOP
#else // !MIXING_EXTRUDER
#if HAS_E0_ENABLE
#define enable_E0() E0_ENABLE_WRITE( E_ENABLE_ON)
#define disable_E0() E0_ENABLE_WRITE(!E_ENABLE_ON)
#define enable_e0() E0_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e0() E0_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_E0() NOOP
#define disable_E0() NOOP
#define enable_e0() NOOP
#define disable_e0() NOOP
#endif
#if E_STEPPERS > 1 && HAS_E1_ENABLE
#define enable_E1() E1_ENABLE_WRITE( E_ENABLE_ON)
#define disable_E1() E1_ENABLE_WRITE(!E_ENABLE_ON)
#define enable_e1() E1_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e1() E1_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_E1() NOOP
#define disable_E1() NOOP
#define enable_e1() NOOP
#define disable_e1() NOOP
#endif
#if E_STEPPERS > 2 && HAS_E2_ENABLE
#define enable_E2() E2_ENABLE_WRITE( E_ENABLE_ON)
#define disable_E2() E2_ENABLE_WRITE(!E_ENABLE_ON)
#define enable_e2() E2_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e2() E2_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_E2() NOOP
#define disable_E2() NOOP
#define enable_e2() NOOP
#define disable_e2() NOOP
#endif
#if E_STEPPERS > 3 && HAS_E3_ENABLE
#define enable_E3() E3_ENABLE_WRITE( E_ENABLE_ON)
#define disable_E3() E3_ENABLE_WRITE(!E_ENABLE_ON)
#define enable_e3() E3_ENABLE_WRITE( E_ENABLE_ON)
#define disable_e3() E3_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_E3() NOOP
#define disable_E3() NOOP
#endif
#if E_STEPPERS > 4 && HAS_E4_ENABLE
#define enable_E4() E4_ENABLE_WRITE( E_ENABLE_ON)
#define disable_E4() E4_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define enable_E4() NOOP
#define disable_E4() NOOP
#define enable_e3() NOOP
#define disable_e3() NOOP
#endif
#endif // !MIXING_EXTRUDER
#if ENABLED(HANGPRINTER)
#define enable_A() enable_X()
#define enable_B() enable_Y()
#define enable_C() enable_Z()
#define __D_ENABLE(p) E##p##_ENABLE_WRITE(E_ENABLE_ON)
#define _D_ENABLE(p) __D_ENABLE(p)
#define enable_D() _D_ENABLE(EXTRUDERS)
// Don't allow any axes to be disabled
#undef disable_X
#undef disable_Y
#undef disable_Z
#define disable_X() NOOP
#define disable_Y() NOOP
#define disable_Z() NOOP
#if EXTRUDERS >= 1
#undef disable_E1
#define disable_E1() NOOP
#if EXTRUDERS >= 2
#undef disable_E2
#define disable_E2() NOOP
#if EXTRUDERS >= 3
#undef disable_E3
#define disable_E3() NOOP
#if EXTRUDERS >= 4
#undef disable_E4
#define disable_E4() NOOP
#endif // EXTRUDERS >= 4
#endif // EXTRUDERS >= 3
#endif // EXTRUDERS >= 2
#endif // EXTRUDERS >= 1
#endif // HANGPRINTER
#if ENABLED(G38_PROBE_TARGET)
extern bool G38_move, // flag to tell the interrupt handler that a G38 command is being run
G38_endstop_hit; // flag from the interrupt handler to indicate if the endstop went active
#endif
/**
* The axis order in all axis related arrays is X, Y, Z, E
*/
#define _AXIS(AXIS) AXIS ##_AXIS
void enable_all_steppers();
void disable_e_stepper(const uint8_t e);
void disable_e_steppers();
void disable_all_steppers();
void sync_plan_position();
void sync_plan_position_e();
#if IS_KINEMATIC
void sync_plan_position_kinematic();
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position_kinematic()
#else
#define SYNC_PLAN_POSITION_KINEMATIC() sync_plan_position()
#endif
void flush_and_request_resend();
void FlushSerialRequestResend();
void ok_to_send();
void reset_bed_level();
void kill(const char*);
void quickstop_stepper();
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
void handle_filament_runout();
#endif
extern uint8_t marlin_debug_flags;
#define DEBUGGING(F) (marlin_debug_flags & (DEBUG_## F))
@@ -232,416 +239,160 @@ extern bool Running;
inline bool IsRunning() { return Running; }
inline bool IsStopped() { return !Running; }
bool enqueue_and_echo_command(const char* cmd); // Add a single command to the end of the buffer. Return false on failure.
void enqueue_and_echo_commands_P(const char * const cmd); // Set one or more commands to be prioritized over the next Serial/SD command.
bool enqueue_and_echo_command(const char* cmd, bool say_ok=false); //put a single ASCII command at the end of the current buffer or return false when it is full
void enqueue_and_echo_command_now(const char* cmd); // enqueue now, only return when the command has been enqueued
void enqueue_and_echo_commands_P(const char* cmd); //put one or many ASCII commands at the end of the current buffer, read from flash
void clear_command_queue();
#if ENABLED(M100_FREE_MEMORY_WATCHER) || ENABLED(POWER_LOSS_RECOVERY)
extern char command_queue[BUFSIZE][MAX_CMD_SIZE];
#endif
void clamp_to_software_endstops(float target[3]);
#define HAS_LCD_QUEUE_NOW (ENABLED(MALYAN_LCD) || (ENABLED(ULTIPANEL) && (ENABLED(AUTO_BED_LEVELING_UBL) || ENABLED(PID_AUTOTUNE_MENU) || ENABLED(ADVANCED_PAUSE_FEATURE))))
#define HAS_QUEUE_NOW (ENABLED(SDSUPPORT) || HAS_LCD_QUEUE_NOW)
#if HAS_QUEUE_NOW
// Return only when commands are actually enqueued
void enqueue_and_echo_command_now(const char* cmd);
#if HAS_LCD_QUEUE_NOW
void enqueue_and_echo_commands_now_P(const char * const cmd);
#endif
#endif
extern millis_t previous_cmd_ms;
inline void refresh_cmd_timeout() { previous_cmd_ms = millis(); }
extern millis_t previous_move_ms;
inline void reset_stepper_timeout() { previous_move_ms = millis(); }
#if ENABLED(FAST_PWM_FAN)
void setPwmFrequency(uint8_t pin, int val);
#endif
/**
* Feedrate scaling and conversion
*/
extern float feedrate_mm_s;
extern int16_t feedrate_percentage;
extern int feedrate_percentage;
#define MMS_SCALED(MM_S) ((MM_S)*feedrate_percentage*0.01f)
extern bool axis_relative_modes[XYZE];
extern uint8_t axis_homed, axis_known_position;
constexpr uint8_t xyz_bits = _BV(X_AXIS) | _BV(Y_AXIS) | _BV(Z_AXIS);
FORCE_INLINE bool all_axes_homed() { return (axis_homed & xyz_bits) == xyz_bits; }
FORCE_INLINE bool all_axes_known() { return (axis_known_position & xyz_bits) == xyz_bits; }
#define MMM_TO_MMS(MM_M) ((MM_M)/60.0)
#define MMS_TO_MMM(MM_S) ((MM_S)*60.0)
#define MMM_SCALED(MM_M) ((MM_M)*feedrate_percentage*0.01)
#define MMS_SCALED(MM_S) MMM_SCALED(MM_S)
#define MMM_TO_MMS_SCALED(MM_M) (MMS_SCALED(MMM_TO_MMS(MM_M)))
extern bool axis_relative_modes[];
extern bool volumetric_enabled;
extern int extruder_multiplier[EXTRUDERS]; // sets extrude multiply factor (in percent) for each extruder individually
extern float filament_size[EXTRUDERS]; // cross-sectional area of filament (in millimeters), typically around 1.75 or 2.85, 0 disables the volumetric calculations for the extruder.
extern float volumetric_multiplier[EXTRUDERS]; // reciprocal of cross-sectional area of filament (in square millimeters), stored this way to reduce computational burden in planner
extern bool axis_known_position[3]; // axis[n].is_known
extern bool axis_homed[3]; // axis[n].is_homed
extern volatile bool wait_for_heatup;
#if HAS_RESUME_CONTINUE
extern volatile bool wait_for_user;
#endif
extern float current_position[NUM_AXIS];
extern float position_shift[3];
extern float home_offset[3];
extern float sw_endstop_min[3];
extern float sw_endstop_max[3];
#if HAS_AUTO_REPORTING || ENABLED(HOST_KEEPALIVE_FEATURE)
extern bool suspend_auto_report;
#endif
#define LOGICAL_POSITION(POS, AXIS) (POS + home_offset[AXIS] + position_shift[AXIS])
#define RAW_POSITION(POS, AXIS) (POS - home_offset[AXIS] - position_shift[AXIS])
#define LOGICAL_X_POSITION(POS) LOGICAL_POSITION(POS, X_AXIS)
#define LOGICAL_Y_POSITION(POS) LOGICAL_POSITION(POS, Y_AXIS)
#define LOGICAL_Z_POSITION(POS) LOGICAL_POSITION(POS, Z_AXIS)
#define RAW_X_POSITION(POS) RAW_POSITION(POS, X_AXIS)
#define RAW_Y_POSITION(POS) RAW_POSITION(POS, Y_AXIS)
#define RAW_Z_POSITION(POS) RAW_POSITION(POS, Z_AXIS)
#define RAW_CURRENT_POSITION(AXIS) RAW_POSITION(current_position[AXIS], AXIS)
extern float current_position[XYZE], destination[XYZE];
/**
* Workspace offsets
*/
#if HAS_WORKSPACE_OFFSET
#if HAS_HOME_OFFSET
extern float home_offset[XYZ];
#endif
#if HAS_POSITION_SHIFT
extern float position_shift[XYZ];
#endif
#if HAS_HOME_OFFSET && HAS_POSITION_SHIFT
extern float workspace_offset[XYZ];
#define WORKSPACE_OFFSET(AXIS) workspace_offset[AXIS]
#elif HAS_HOME_OFFSET
#define WORKSPACE_OFFSET(AXIS) home_offset[AXIS]
#elif HAS_POSITION_SHIFT
#define WORKSPACE_OFFSET(AXIS) position_shift[AXIS]
#endif
#define NATIVE_TO_LOGICAL(POS, AXIS) ((POS) + WORKSPACE_OFFSET(AXIS))
#define LOGICAL_TO_NATIVE(POS, AXIS) ((POS) - WORKSPACE_OFFSET(AXIS))
#else
#define NATIVE_TO_LOGICAL(POS, AXIS) (POS)
#define LOGICAL_TO_NATIVE(POS, AXIS) (POS)
#endif
#define LOGICAL_X_POSITION(POS) NATIVE_TO_LOGICAL(POS, X_AXIS)
#define LOGICAL_Y_POSITION(POS) NATIVE_TO_LOGICAL(POS, Y_AXIS)
#define LOGICAL_Z_POSITION(POS) NATIVE_TO_LOGICAL(POS, Z_AXIS)
#define RAW_X_POSITION(POS) LOGICAL_TO_NATIVE(POS, X_AXIS)
#define RAW_Y_POSITION(POS) LOGICAL_TO_NATIVE(POS, Y_AXIS)
#define RAW_Z_POSITION(POS) LOGICAL_TO_NATIVE(POS, Z_AXIS)
// Hotend Offsets
#if HOTENDS > 1
extern float hotend_offset[XYZ][HOTENDS];
#endif
// Software Endstops
extern float soft_endstop_min[XYZ], soft_endstop_max[XYZ];
#if HAS_SOFTWARE_ENDSTOPS
extern bool soft_endstops_enabled;
void clamp_to_software_endstops(float target[XYZ]);
#else
#define soft_endstops_enabled false
#define clamp_to_software_endstops(x) NOOP
#endif
#if HAS_WORKSPACE_OFFSET || ENABLED(DUAL_X_CARRIAGE)
void update_software_endstops(const AxisEnum axis);
#endif
#define MAX_COORDINATE_SYSTEMS 9
#if ENABLED(CNC_COORDINATE_SYSTEMS)
extern float coordinate_system[MAX_COORDINATE_SYSTEMS][XYZ];
bool select_coordinate_system(const int8_t _new);
#endif
void tool_change(const uint8_t tmp_extruder, const float fr_mm_s=0.0, bool no_move=false);
void home_all_axes();
void report_current_position();
#if IS_KINEMATIC
#if ENABLED(HANGPRINTER)
extern float line_lengths[ABCD];
#else
extern float delta[ABC];
#endif
void inverse_kinematics(const float raw[XYZ]);
#endif
// GCode support for external objects
bool code_seen(char);
int code_value_int();
float code_value_temp_abs();
float code_value_temp_diff();
#if ENABLED(DELTA)
extern float delta_height,
delta_endstop_adj[ABC],
delta_radius,
delta_tower_angle_trim[ABC],
delta_tower[ABC][2],
delta_diagonal_rod,
delta_calibration_radius,
delta_diagonal_rod_2_tower[ABC],
delta_segments_per_second,
delta_clip_start_height;
void recalc_delta_settings();
float delta_safe_distance_from_top();
// Macro to obtain the Z position of an individual tower
#define DELTA_Z(V,T) V[Z_AXIS] + SQRT( \
delta_diagonal_rod_2_tower[T] - HYPOT2( \
delta_tower[T][X_AXIS] - V[X_AXIS], \
delta_tower[T][Y_AXIS] - V[Y_AXIS] \
) \
)
#define DELTA_IK(V) do { \
delta[A_AXIS] = DELTA_Z(V, A_AXIS); \
delta[B_AXIS] = DELTA_Z(V, B_AXIS); \
delta[C_AXIS] = DELTA_Z(V, C_AXIS); \
}while(0)
#elif ENABLED(HANGPRINTER)
// Don't collect anchor positions in array because there are no A_x, D_x or D_y
extern float anchor_A_y,
anchor_A_z,
anchor_B_x,
anchor_B_y,
anchor_B_z,
anchor_C_x,
anchor_C_y,
anchor_C_z,
anchor_D_z,
delta_segments_per_second,
line_lengths_origin[ABCD];
void recalc_hangprinter_settings();
#define HANGPRINTER_IK(V) do { \
line_lengths[A_AXIS] = SQRT(sq(anchor_A_z - V[Z_AXIS]) \
+ sq(anchor_A_y - V[Y_AXIS]) \
+ sq( V[X_AXIS])); \
line_lengths[B_AXIS] = SQRT(sq(anchor_B_z - V[Z_AXIS]) \
+ sq(anchor_B_y - V[Y_AXIS]) \
+ sq(anchor_B_x - V[X_AXIS])); \
line_lengths[C_AXIS] = SQRT(sq(anchor_C_z - V[Z_AXIS]) \
+ sq(anchor_C_y - V[Y_AXIS]) \
+ sq(anchor_C_x - V[X_AXIS])); \
line_lengths[D_AXIS] = SQRT(sq( V[X_AXIS]) \
+ sq( V[Y_AXIS]) \
+ sq(anchor_D_z - V[Z_AXIS])); \
}while(0)
// Inverse kinematics at origin
#define HANGPRINTER_IK_ORIGIN(LL) do { \
LL[A_AXIS] = SQRT(sq(anchor_A_z) \
+ sq(anchor_A_y)); \
LL[B_AXIS] = SQRT(sq(anchor_B_z) \
+ sq(anchor_B_y) \
+ sq(anchor_B_x)); \
LL[C_AXIS] = SQRT(sq(anchor_C_z) \
+ sq(anchor_C_y) \
+ sq(anchor_C_x)); \
LL[D_AXIS] = anchor_D_z; \
}while(0)
#elif IS_SCARA
void forward_kinematics_SCARA(const float &a, const float &b);
extern float delta[3];
extern float endstop_adj[3]; // axis[n].endstop_adj
extern float delta_radius;
extern float delta_diagonal_rod;
extern float delta_segments_per_second;
extern float delta_diagonal_rod_trim_tower_1;
extern float delta_diagonal_rod_trim_tower_2;
extern float delta_diagonal_rod_trim_tower_3;
void inverse_kinematics(const float cartesian[3]);
void recalc_delta_settings(float radius, float diagonal_rod);
#if ENABLED(AUTO_BED_LEVELING_FEATURE)
extern int delta_grid_spacing[2];
void adjust_delta(float cartesian[3]);
#endif
#elif ENABLED(SCARA)
extern float delta[3];
extern float axis_scaling[3]; // Build size scaling
void inverse_kinematics(const float cartesian[3]);
void forward_kinematics_SCARA(float f_scara[3]);
#endif
#if ENABLED(G26_MESH_VALIDATION)
extern bool g26_debug_flag;
#elif ENABLED(AUTO_BED_LEVELING_UBL)
constexpr bool g26_debug_flag = false;
#endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
#define _GET_MESH_X(I) (bilinear_start[X_AXIS] + (I) * bilinear_grid_spacing[X_AXIS])
#define _GET_MESH_Y(J) (bilinear_start[Y_AXIS] + (J) * bilinear_grid_spacing[Y_AXIS])
#elif ENABLED(AUTO_BED_LEVELING_UBL)
#define _GET_MESH_X(I) ubl.mesh_index_to_xpos(I)
#define _GET_MESH_Y(J) ubl.mesh_index_to_ypos(J)
#elif ENABLED(MESH_BED_LEVELING)
#define _GET_MESH_X(I) mbl.index_to_xpos[I]
#define _GET_MESH_Y(J) mbl.index_to_ypos[J]
#endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
extern int bilinear_grid_spacing[2], bilinear_start[2];
extern float bilinear_grid_factor[2],
z_values[GRID_MAX_POINTS_X][GRID_MAX_POINTS_Y];
float bilinear_z_offset(const float raw[XYZ]);
#endif
#if ENABLED(AUTO_BED_LEVELING_BILINEAR) || ENABLED(MESH_BED_LEVELING)
typedef float (*element_2d_fn)(const uint8_t, const uint8_t);
void print_2d_array(const uint8_t sx, const uint8_t sy, const uint8_t precision, const element_2d_fn fn);
#endif
#if HAS_LEVELING
bool leveling_is_valid();
void set_bed_leveling_enabled(const bool enable=true);
void reset_bed_level();
#endif
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
void set_z_fade_height(const float zfh, const bool do_report=true);
#if ENABLED(Z_DUAL_ENDSTOPS)
extern float z_endstop_adj;
#endif
#if HAS_BED_PROBE
extern float zprobe_zoffset;
bool set_probe_deployed(const bool deploy);
#ifdef Z_AFTER_PROBING
void move_z_after_probing();
#endif
enum ProbePtRaise : unsigned char {
PROBE_PT_NONE, // No raise or stow after run_z_probe
PROBE_PT_STOW, // Do a complete stow after run_z_probe
PROBE_PT_RAISE, // Raise to "between" clearance after run_z_probe
PROBE_PT_BIG_RAISE // Raise to big clearance after run_z_probe
};
float probe_pt(const float &rx, const float &ry, const ProbePtRaise raise_after=PROBE_PT_NONE, const uint8_t verbose_level=0, const bool probe_relative=true);
#define DEPLOY_PROBE() set_probe_deployed(true)
#define STOW_PROBE() set_probe_deployed(false)
#else
#define DEPLOY_PROBE()
#define STOW_PROBE()
#endif
#if ENABLED(HOST_KEEPALIVE_FEATURE)
extern MarlinBusyState busy_state;
#define KEEPALIVE_STATE(n) do{ busy_state = n; }while(0)
#else
#define KEEPALIVE_STATE(n) NOOP
extern uint8_t host_keepalive_interval;
#endif
#if FAN_COUNT > 0
extern int16_t fanSpeeds[FAN_COUNT];
#if ENABLED(EXTRA_FAN_SPEED)
extern int16_t old_fanSpeeds[FAN_COUNT],
new_fanSpeeds[FAN_COUNT];
#endif
#if ENABLED(PROBING_FANS_OFF)
extern bool fans_paused;
extern int16_t paused_fanSpeeds[FAN_COUNT];
#endif
#endif
#if ENABLED(USE_CONTROLLER_FAN)
extern int controllerFanSpeed;
extern int fanSpeeds[FAN_COUNT];
#endif
#if ENABLED(BARICUDA)
extern uint8_t baricuda_valve_pressure, baricuda_e_to_p_pressure;
extern int baricuda_valve_pressure;
extern int baricuda_e_to_p_pressure;
#endif
#if ENABLED(FILAMENT_WIDTH_SENSOR)
extern bool filament_sensor; // Flag that filament sensor readings should control extrusion
extern float filament_width_nominal, // Theoretical filament diameter i.e., 3.00 or 1.75
filament_width_meas; // Measured filament diameter
extern uint8_t meas_delay_cm; // Delay distance
extern int8_t measurement_delay[MAX_MEASUREMENT_DELAY + 1], // Ring buffer to delay measurement
filwidth_delay_index[2]; // Ring buffer indexes. Used by planner, temperature, and main code
extern float filament_width_nominal; //holds the theoretical filament diameter i.e., 3.00 or 1.75
extern bool filament_sensor; //indicates that filament sensor readings should control extrusion
extern float filament_width_meas; //holds the filament diameter as accurately measured
extern int8_t measurement_delay[]; //ring buffer to delay measurement
extern int filwidth_delay_index1, filwidth_delay_index2; //ring buffer index. used by planner, temperature, and main code
extern int meas_delay_cm; //delay distance
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE)
extern int8_t did_pause_print;
extern AdvancedPauseMenuResponse advanced_pause_menu_response;
extern float filament_change_unload_length[EXTRUDERS],
filament_change_load_length[EXTRUDERS];
#if ENABLED(FILAMENT_CHANGE_FEATURE)
extern FilamentChangeMenuResponse filament_change_menu_response;
#endif
#if HAS_POWER_SWITCH
extern bool powersupply_on;
#define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PS_ON_AWAKE); powersupply_on = true; }while(0)
#define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, PS_ON_ASLEEP); powersupply_on = false; }while(0)
#if ENABLED(PID_EXTRUSION_SCALING)
extern int lpq_len;
#endif
#if ENABLED(FWRETRACT)
extern bool autoretract_enabled;
extern bool retracted[EXTRUDERS]; // extruder[n].retracted
extern float retract_length, retract_length_swap, retract_feedrate_mm_s, retract_zlift;
extern float retract_recover_length, retract_recover_length_swap, retract_recover_feedrate_mm_s;
#endif
// Print job timer
#if ENABLED(PRINTCOUNTER)
extern PrintCounter print_job_timer;
#else
extern Stopwatch print_job_timer;
#endif
// Handling multiple extruders pins
extern uint8_t active_extruder;
#if HAS_TEMP_HOTEND || HAS_TEMP_BED
void print_heaterstates();
#endif
#if ENABLED(MIXING_EXTRUDER)
extern float mixing_factor[MIXING_STEPPERS];
#endif
inline void set_current_from_destination() { COPY(current_position, destination); }
inline void set_destination_from_current() { COPY(destination, current_position); }
void prepare_move_to_destination();
void calculate_volumetric_multipliers();
// Buzzer
#if HAS_BUZZER && PIN_EXISTS(BEEPER)
#include "buzzer.h"
#endif
/**
* Blocking movement and shorthand functions
*/
void do_blocking_move_to(const float rx, const float ry, const float rz, const float &fr_mm_s=0);
void do_blocking_move_to_x(const float &rx, const float &fr_mm_s=0);
void do_blocking_move_to_z(const float &rz, const float &fr_mm_s=0);
void do_blocking_move_to_xy(const float &rx, const float &ry, const float &fr_mm_s=0);
inline void do_blocking_move_to(float x, float y, float z, float fr_mm_m=0.0);
inline void do_blocking_move_to_x(float x, float fr_mm_m=0.0);
inline void do_blocking_move_to_z(float z, float fr_mm_m=0.0);
inline void do_blocking_move_to_xy(float x, float y, float fr_mm_m=0.0);
#if ENABLED(ARC_SUPPORT)
void plan_arc(const float(&cart)[XYZE], const float(&offset)[2], const bool clockwise);
#endif
#define HAS_AXIS_UNHOMED_ERR ( \
ENABLED(Z_PROBE_ALLEN_KEY) \
|| ENABLED(Z_PROBE_SLED) \
|| HAS_PROBING_PROCEDURE \
|| HOTENDS > 1 \
|| ENABLED(NOZZLE_CLEAN_FEATURE) \
|| ENABLED(NOZZLE_PARK_FEATURE) \
|| (ENABLED(ADVANCED_PAUSE_FEATURE) && ENABLED(HOME_BEFORE_FILAMENT_CHANGE)) \
|| HAS_M206_COMMAND \
) || ENABLED(NO_MOTION_BEFORE_HOMING)
#if HAS_AXIS_UNHOMED_ERR
bool axis_unhomed_error(const bool x=true, const bool y=true, const bool z=true);
#endif
/**
* position_is_reachable family of functions
*/
#if IS_KINEMATIC // (DELTA or SCARA)
#if IS_SCARA
extern const float L1, L2;
#endif
// Return true if the given point is within the printable area
inline bool position_is_reachable(const float &rx, const float &ry, const float inset=0) {
#if ENABLED(DELTA)
return HYPOT2(rx, ry) <= sq(DELTA_PRINTABLE_RADIUS - inset);
#elif ENABLED(HANGPRINTER)
// TODO: This is over simplified. Hangprinter's build volume is _not_ cylindrical.
return HYPOT2(rx, ry) <= sq(HANGPRINTER_PRINTABLE_RADIUS - inset);
#elif IS_SCARA
const float R2 = HYPOT2(rx - SCARA_OFFSET_X, ry - SCARA_OFFSET_Y);
return (
R2 <= sq(L1 + L2) - inset
#if MIDDLE_DEAD_ZONE_R > 0
&& R2 >= sq(float(MIDDLE_DEAD_ZONE_R))
#endif
);
#endif
}
#if HAS_BED_PROBE
// Return true if the both nozzle and the probe can reach the given point.
// Note: This won't work on SCARA since the probe offset rotates with the arm.
inline bool position_is_reachable_by_probe(const float &rx, const float &ry) {
return position_is_reachable(rx - (X_PROBE_OFFSET_FROM_EXTRUDER), ry - (Y_PROBE_OFFSET_FROM_EXTRUDER))
&& position_is_reachable(rx, ry, ABS(MIN_PROBE_EDGE));
}
#endif
#else // CARTESIAN
// Return true if the given position is within the machine bounds.
inline bool position_is_reachable(const float &rx, const float &ry) {
// Add 0.001 margin to deal with float imprecision
return WITHIN(rx, X_MIN_POS - 0.001f, X_MAX_POS + 0.001f)
&& WITHIN(ry, Y_MIN_POS - 0.001f, Y_MAX_POS + 0.001f);
}
#if HAS_BED_PROBE
/**
* Return whether the given position is within the bed, and whether the nozzle
* can reach the position required to put the probe at the given position.
*
* Example: For a probe offset of -10,+10, then for the probe to reach 0,0 the
* nozzle must be be able to reach +10,-10.
*/
inline bool position_is_reachable_by_probe(const float &rx, const float &ry) {
return position_is_reachable(rx - (X_PROBE_OFFSET_FROM_EXTRUDER), ry - (Y_PROBE_OFFSET_FROM_EXTRUDER))
&& WITHIN(rx, MIN_PROBE_X - 0.001f, MAX_PROBE_X + 0.001f)
&& WITHIN(ry, MIN_PROBE_Y - 0.001f, MAX_PROBE_Y + 0.001f);
}
#endif
#endif // CARTESIAN
#if !HAS_BED_PROBE
FORCE_INLINE bool position_is_reachable_by_probe(const float &rx, const float &ry) { return position_is_reachable(rx, ry); }
#endif
#endif // MARLIN_H
#endif //MARLIN_H

View File

@@ -1,53 +1,73 @@
/*
================================================================================
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
Marlin Firmware
/**
* About Marlin
*
* This firmware is a mashup between Sprinter and grbl.
* - https://github.com/kliment/Sprinter
* - https://github.com/simen/grbl/tree
*
* It has preliminary support for Matthew Roberts advance algorithm
* - http://reprap.org/pipermail/reprap-dev/2011-May/003323.html
*/
(c) 2011-2018 MarlinFirmware
Portions of Marlin are (c) by their respective authors.
All code complies with GPLv2 and/or GPLv3
/* All the implementation is done in *.cpp files to get better compatibility with avr-gcc without the Arduino IDE */
/* Use this file to help the Arduino IDE find which Arduino libraries are needed and to keep documentation on GCode */
================================================================================
#include "MarlinConfig.h"
Greetings! Thank you for choosing Marlin as your 3D printer firmware.
#if ENABLED(ULTRA_LCD)
#if ENABLED(LCD_I2C_TYPE_PCF8575)
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#elif ENABLED(LCD_I2C_TYPE_MCP23017) || ENABLED(LCD_I2C_TYPE_MCP23008)
#include <Wire.h>
#include <LiquidTWI2.h>
#elif ENABLED(LCM1602)
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>
#elif ENABLED(DOGLCD)
#include <U8glib.h> // library for graphics LCD by Oli Kraus (https://github.com/olikraus/U8glib_Arduino)
#else
#include <LiquidCrystal.h> // library for character LCD
#endif
#endif
To configure Marlin you must edit Configuration.h and Configuration_adv.h
located in the root 'Marlin' folder. Check the example_configurations folder to
see if there's a more suitable starting-point for your specific hardware.
#if HAS_DIGIPOTSS
#include <SPI.h>
#endif
Before diving in, we recommend the following essential links:
#if ENABLED(DIGIPOT_I2C)
#include <Wire.h>
#endif
Marlin Firmware Official Website
#if ENABLED(HAVE_TMCDRIVER)
#include <SPI.h>
#include <TMC26XStepper.h>
#endif
- http://marlinfw.org/
The official Marlin Firmware website contains the most up-to-date
documentation. Contributions are always welcome!
Configuration
- 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
- http://marlinfw.org/docs/configuration/configuration.html
Marlin's configuration options are explained in more detail here.
Getting Help
- http://forums.reprap.org/list.php?415
The Marlin Discussion Forum is a great place to get help from other Marlin
users who may have experienced similar issues to your own.
- https://github.com/MarlinFirmware/Marlin/issues
With a free GitHub account you can provide us with feedback, bug reports,
and feature requests via the Marlin Issue Queue.
Contributing
- http://marlinfw.org/docs/development/contributing.html
If you'd like to contribute to Marlin, read this first!
- http://marlinfw.org/docs/development/coding_standards.html
Before submitting code get to know the Coding Standards.
*/
#if ENABLED(HAVE_L6470DRIVER)
#include <SPI.h>
#include <L6470.h>
#endif

View File

@@ -23,26 +23,19 @@
#ifndef MARLIN_CONFIG_H
#define MARLIN_CONFIG_H
#include "boards.h"
#include "fastio.h"
#include "macros.h"
#include "boards.h"
#include "Version.h"
#include "Configuration.h"
#include "Conditionals_LCD.h"
#include "drivers.h"
#include "Configuration_adv.h"
#if USE_MARLINSERIAL
#include "pins.h"
#ifndef USBCON
#define HardwareSerial_h // trick to disable the standard HWserial
#endif
#include "types.h"
#include "HAL.h"
#include "pins.h"
#include "Arduino.h"
#include "Conditionals_post.h"
#include "SanityCheck.h"
#include "enum.h"
#include "language.h"
#include "utility.h"
#include "serial.h"
#endif // MARLIN_CONFIG_H

View File

@@ -1,57 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __MARLIN_SPI_H__
#define __MARLIN_SPI_H__
#include <stdint.h>
#include "softspi.h"
template<uint8_t MisoPin, uint8_t MosiPin, uint8_t SckPin>
class SPI {
static SoftSPI<MisoPin, MosiPin, SckPin> softSPI;
public:
FORCE_INLINE static void init() { softSPI.begin(); }
FORCE_INLINE static void send(uint8_t data) { softSPI.send(data); }
FORCE_INLINE static uint8_t receive() { return softSPI.receive(); }
};
// Hardware SPI
template<>
class SPI<MISO_PIN, MOSI_PIN, SCK_PIN> {
public:
FORCE_INLINE static void init() {
OUT_WRITE(SCK_PIN, LOW);
OUT_WRITE(MOSI_PIN, HIGH);
SET_INPUT(MISO_PIN);
WRITE(MISO_PIN, HIGH);
}
FORCE_INLINE static uint8_t receive() {
SPDR = 0;
while (!TEST(SPSR, SPIF)) { /* nada */ }
return SPDR;
}
};
#endif // __MARLIN_SPI_H__

File diff suppressed because it is too large Load Diff

View File

@@ -21,16 +21,16 @@
*/
/**
* MarlinSerial.h - Hardware serial library for Wiring
* Copyright (c) 2006 Nicholas Zambetti. All right reserved.
*
* Modified 28 September 2010 by Mark Sproul
* Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
* Modified 01 October 2017 by Eduardo José Tagle (added XON/XOFF)
*/
MarlinSerial.h - Hardware serial library for Wiring
Copyright (c) 2006 Nicholas Zambetti. All right reserved.
#ifndef _MARLINSERIAL_H_
#define _MARLINSERIAL_H_
Modified 28 September 2010 by Mark Sproul
Modified 14 February 2016 by Andreas Hardtung (added tx buffer)
*/
#ifndef MarlinSerial_h
#define MarlinSerial_h
#include "MarlinConfig.h"
@@ -52,133 +52,130 @@
#define SERIAL_REGNAME_INTERNAL(registerbase,number,suffix) registerbase##number##suffix
#endif
// Registers used by MarlinSerial class (expanded depending on selected serial port)
#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number
#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B)
#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,)
#define M_TXENx SERIAL_REGNAME(TXEN,SERIAL_PORT,)
#define M_TXCx SERIAL_REGNAME(TXC,SERIAL_PORT,)
#define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,)
#define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,)
#define M_FEx SERIAL_REGNAME(FE,SERIAL_PORT,)
#define M_DORx SERIAL_REGNAME(DOR,SERIAL_PORT,)
#define M_UPEx SERIAL_REGNAME(UPE,SERIAL_PORT,)
#define M_UDRIEx SERIAL_REGNAME(UDRIE,SERIAL_PORT,)
#define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,)
#define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H)
#define M_UBRRxL SERIAL_REGNAME(UBRR,SERIAL_PORT,L)
#define M_RXCx SERIAL_REGNAME(RXC,SERIAL_PORT,)
#define M_USARTx_RX_vect SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)
#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,)
// Registers used by MarlinSerial class (these are expanded
// depending on selected serial port
#define M_UCSRxA SERIAL_REGNAME(UCSR,SERIAL_PORT,A) // defines M_UCSRxA to be UCSRnA where n is the serial port number
#define M_UCSRxB SERIAL_REGNAME(UCSR,SERIAL_PORT,B)
#define M_RXENx SERIAL_REGNAME(RXEN,SERIAL_PORT,)
#define M_TXENx SERIAL_REGNAME(TXEN,SERIAL_PORT,)
#define M_TXCx SERIAL_REGNAME(TXC,SERIAL_PORT,)
#define M_RXCIEx SERIAL_REGNAME(RXCIE,SERIAL_PORT,)
#define M_UDREx SERIAL_REGNAME(UDRE,SERIAL_PORT,)
#define M_UDRIEx SERIAL_REGNAME(UDRIE,SERIAL_PORT,)
#define M_UDRx SERIAL_REGNAME(UDR,SERIAL_PORT,)
#define M_UBRRxH SERIAL_REGNAME(UBRR,SERIAL_PORT,H)
#define M_UBRRxL SERIAL_REGNAME(UBRR,SERIAL_PORT,L)
#define M_RXCx SERIAL_REGNAME(RXC,SERIAL_PORT,)
#define M_USARTx_RX_vect SERIAL_REGNAME(USART,SERIAL_PORT,_RX_vect)
#define M_U2Xx SERIAL_REGNAME(U2X,SERIAL_PORT,)
#define M_USARTx_UDRE_vect SERIAL_REGNAME(USART,SERIAL_PORT,_UDRE_vect)
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0
// Define constants and variables for buffering serial data.
// Use only 0 or powers of 2 greater than 1
// : [0, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, ...]
#ifndef USBCON
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
// is the index of the location from which to read.
// 256 is the max limit due to uint8_t head and tail. Use only powers of 2. (...,16,32,64,128,256)
#ifndef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128
#endif
// 256 is the max TX buffer limit due to uint8_t head and tail.
#ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32
#endif
#if !((RX_BUFFER_SIZE == 256) ||(RX_BUFFER_SIZE == 128) ||(RX_BUFFER_SIZE == 64) ||(RX_BUFFER_SIZE == 32) ||(RX_BUFFER_SIZE == 16) ||(RX_BUFFER_SIZE == 8) ||(RX_BUFFER_SIZE == 4) ||(RX_BUFFER_SIZE == 2))
#error "RX_BUFFER_SIZE has to be a power of 2 and >= 2"
#endif
#if !((TX_BUFFER_SIZE == 256) ||(TX_BUFFER_SIZE == 128) ||(TX_BUFFER_SIZE == 64) ||(TX_BUFFER_SIZE == 32) ||(TX_BUFFER_SIZE == 16) ||(TX_BUFFER_SIZE == 8) ||(TX_BUFFER_SIZE == 4) ||(TX_BUFFER_SIZE == 2) ||(TX_BUFFER_SIZE == 0))
#error TX_BUFFER_SIZE has to be a power of 2 or 0
#endif
#if USE_MARLINSERIAL
struct ring_buffer_r {
unsigned char buffer[RX_BUFFER_SIZE];
volatile uint8_t head;
volatile uint8_t tail;
};
#if RX_BUFFER_SIZE > 256
typedef uint16_t ring_buffer_pos_t;
#else
typedef uint8_t ring_buffer_pos_t;
#endif
#if ENABLED(SERIAL_STATS_DROPPED_RX)
extern uint8_t rx_dropped_bytes;
#endif
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
extern uint8_t rx_buffer_overruns;
#endif
#if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS)
extern uint8_t rx_framing_errors;
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
extern ring_buffer_pos_t rx_max_enqueued;
#endif
class MarlinSerial {
public:
MarlinSerial() {};
static void begin(const long);
static void end();
static int peek(void);
static int read(void);
static void flush(void);
static ring_buffer_pos_t available(void);
static void write(const uint8_t c);
static void flushTX(void);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE static uint32_t dropped() { return rx_dropped_bytes; }
#endif
#if ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS)
FORCE_INLINE static uint32_t buffer_overruns() { return rx_buffer_overruns; }
#endif
#if ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS)
FORCE_INLINE static uint32_t framing_errors() { return rx_framing_errors; }
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return rx_max_enqueued; }
#endif
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE static void print(const char* str) { write(str); }
static void print(char, int = BYTE);
static void print(unsigned char, int = BYTE);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = BYTE);
static void println(unsigned char, int = BYTE);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println(void);
operator bool() { return true; }
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
#if TX_BUFFER_SIZE > 0
struct ring_buffer_t {
unsigned char buffer[TX_BUFFER_SIZE];
volatile uint8_t head;
volatile uint8_t tail;
};
#endif
extern MarlinSerial customizedSerial;
#if UART_PRESENT(SERIAL_PORT)
extern ring_buffer_r rx_buffer;
#if TX_BUFFER_SIZE > 0
extern ring_buffer_t tx_buffer;
#endif
#endif
#endif // USE_MARLINSERIAL
#if ENABLED(EMERGENCY_PARSER)
#include "language.h"
void emergency_parser(unsigned char c);
#endif
class MarlinSerial { //: public Stream
public:
MarlinSerial();
void begin(long);
void end();
int peek(void);
int read(void);
void flush(void);
uint8_t available(void);
void checkRx(void);
void write(uint8_t c);
#if TX_BUFFER_SIZE > 0
uint8_t availableForWrite(void);
void flushTX(void);
#endif
private:
void printNumber(unsigned long, uint8_t);
void printFloat(double, uint8_t);
public:
FORCE_INLINE void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE void print(const char* str) { write(str); }
void print(char, int = BYTE);
void print(unsigned char, int = BYTE);
void print(int, int = DEC);
void print(unsigned int, int = DEC);
void print(long, int = DEC);
void print(unsigned long, int = DEC);
void print(double, int = 2);
void println(const String& s);
void println(const char[]);
void println(char, int = BYTE);
void println(unsigned char, int = BYTE);
void println(int, int = DEC);
void println(unsigned int, int = DEC);
void println(long, int = DEC);
void println(unsigned long, int = DEC);
void println(double, int = 2);
void println(void);
};
extern MarlinSerial customizedSerial;
#endif // !USBCON
// Use the UART for Bluetooth in AT90USB configurations
#if !USE_MARLINSERIAL && ENABLED(BLUETOOTH)
#if defined(USBCON) && ENABLED(BLUETOOTH)
extern HardwareSerial bluetoothSerial;
#endif
#endif // _MARLINSERIAL_H_
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,593 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* This module is off by default, but can be enabled to facilitate the display of
* extra debug information during code development.
*
* Just connect up 5V and GND to give it power, then connect up the pins assigned
* in Configuration_adv.h. For example, on the Re-ARM you could use:
*
* #define MAX7219_CLK_PIN 77
* #define MAX7219_DIN_PIN 78
* #define MAX7219_LOAD_PIN 79
*
* send() is called automatically at startup, and then there are a number of
* support functions available to control the LEDs in the 8x8 grid.
*/
#include "MarlinConfig.h"
#if ENABLED(MAX7219_DEBUG)
#define MAX7219_ERRORS // Disable to save 406 bytes of Program Memory
#include "Max7219_Debug_LEDs.h"
#include "planner.h"
#include "stepper.h"
#include "Marlin.h"
#include "delay.h"
Max7219 max7219;
uint8_t Max7219::led_line[MAX7219_LINES]; // = { 0 };
#define LINE_REG(Q) (max7219_reg_digit0 + ((Q) & 0x7))
#if _ROT == 0 || _ROT == 270
#define _LED_BIT(Q) (7 - ((Q) & 0x7))
#define _LED_UNIT(Q) ((Q) & ~0x7)
#else
#define _LED_BIT(Q) ((Q) & 0x7)
#define _LED_UNIT(Q) ((MAX7219_NUMBER_UNITS - 1 - ((Q) >> 3)) << 3)
#endif
#if _ROT < 180
#define _LED_IND(P,Q) (_LED_UNIT(P) + (Q))
#else
#define _LED_IND(P,Q) (_LED_UNIT(P) + (7 - ((Q) & 0x7)))
#endif
#if _ROT == 0 || _ROT == 180
#define LED_IND(X,Y) _LED_IND(X,Y)
#define LED_BIT(X,Y) _LED_BIT(X)
#elif _ROT == 90 || _ROT == 270
#define LED_IND(X,Y) _LED_IND(Y,X)
#define LED_BIT(X,Y) _LED_BIT(Y)
#endif
#define XOR_7219(X,Y) do{ led_line[LED_IND(X,Y)] ^= _BV(LED_BIT(X,Y)); }while(0)
#define SET_7219(X,Y) do{ led_line[LED_IND(X,Y)] |= _BV(LED_BIT(X,Y)); }while(0)
#define CLR_7219(X,Y) do{ led_line[LED_IND(X,Y)] &= ~_BV(LED_BIT(X,Y)); }while(0)
#define BIT_7219(X,Y) TEST(led_line[LED_IND(X,Y)], LED_BIT(X,Y))
#ifdef CPU_32_BIT
#define SIG_DELAY() DELAY_US(1) // Approximate a 1µs delay on 32-bit ARM
#undef CRITICAL_SECTION_START
#undef CRITICAL_SECTION_END
#define CRITICAL_SECTION_START NOOP
#define CRITICAL_SECTION_END NOOP
#else
#define SIG_DELAY() DELAY_NS(188) // Delay for 0.1875µs (16MHz AVR) or 0.15µs (20MHz AVR)
#endif
void Max7219::error(const char * const func, const int32_t v1, const int32_t v2/*=-1*/) {
#if ENABLED(MAX7219_ERRORS)
SERIAL_ECHOPGM("??? Max7219::");
serialprintPGM(func);
SERIAL_CHAR('(');
SERIAL_ECHO(v1);
if (v2 > 0) SERIAL_ECHOPAIR(", ", v2);
SERIAL_CHAR(')');
SERIAL_EOL();
#else
UNUSED(func); UNUSED(v1); UNUSED(v2);
#endif
}
/**
* Flip the lowest n_bytes of the supplied bits:
* flipped(x, 1) flips the low 8 bits of x.
* flipped(x, 2) flips the low 16 bits of x.
* flipped(x, 3) flips the low 24 bits of x.
* flipped(x, 4) flips the low 32 bits of x.
*/
inline uint32_t flipped(const uint32_t bits, const uint8_t n_bytes) {
uint32_t mask = 1, outbits = 0;
for (uint8_t b = 0; b < n_bytes * 8; b++) {
outbits <<= 1;
if (bits & mask) outbits |= 1;
mask <<= 1;
}
return outbits;
}
void Max7219::noop() {
CRITICAL_SECTION_START;
SIG_DELAY();
WRITE(MAX7219_DIN_PIN, LOW);
for (uint8_t i = 16; i--;) {
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, LOW);
SIG_DELAY();
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, HIGH);
SIG_DELAY();
}
CRITICAL_SECTION_END;
}
void Max7219::putbyte(uint8_t data) {
CRITICAL_SECTION_START;
for (uint8_t i = 8; i--;) {
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, LOW); // tick
SIG_DELAY();
WRITE(MAX7219_DIN_PIN, (data & 0x80) ? HIGH : LOW); // send 1 or 0 based on data bit
SIG_DELAY();
WRITE(MAX7219_CLK_PIN, HIGH); // tock
SIG_DELAY();
data <<= 1;
}
CRITICAL_SECTION_END;
}
void Max7219::pulse_load() {
SIG_DELAY();
WRITE(MAX7219_LOAD_PIN, LOW); // tell the chip to load the data
SIG_DELAY();
WRITE(MAX7219_LOAD_PIN, HIGH);
SIG_DELAY();
}
void Max7219::send(const uint8_t reg, const uint8_t data) {
SIG_DELAY();
CRITICAL_SECTION_START;
SIG_DELAY();
putbyte(reg); // specify register
SIG_DELAY();
putbyte(data); // put data
CRITICAL_SECTION_END;
}
// Send out a single native row of bits to all units
void Max7219::refresh_line(const uint8_t line) {
for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
send(LINE_REG(line), led_line[(u << 3) | (line & 0x7)]);
pulse_load();
}
// Send out a single native row of bits to just one unit
void Max7219::refresh_unit_line(const uint8_t line) {
for (uint8_t u = MAX7219_NUMBER_UNITS; u--;)
if (u == (line >> 3)) send(LINE_REG(line), led_line[line]); else noop();
pulse_load();
}
void Max7219::set(const uint8_t line, const uint8_t bits) {
led_line[line] = bits;
refresh_line(line);
}
#if ENABLED(MAX7219_NUMERIC)
// Draw an integer with optional leading zeros and optional decimal point
void Max7219::print(const uint8_t start, int16_t value, uint8_t size, const bool leadzero=false, bool dec=false) {
constexpr uint8_t led_numeral[10] = { 0x7E, 0x60, 0x6D, 0x79, 0x63, 0x5B, 0x5F, 0x70, 0x7F, 0x7A },
led_decimal = 0x80, led_minus = 0x01;
bool blank = false, neg = value < 0;
if (neg) value *= -1;
while (size--) {
const bool minus = neg && blank;
if (minus) neg = false;
send(
max7219_reg_digit0 + start + size,
minus ? led_minus : blank ? 0x00 : led_numeral[value % 10] | (dec ? led_decimal : 0x00)
);
pulse_load(); // tell the chips to load the clocked out data
value /= 10;
if (!value && !leadzero) blank = true;
dec = false;
}
}
// Draw a float with a decimal point and optional digits
void Max7219::print(const uint8_t start, const float value, const uint8_t pre_size, const uint8_t post_size, const bool leadzero=false) {
if (pre_size) print(start, value, pre_size, leadzero, !!post_size);
if (post_size) {
const int16_t after = ABS(value) * (10 ^ post_size);
print(start + pre_size, after, post_size, true);
}
}
#endif // MAX7219_NUMERIC
// Modify a single LED bit and send the changed line
void Max7219::led_set(const uint8_t x, const uint8_t y, const bool on) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_set"), x, y);
if (BIT_7219(x, y) == on) return;
XOR_7219(x, y);
refresh_line(LED_IND(x, y));
}
void Max7219::led_on(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_on"), x, y);
led_set(x, y, true);
}
void Max7219::led_off(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_off"), x, y);
led_set(x, y, false);
}
void Max7219::led_toggle(const uint8_t x, const uint8_t y) {
if (x > MAX7219_X_LEDS - 1 || y > MAX7219_Y_LEDS - 1) return error(PSTR("led_toggle"), x, y);
led_set(x, y, !BIT_7219(x, y));
}
void Max7219::send_row(const uint8_t row) {
#if _ROT == 0 || _ROT == 180
refresh_line(LED_IND(0, row));
#else
UNUSED(row);
refresh();
#endif
}
void Max7219::send_column(const uint8_t col) {
#if _ROT == 90 || _ROT == 270
refresh_line(LED_IND(col, 0));
#else
UNUSED(col);
refresh();
#endif
}
void Max7219::clear() {
ZERO(led_line);
refresh();
}
void Max7219::fill() {
memset(led_line, 0xFF, sizeof(led_line));
refresh();
}
void Max7219::clear_row(const uint8_t row) {
if (row >= MAX7219_Y_LEDS) return error(PSTR("clear_row"), row);
for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) CLR_7219(x, row);
send_row(row);
}
void Max7219::clear_column(const uint8_t col) {
if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) CLR_7219(col, y);
send_column(col);
}
/**
* Plot the low order bits of val to the specified row of the matrix.
* With 4 Max7219 units in the chain, it's possible to set 32 bits at once with
* one call to the function (if rotated 90° or 180°).
*/
void Max7219::set_row(const uint8_t row, const uint32_t val) {
if (row >= MAX7219_Y_LEDS) return error(PSTR("set_row"), row);
uint32_t mask = _BV32(MAX7219_X_LEDS - 1);
for (uint8_t x = 0; x < MAX7219_X_LEDS; x++) {
if (val & mask) SET_7219(x, row); else CLR_7219(x, row);
mask >>= 1;
}
send_row(row);
}
/**
* Plot the low order bits of val to the specified column of the matrix.
* With 4 Max7219 units in the chain, it's possible to set 32 bits at once with
* one call to the function (if rotated 90° or 180°).
*/
void Max7219::set_column(const uint8_t col, const uint32_t val) {
if (col >= MAX7219_X_LEDS) return error(PSTR("set_column"), col);
uint32_t mask = _BV32(MAX7219_Y_LEDS - 1);
for (uint8_t y = 0; y < MAX7219_Y_LEDS; y++) {
if (val & mask) SET_7219(col, y); else CLR_7219(col, y);
mask >>= 1;
}
send_column(col);
}
void Max7219::set_rows_16bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_16bits"), y, val);
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#else // at least 16 bits on each row
if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_16bits"), y, val);
set_row(y, val);
#endif
}
void Max7219::set_rows_32bits(const uint8_t y, uint32_t val) {
#if MAX7219_X_LEDS == 8
if (y > MAX7219_Y_LEDS - 4) return error(PSTR("set_rows_32bits"), y, val);
set_row(y + 3, val); val >>= 8;
set_row(y + 2, val); val >>= 8;
set_row(y + 1, val); val >>= 8;
set_row(y + 0, val);
#elif MAX7219_X_LEDS == 16
if (y > MAX7219_Y_LEDS - 2) return error(PSTR("set_rows_32bits"), y, val);
set_row(y + 1, val); val >>= 16;
set_row(y + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
if (y > MAX7219_Y_LEDS - 1) return error(PSTR("set_rows_32bits"), y, val);
set_row(y, val);
#endif
}
void Max7219::set_columns_16bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_columns_16bits"), x, val);
set_column(x + 0, val); val >>= 8;
set_column(x + 1, val);
#else // at least 16 bits in each column
if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_columns_16bits"), x, val);
set_column(x, val);
#endif
}
void Max7219::set_columns_32bits(const uint8_t x, uint32_t val) {
#if MAX7219_Y_LEDS == 8
if (x > MAX7219_X_LEDS - 4) return error(PSTR("set_rows_32bits"), x, val);
set_column(x + 3, val); val >>= 8;
set_column(x + 2, val); val >>= 8;
set_column(x + 1, val); val >>= 8;
set_column(x + 0, val);
#elif MAX7219_Y_LEDS == 16
if (x > MAX7219_X_LEDS - 2) return error(PSTR("set_rows_32bits"), x, val);
set_column(x + 1, val); val >>= 16;
set_column(x + 0, val);
#else // at least 24 bits on each row. In the 3 matrix case, just display the low 24 bits
if (x > MAX7219_X_LEDS - 1) return error(PSTR("set_rows_32bits"), x, val);
set_column(x, val);
#endif
}
// Initialize the Max7219
void Max7219::register_setup() {
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_scanLimit, 0x07);
pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_decodeMode, 0x00); // using an led matrix (not digits)
pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_shutdown, 0x01); // not in shutdown mode
pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_displayTest, 0x00); // no display test
pulse_load(); // tell the chips to load the clocked out data
for (uint8_t i = 0; i < MAX7219_NUMBER_UNITS; i++)
send(max7219_reg_intensity, 0x01 & 0x0F); // the first 0x0F is the value you can set
// range: 0x00 to 0x0F
pulse_load(); // tell the chips to load the clocked out data
}
#ifdef MAX7219_INIT_TEST
#if MAX7219_INIT_TEST == 2
void Max7219::spiral(const bool on, const uint16_t del) {
constexpr int8_t way[] = { 1, 0, 0, 1, -1, 0, 0, -1 };
int8_t px = 0, py = 0, dir = 0;
for (uint8_t i = MAX7219_X_LEDS * MAX7219_Y_LEDS; i--;) {
led_set(px, py, on);
delay(del);
const int8_t x = px + way[dir], y = py + way[dir + 1];
if (!WITHIN(x, 0, MAX7219_X_LEDS-1) || !WITHIN(y, 0, MAX7219_Y_LEDS-1) || BIT_7219(x, y) == on) dir = (dir + 2) & 0x7;
px += way[dir]; py += way[dir + 1];
}
}
#else
void Max7219::sweep(const int8_t dir, const uint16_t ms, const bool on) {
uint8_t x = dir > 0 ? 0 : MAX7219_X_LEDS-1;
for (uint8_t i = MAX7219_X_LEDS; i--; x += dir) {
set_column(x, on ? 0xFFFFFFFF : 0x00000000);
delay(ms);
}
}
#endif
#endif // MAX7219_INIT_TEST
void Max7219::init() {
SET_OUTPUT(MAX7219_DIN_PIN);
SET_OUTPUT(MAX7219_CLK_PIN);
OUT_WRITE(MAX7219_LOAD_PIN, HIGH);
delay(1);
register_setup();
for (uint8_t i = 0; i <= 7; i++) { // Empty registers to turn all LEDs off
led_line[i] = 0x00;
send(max7219_reg_digit0 + i, 0);
pulse_load(); // tell the chips to load the clocked out data
}
#ifdef MAX7219_INIT_TEST
#if MAX7219_INIT_TEST == 2
spiral(true, 8);
delay(150);
spiral(false, 8);
#else
// Do an aesthetically-pleasing pattern to fully test the Max7219 module and LEDs.
// Light up and turn off columns, both forward and backward.
sweep(1, 20, true);
sweep(1, 20, false);
delay(150);
sweep(-1, 20, true);
sweep(-1, 20, false);
#endif
#endif
}
/**
* This code demonstrates some simple debugging using a single 8x8 LED Matrix. If your feature could
* benefit from matrix display, add its code here. Very little processing is required, so the 7219 is
* ideal for debugging when realtime feedback is important but serial output can't be used.
*/
// Apply changes to update a marker
void Max7219::mark16(const uint8_t y, const uint8_t v1, const uint8_t v2) {
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
led_off(v1 & 0x7, y + (v1 >= 8));
led_on(v2 & 0x7, y + (v2 >= 8));
#else
led_off(y, v1 & 0xF); // At least 16 LEDs down. Use a single column.
led_on(y, v2 & 0xF);
#endif
#else
led_off(v1 & 0xF, y); // At least 16 LEDs across. Use a single row.
led_on(v2 & 0xF, y);
#endif
}
// Apply changes to update a tail-to-head range
void Max7219::range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh) {
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
led_off(n & 0x7, y + (n >= 8));
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
led_on(n & 0x7, y + (n >= 8));
#else // The Max7219 Y-Axis has at least 16 LED's. So use a single column
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
led_off(y, n & 0xF);
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
led_on(y, n & 0xF);
#endif
#else // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
if (ot != nt) for (uint8_t n = ot & 0xF; n != (nt & 0xF) && n != (nh & 0xF); n = (n + 1) & 0xF)
led_off(n & 0xF, y);
if (oh != nh) for (uint8_t n = (oh + 1) & 0xF; n != ((nh + 1) & 0xF); n = (n + 1) & 0xF)
led_on(n & 0xF, y);
#endif
}
// Apply changes to update a quantity
void Max7219::quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv) {
for (uint8_t i = MIN(nv, ov); i < MAX(nv, ov); i++)
#if MAX7219_X_LEDS == 8
#if MAX7219_Y_LEDS == 8
led_set(i >> 1, y + (i & 1), nv >= ov); // single 8x8 LED matrix. Use two lines to get 16 LED's
#else
led_set(y, i, nv >= ov); // The Max7219 Y-Axis has at least 16 LED's. So use a single column
#endif
#else
led_set(i, y, nv >= ov); // LED matrix has at least 16 LED's on the X-Axis. Use single line of LED's
#endif
}
void Max7219::idle_tasks() {
#define MAX7219_USE_HEAD (defined(MAX7219_DEBUG_PLANNER_HEAD) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#define MAX7219_USE_TAIL (defined(MAX7219_DEBUG_PLANNER_TAIL) || defined(MAX7219_DEBUG_PLANNER_QUEUE))
#if MAX7219_USE_HEAD || MAX7219_USE_TAIL
CRITICAL_SECTION_START;
#if MAX7219_USE_HEAD
const uint8_t head = planner.block_buffer_head;
#endif
#if MAX7219_USE_TAIL
const uint8_t tail = planner.block_buffer_tail;
#endif
CRITICAL_SECTION_END;
#endif
#if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
static uint8_t refresh_cnt; // = 0
constexpr uint16_t refresh_limit = 5;
static millis_t next_blink = 0;
const millis_t ms = millis();
const bool do_blink = ELAPSED(ms, next_blink);
#else
static uint16_t refresh_cnt; // = 0
constexpr bool do_blink = true;
constexpr uint16_t refresh_limit = 50000;
#endif
// Some Max7219 units are vulnerable to electrical noise, especially
// with long wires next to high current wires. If the display becomes
// corrupted, this will fix it within a couple seconds.
if (do_blink && ++refresh_cnt >= refresh_limit) {
refresh_cnt = 0;
register_setup();
}
#if ENABLED(MAX7219_DEBUG_PRINTER_ALIVE)
if (do_blink) {
led_toggle(MAX7219_X_LEDS - 1, MAX7219_Y_LEDS - 1);
next_blink = ms + 1000;
}
#endif
#if defined(MAX7219_DEBUG_PLANNER_HEAD) && defined(MAX7219_DEBUG_PLANNER_TAIL) && MAX7219_DEBUG_PLANNER_HEAD == MAX7219_DEBUG_PLANNER_TAIL
static int16_t last_head_cnt = 0xF, last_tail_cnt = 0xF;
if (last_head_cnt != head || last_tail_cnt != tail) {
range16(MAX7219_DEBUG_PLANNER_HEAD, last_tail_cnt, tail, last_head_cnt, head);
last_head_cnt = head;
last_tail_cnt = tail;
}
#else
#ifdef MAX7219_DEBUG_PLANNER_HEAD
static int16_t last_head_cnt = 0x1;
if (last_head_cnt != head) {
mark16(MAX7219_DEBUG_PLANNER_HEAD, last_head_cnt, head);
last_head_cnt = head;
}
#endif
#ifdef MAX7219_DEBUG_PLANNER_TAIL
static int16_t last_tail_cnt = 0x1;
if (last_tail_cnt != tail) {
mark16(MAX7219_DEBUG_PLANNER_TAIL, last_tail_cnt, tail);
last_tail_cnt = tail;
}
#endif
#endif
#ifdef MAX7219_DEBUG_PLANNER_QUEUE
static int16_t last_depth = 0;
const int16_t current_depth = (head - tail + BLOCK_BUFFER_SIZE) & (BLOCK_BUFFER_SIZE - 1) & 0xF;
if (current_depth != last_depth) {
quantity16(MAX7219_DEBUG_PLANNER_QUEUE, last_depth, current_depth);
last_depth = current_depth;
}
#endif
}
#endif // MAX7219_DEBUG

View File

@@ -1,154 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* This module is off by default, but can be enabled to facilitate the display of
* extra debug information during code development.
*
* Just connect up 5V and GND to give it power, then connect up the pins assigned
* in Configuration_adv.h. For example, on the Re-ARM you could use:
*
* #define MAX7219_CLK_PIN 77
* #define MAX7219_DIN_PIN 78
* #define MAX7219_LOAD_PIN 79
*
* max7219.init() is called automatically at startup, and then there are a number of
* support functions available to control the LEDs in the 8x8 grid.
*
* If you are using the Max7219 matrix for firmware debug purposes in time sensitive
* areas of the code, please be aware that the orientation (rotation) of the display can
* affect the speed. The Max7219 can update a single column fairly fast. It is much
* faster to do a Max7219_Set_Column() with a rotation of 90 or 270 degrees than to do
* a Max7219_Set_Row(). The opposite is true for rotations of 0 or 180 degrees.
*/
#pragma once
#ifndef MAX7219_ROTATE
#define MAX7219_ROTATE 0
#endif
#define _ROT ((MAX7219_ROTATE + 360) % 360)
#define MAX7219_LINES (8 * (MAX7219_NUMBER_UNITS))
#if _ROT == 0 || _ROT == 180
#define MAX7219_Y_LEDS 8
#define MAX7219_X_LEDS MAX7219_LINES
#elif _ROT == 90 || _ROT == 270
#define MAX7219_X_LEDS 8
#define MAX7219_Y_LEDS MAX7219_LINES
#else
#error "MAX7219_ROTATE must be a multiple of +/- 90°."
#endif
//
// MAX7219 registers
//
#define max7219_reg_noop 0x00
#define max7219_reg_digit0 0x01
#define max7219_reg_digit1 0x02
#define max7219_reg_digit2 0x03
#define max7219_reg_digit3 0x04
#define max7219_reg_digit4 0x05
#define max7219_reg_digit5 0x06
#define max7219_reg_digit6 0x07
#define max7219_reg_digit7 0x08
#define max7219_reg_decodeMode 0x09
#define max7219_reg_intensity 0x0A
#define max7219_reg_scanLimit 0x0B
#define max7219_reg_shutdown 0x0C
#define max7219_reg_displayTest 0x0F
class Max7219 {
public:
static uint8_t led_line[MAX7219_LINES];
Max7219() { }
static void init();
static void register_setup();
static void putbyte(uint8_t data);
static void pulse_load();
// Set a single register (e.g., a whole native row)
static void send(const uint8_t reg, const uint8_t data);
// Refresh all units
inline static void refresh() { for (uint8_t i = 0; i < 8; i++) refresh_line(i); }
// Update a single native line on all units
static void refresh_line(const uint8_t line);
// Update a single native line on just one unit
static void refresh_unit_line(const uint8_t line);
// Set a single LED by XY coordinate
static void led_set(const uint8_t x, const uint8_t y, const bool on);
static void led_on(const uint8_t x, const uint8_t y);
static void led_off(const uint8_t x, const uint8_t y);
static void led_toggle(const uint8_t x, const uint8_t y);
// Set all LEDs in a single column
static void set_column(const uint8_t col, const uint32_t val);
static void clear_column(const uint8_t col);
// Set all LEDs in a single row
static void set_row(const uint8_t row, const uint32_t val);
static void clear_row(const uint8_t row);
// 16 and 32 bit versions of Row and Column functions
// Multiple rows and columns will be used to display the value if
// the array of matrix LED's is too narrow to accomplish the goal
static void set_rows_16bits(const uint8_t y, uint32_t val);
static void set_rows_32bits(const uint8_t y, uint32_t val);
static void set_columns_16bits(const uint8_t x, uint32_t val);
static void set_columns_32bits(const uint8_t x, uint32_t val);
// Quickly clear the whole matrix
static void clear();
// Quickly fill the whole matrix
static void fill();
// Apply custom code to update the matrix
static void idle_tasks();
private:
static void error(const char * const func, const int32_t v1, const int32_t v2=-1);
static void noop();
static void set(const uint8_t line, const uint8_t bits);
static void send_row(const uint8_t row);
static void send_column(const uint8_t col);
static void mark16(const uint8_t y, const uint8_t v1, const uint8_t v2);
static void range16(const uint8_t y, const uint8_t ot, const uint8_t nt, const uint8_t oh, const uint8_t nh);
static void quantity16(const uint8_t y, const uint8_t ov, const uint8_t nv);
#ifdef MAX7219_INIT_TEST
#if MAX7219_INIT_TEST == 2
static void spiral(const bool on, const uint16_t del);
#else
static void sweep(const int8_t dir, const uint16_t ms, const bool on);
#endif
#endif
};
extern Max7219 max7219;

File diff suppressed because it is too large Load Diff

View File

@@ -26,19 +26,15 @@
*
* This file is part of the Arduino Sd2Card Library
*/
#include "MarlinConfig.h"
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#include "Sd2Card.h"
#if ENABLED(USE_WATCHDOG)
#include "watchdog.h"
#endif
//------------------------------------------------------------------------------
#if DISABLED(SOFTWARE_SPI)
// functions for hardware SPI
//------------------------------------------------------------------------------
// make sure SPCR rate is in expected bits
#if (SPR0 != 0 || SPR1 != 1)
#error "unexpected SPCR bits"
@@ -52,34 +48,34 @@
SPCR = _BV(SPE) | _BV(MSTR) | (spiRate >> 1);
SPSR = spiRate & 1 || spiRate == 6 ? 0 : _BV(SPI2X);
}
//------------------------------------------------------------------------------
/** SPI receive a byte */
static uint8_t spiRec() {
SPDR = 0xFF;
SPDR = 0XFF;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
return SPDR;
}
//------------------------------------------------------------------------------
/** SPI read data - only one call so force inline */
static inline __attribute__((always_inline))
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte-- == 0) return;
SPDR = 0xFF;
SPDR = 0XFF;
for (uint16_t i = 0; i < nbyte; i++) {
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[i] = SPDR;
SPDR = 0xFF;
SPDR = 0XFF;
}
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
buf[nbyte] = SPDR;
}
//------------------------------------------------------------------------------
/** SPI send a byte */
static void spiSend(uint8_t b) {
SPDR = b;
while (!TEST(SPSR, SPIF)) { /* Intentionally left empty */ }
}
//------------------------------------------------------------------------------
/** SPI send block - only one call so force inline */
static inline __attribute__((always_inline))
void spiSendBlock(uint8_t token, const uint8_t* buf) {
@@ -95,16 +91,15 @@
//------------------------------------------------------------------------------
#else // SOFTWARE_SPI
//------------------------------------------------------------------------------
/** nop to tune soft SPI timing */
#define nop asm volatile ("nop\n\t")
//------------------------------------------------------------------------------
/** Soft SPI receive byte */
static uint8_t spiRec() {
uint8_t data = 0;
// no interrupts during byte receive - about 8 us
cli();
// output pin high - like sending 0xFF
// output pin high - like sending 0XFF
WRITE(SPI_MOSI_PIN, HIGH);
for (uint8_t i = 0; i < 8; i++) {
@@ -124,13 +119,13 @@
sei();
return data;
}
//------------------------------------------------------------------------------
/** Soft SPI read data */
static void spiRead(uint8_t* buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
buf[i] = spiRec();
}
//------------------------------------------------------------------------------
/** Soft SPI send byte */
static void spiSend(uint8_t data) {
// no interrupts during byte send - about 8 us
@@ -138,7 +133,7 @@
for (uint8_t i = 0; i < 8; i++) {
WRITE(SPI_SCK_PIN, LOW);
WRITE(SPI_MOSI_PIN, data & 0x80);
WRITE(SPI_MOSI_PIN, data & 0X80);
data <<= 1;
@@ -154,7 +149,7 @@
// enable interrupts
sei();
}
//------------------------------------------------------------------------------
/** Soft SPI send block */
void spiSendBlock(uint8_t token, const uint8_t* buf) {
spiSend(token);
@@ -162,7 +157,7 @@
spiSend(buf[i]);
}
#endif // SOFTWARE_SPI
//------------------------------------------------------------------------------
// send command and return error code. Return zero for OK
uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
// select card
@@ -178,19 +173,19 @@ uint8_t Sd2Card::cardCommand(uint8_t cmd, uint32_t arg) {
for (int8_t s = 24; s >= 0; s -= 8) spiSend(arg >> s);
// send CRC
uint8_t crc = 0xFF;
if (cmd == CMD0) crc = 0x95; // correct crc for CMD0 with arg 0
if (cmd == CMD8) crc = 0x87; // correct crc for CMD8 with arg 0x1AA
uint8_t crc = 0XFF;
if (cmd == CMD0) crc = 0X95; // correct crc for CMD0 with arg 0
if (cmd == CMD8) crc = 0X87; // correct crc for CMD8 with arg 0X1AA
spiSend(crc);
// skip stuff byte for stop read
if (cmd == CMD12) spiRec();
// wait for response
for (uint8_t i = 0; ((status_ = spiRec()) & 0x80) && i != 0xFF; i++) { /* Intentionally left empty */ }
for (uint8_t i = 0; ((status_ = spiRec()) & 0X80) && i != 0XFF; i++) { /* Intentionally left empty */ }
return status_;
}
//------------------------------------------------------------------------------
/**
* Determine the size of an SD flash memory card.
*
@@ -218,20 +213,19 @@ uint32_t Sd2Card::cardSize() {
return 0;
}
}
//------------------------------------------------------------------------------
void Sd2Card::chipSelectHigh() {
digitalWrite(chipSelectPin_, HIGH);
}
//------------------------------------------------------------------------------
void Sd2Card::chipSelectLow() {
#if DISABLED(SOFTWARE_SPI)
spiInit(spiRate_);
#endif // SOFTWARE_SPI
digitalWrite(chipSelectPin_, LOW);
}
/**
* Erase a range of blocks.
//------------------------------------------------------------------------------
/** Erase a range of blocks.
*
* \param[in] firstBlock The address of the first block in the range.
* \param[in] lastBlock The address of the last block in the range.
@@ -241,11 +235,12 @@ void Sd2Card::chipSelectLow() {
* either 0 or 1, depends on the card vendor. The card must support
* single block erase.
*
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
csd_t csd;
if (!readCSD(&csd)) goto FAIL;
if (!readCSD(&csd)) goto fail;
// check for single block erase
if (!csd.v1.erase_blk_en) {
// erase size mask
@@ -253,7 +248,7 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
if ((firstBlock & m) != 0 || ((lastBlock + 1) & m) != 0) {
// error card can't erase specified area
error(SD_CARD_ERROR_ERASE_SINGLE_BLOCK);
goto FAIL;
goto fail;
}
}
if (type_ != SD_CARD_TYPE_SDHC) {
@@ -264,65 +259,59 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
|| cardCommand(CMD33, lastBlock)
|| cardCommand(CMD38, 0)) {
error(SD_CARD_ERROR_ERASE);
goto FAIL;
goto fail;
}
if (!waitNotBusy(SD_ERASE_TIMEOUT)) {
error(SD_CARD_ERROR_ERASE_TIMEOUT);
goto FAIL;
goto fail;
}
chipSelectHigh();
return true;
FAIL:
fail:
chipSelectHigh();
return false;
}
/**
* Determine if card supports single block erase.
//------------------------------------------------------------------------------
/** Determine if card supports single block erase.
*
* \return true if single block erase is supported.
* false if single block erase is not supported.
* \return The value one, true, is returned if single block erase is supported.
* The value zero, false, is returned if single block erase is not supported.
*/
bool Sd2Card::eraseSingleBlockEnable() {
csd_t csd;
return readCSD(&csd) ? csd.v1.erase_blk_en : false;
}
//------------------------------------------------------------------------------
/**
* Initialize an SD flash memory card.
*
* \param[in] sckRateID SPI clock rate selector. See setSckRate().
* \param[in] chipSelectPin SD chip select pin number.
*
* \return true for success, false for failure.
* The reason for failure can be determined by calling errorCode() and errorData().
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure. The reason for failure
* can be determined by calling errorCode() and errorData().
*/
bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
bool Sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin) {
errorCode_ = type_ = 0;
chipSelectPin_ = chipSelectPin;
// 16-bit init start time allows over a minute
uint16_t t0 = (uint16_t)millis();
uint32_t arg;
// If init takes more than 4s it could trigger
// watchdog leading to a reboot loop.
#if ENABLED(USE_WATCHDOG)
watchdog_reset();
#endif
// set pin modes
pinMode(chipSelectPin_, OUTPUT);
chipSelectHigh();
SET_INPUT(SPI_MISO_PIN);
SET_OUTPUT(SPI_MOSI_PIN);
SET_OUTPUT(SPI_SCK_PIN);
pinMode(SPI_MISO_PIN, INPUT);
pinMode(SPI_MOSI_PIN, OUTPUT);
pinMode(SPI_SCK_PIN, OUTPUT);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
SET_OUTPUT(SS_PIN);
pinMode(SS_PIN, OUTPUT);
// set SS high - may be chip select for another SPI device
#if SET_SPI_SS_HIGH
WRITE(SS_PIN, HIGH);
digitalWrite(SS_PIN, HIGH);
#endif // SET_SPI_SS_HIGH
// set SCK rate for initialization commands
spiRate_ = SPI_SD_INIT_RATE;
@@ -330,13 +319,13 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
#endif // SOFTWARE_SPI
// must supply min of 74 clock cycles with CS high.
for (uint8_t i = 0; i < 10; i++) spiSend(0xFF);
for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);
// command to go idle in SPI mode
while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
error(SD_CARD_ERROR_CMD0);
goto FAIL;
goto fail;
}
}
// check SD version
@@ -346,29 +335,29 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
else {
// only need last byte of r7 response
for (uint8_t i = 0; i < 4; i++) status_ = spiRec();
if (status_ != 0xAA) {
if (status_ != 0XAA) {
error(SD_CARD_ERROR_CMD8);
goto FAIL;
goto fail;
}
type(SD_CARD_TYPE_SD2);
}
// initialize card and send host supports SDHC if SD2
arg = type() == SD_CARD_TYPE_SD2 ? 0x40000000 : 0;
arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
// check for timeout
if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
error(SD_CARD_ERROR_ACMD41);
goto FAIL;
goto fail;
}
}
// if SD2 read OCR register to check for SDHC card
if (type() == SD_CARD_TYPE_SD2) {
if (cardCommand(CMD58, 0)) {
error(SD_CARD_ERROR_CMD58);
goto FAIL;
goto fail;
}
if ((spiRec() & 0xC0) == 0xC0) type(SD_CARD_TYPE_SDHC);
if ((spiRec() & 0XC0) == 0XC0) type(SD_CARD_TYPE_SDHC);
// discard rest of ocr - contains allowed voltage range
for (uint8_t i = 0; i < 3; i++) spiRec();
}
@@ -381,17 +370,18 @@ bool Sd2Card::init(uint8_t sckRateID, pin_t chipSelectPin) {
return true;
#endif // SOFTWARE_SPI
FAIL:
fail:
chipSelectHigh();
return false;
}
//------------------------------------------------------------------------------
/**
* Read a 512 byte block from an SD card.
*
* \param[in] blockNumber Logical block to be read.
* \param[out] dst Pointer to the location that will receive the data.
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
// use address if not SDHC card
@@ -399,36 +389,36 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t* dst) {
#if ENABLED(SD_CHECK_AND_RETRY)
uint8_t retryCnt = 3;
for (;;) {
if (cardCommand(CMD17, blockNumber))
do {
if (!cardCommand(CMD17, blockNumber)) {
if (readData(dst, 512)) return true;
}
else
error(SD_CARD_ERROR_CMD17);
else if (readData(dst, 512))
return true;
if (--retryCnt) break;
chipSelectHigh();
if (!--retryCnt) break;
cardCommand(CMD12, 0); // Try sending a stop command, ignore the result.
errorCode_ = 0;
}
return false;
} while (true);
#else
if (cardCommand(CMD17, blockNumber)) {
if (cardCommand(CMD17, blockNumber))
error(SD_CARD_ERROR_CMD17);
chipSelectHigh();
return false;
}
else
return readData(dst, 512);
#endif
}
/**
* Read one data block in a multiple block read sequence
chipSelectHigh();
return false;
}
//------------------------------------------------------------------------------
/** Read one data block in a multiple block read sequence
*
* \param[in] dst Pointer to the location for the data to be read.
*
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::readData(uint8_t* dst) {
chipSelectLow();
@@ -436,61 +426,62 @@ bool Sd2Card::readData(uint8_t* dst) {
}
#if ENABLED(SD_CHECK_AND_RETRY)
static const uint16_t crctab[] PROGMEM = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
uint16_t crc = 0;
for (size_t i = 0; i < n; i++) {
crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8);
}
return crc;
static const uint16_t crctab[] PROGMEM = {
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
uint16_t crc = 0;
for (size_t i = 0; i < n; i++) {
crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0XFF]) ^ (crc << 8);
}
#endif // SD_CHECK_AND_RETRY
return crc;
}
#endif
//------------------------------------------------------------------------------
bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
// wait for start block token
uint16_t t0 = millis();
while ((status_ = spiRec()) == 0XFF) {
if (((uint16_t)millis() - t0) > SD_READ_TIMEOUT) {
error(SD_CARD_ERROR_READ_TIMEOUT);
goto FAIL;
goto fail;
}
}
if (status_ != DATA_START_BLOCK) {
error(SD_CARD_ERROR_READ);
goto FAIL;
goto fail;
}
// transfer data
spiRead(dst, count);
@@ -502,7 +493,7 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
recvCrc |= spiRec();
if (calcCrc != recvCrc) {
error(SD_CARD_ERROR_CRC);
goto FAIL;
goto fail;
}
}
#else
@@ -514,61 +505,67 @@ bool Sd2Card::readData(uint8_t* dst, uint16_t count) {
// Send an additional dummy byte, required by Toshiba Flash Air SD Card
spiSend(0XFF);
return true;
FAIL:
fail:
chipSelectHigh();
// Send an additional dummy byte, required by Toshiba Flash Air SD Card
spiSend(0XFF);
return false;
}
//------------------------------------------------------------------------------
/** read CID or CSR register */
bool Sd2Card::readRegister(uint8_t cmd, void* buf) {
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
if (cardCommand(cmd, 0)) {
error(SD_CARD_ERROR_READ_REG);
chipSelectHigh();
return false;
goto fail;
}
return readData(dst, 16);
fail:
chipSelectHigh();
return false;
}
/**
* Start a read multiple blocks sequence.
//------------------------------------------------------------------------------
/** Start a read multiple blocks sequence.
*
* \param[in] blockNumber Address of first block in sequence.
*
* \note This function is used with readData() and readStop() for optimized
* multiple block reads. SPI chipSelect must be low for the entire sequence.
*
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::readStart(uint32_t blockNumber) {
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD18, blockNumber)) {
error(SD_CARD_ERROR_CMD18);
chipSelectHigh();
return false;
goto fail;
}
chipSelectHigh();
return true;
fail:
chipSelectHigh();
return false;
}
/**
* End a read multiple blocks sequence.
//------------------------------------------------------------------------------
/** End a read multiple blocks sequence.
*
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::readStop() {
chipSelectLow();
if (cardCommand(CMD12, 0)) {
error(SD_CARD_ERROR_CMD12);
chipSelectHigh();
return false;
goto fail;
}
chipSelectHigh();
return true;
fail:
chipSelectHigh();
return false;
}
//------------------------------------------------------------------------------
/**
* Set the SPI clock rate.
*
@@ -589,84 +586,89 @@ bool Sd2Card::setSckRate(uint8_t sckRateID) {
spiRate_ = sckRateID;
return true;
}
//------------------------------------------------------------------------------
// wait for card to go not busy
bool Sd2Card::waitNotBusy(uint16_t timeoutMillis) {
uint16_t t0 = millis();
while (spiRec() != 0XFF)
if (((uint16_t)millis() - t0) >= timeoutMillis) return false;
while (spiRec() != 0XFF) {
if (((uint16_t)millis() - t0) >= timeoutMillis) goto fail;
}
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
/**
* Writes a 512 byte block to an SD card.
*
* \param[in] blockNumber Logical block to be written.
* \param[in] src Pointer to the location of the data to be written.
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t* src) {
// use address if not SDHC card
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD24, blockNumber)) {
error(SD_CARD_ERROR_CMD24);
goto FAIL;
goto fail;
}
if (!writeData(DATA_START_BLOCK, src)) goto FAIL;
if (!writeData(DATA_START_BLOCK, src)) goto fail;
// wait for flash programming to complete
if (!waitNotBusy(SD_WRITE_TIMEOUT)) {
error(SD_CARD_ERROR_WRITE_TIMEOUT);
goto FAIL;
goto fail;
}
// response is r2 so get and check two bytes for nonzero
if (cardCommand(CMD13, 0) || spiRec()) {
error(SD_CARD_ERROR_WRITE_PROGRAMMING);
goto FAIL;
goto fail;
}
chipSelectHigh();
return true;
FAIL:
fail:
chipSelectHigh();
return false;
}
/**
* Write one data block in a multiple block write sequence
//------------------------------------------------------------------------------
/** Write one data block in a multiple block write sequence
* \param[in] src Pointer to the location of the data to be written.
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::writeData(const uint8_t* src) {
chipSelectLow();
// wait for previous write to finish
if (!waitNotBusy(SD_WRITE_TIMEOUT) || !writeData(WRITE_MULTIPLE_TOKEN, src)) {
error(SD_CARD_ERROR_WRITE_MULTIPLE);
chipSelectHigh();
return false;
}
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
if (!writeData(WRITE_MULTIPLE_TOKEN, src)) goto fail;
chipSelectHigh();
return true;
fail:
error(SD_CARD_ERROR_WRITE_MULTIPLE);
chipSelectHigh();
return false;
}
//------------------------------------------------------------------------------
// send one block of data for write block or write multiple blocks
bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
spiSendBlock(token, src);
spiSend(0xFF); // dummy crc
spiSend(0xFF); // dummy crc
spiSend(0xff); // dummy crc
spiSend(0xff); // dummy crc
status_ = spiRec();
if ((status_ & DATA_RES_MASK) != DATA_RES_ACCEPTED) {
error(SD_CARD_ERROR_WRITE);
chipSelectHigh();
return false;
goto fail;
}
return true;
fail:
chipSelectHigh();
return false;
}
/**
* Start a write multiple blocks sequence.
//------------------------------------------------------------------------------
/** Start a write multiple blocks sequence.
*
* \param[in] blockNumber Address of first block in sequence.
* \param[in] eraseCount The number of blocks to be pre-erased.
@@ -674,43 +676,44 @@ bool Sd2Card::writeData(uint8_t token, const uint8_t* src) {
* \note This function is used with writeData() and writeStop()
* for optimized multiple block writes.
*
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::writeStart(uint32_t blockNumber, uint32_t eraseCount) {
// send pre-erase count
if (cardAcmd(ACMD23, eraseCount)) {
error(SD_CARD_ERROR_ACMD23);
goto FAIL;
goto fail;
}
// use address if not SDHC card
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
if (cardCommand(CMD25, blockNumber)) {
error(SD_CARD_ERROR_CMD25);
goto FAIL;
goto fail;
}
chipSelectHigh();
return true;
FAIL:
fail:
chipSelectHigh();
return false;
}
/**
* End a write multiple blocks sequence.
//------------------------------------------------------------------------------
/** End a write multiple blocks sequence.
*
* \return true for success, false for failure.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure.
*/
bool Sd2Card::writeStop() {
chipSelectLow();
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
spiSend(STOP_TRAN_TOKEN);
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto FAIL;
if (!waitNotBusy(SD_WRITE_TIMEOUT)) goto fail;
chipSelectHigh();
return true;
FAIL:
fail:
error(SD_CARD_ERROR_STOP_TRAN);
chipSelectHigh();
return false;
}
#endif // SDSUPPORT
#endif

View File

@@ -20,119 +20,165 @@
*
*/
/**
* \file
* \brief Sd2Card class for V2 SD/SDHC cards
*/
/**
* Arduino Sd2Card Library
* Copyright (C) 2009 by William Greiman
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SD2CARD_H_
#define _SD2CARD_H_
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#ifndef Sd2Card_h
#define Sd2Card_h
/**
* \file
* \brief Sd2Card class for V2 SD/SDHC cards
*/
#include "SdFatConfig.h"
#include "SdInfo.h"
//------------------------------------------------------------------------------
// SPI speed is F_CPU/2^(1 + index), 0 <= index <= 6
uint8_t const SPI_FULL_SPEED = 0, // Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate().
SPI_HALF_SPEED = 1, // Set SCK rate to F_CPU/4. See Sd2Card::setSckRate().
SPI_QUARTER_SPEED = 2, // Set SCK rate to F_CPU/8. See Sd2Card::setSckRate().
SPI_EIGHTH_SPEED = 3, // Set SCK rate to F_CPU/16. See Sd2Card::setSckRate().
SPI_SIXTEENTH_SPEED = 4; // Set SCK rate to F_CPU/32. See Sd2Card::setSckRate().
uint16_t const SD_INIT_TIMEOUT = 2000, // init timeout ms
SD_ERASE_TIMEOUT = 10000, // erase timeout ms
SD_READ_TIMEOUT = 300, // read timeout ms
SD_WRITE_TIMEOUT = 600; // write time out ms
/** Set SCK to max rate of F_CPU/2. See Sd2Card::setSckRate(). */
uint8_t const SPI_FULL_SPEED = 0;
/** Set SCK rate to F_CPU/4. See Sd2Card::setSckRate(). */
uint8_t const SPI_HALF_SPEED = 1;
/** Set SCK rate to F_CPU/8. See Sd2Card::setSckRate(). */
uint8_t const SPI_QUARTER_SPEED = 2;
/** Set SCK rate to F_CPU/16. See Sd2Card::setSckRate(). */
uint8_t const SPI_EIGHTH_SPEED = 3;
/** Set SCK rate to F_CPU/32. See Sd2Card::setSckRate(). */
uint8_t const SPI_SIXTEENTH_SPEED = 4;
//------------------------------------------------------------------------------
/** init timeout ms */
uint16_t const SD_INIT_TIMEOUT = 2000;
/** erase timeout ms */
uint16_t const SD_ERASE_TIMEOUT = 10000;
/** read timeout ms */
uint16_t const SD_READ_TIMEOUT = 300;
/** write time out ms */
uint16_t const SD_WRITE_TIMEOUT = 600;
//------------------------------------------------------------------------------
// SD card errors
uint8_t const SD_CARD_ERROR_CMD0 = 0X1, // timeout error for command CMD0 (initialize card in SPI mode)
SD_CARD_ERROR_CMD8 = 0X2, // CMD8 was not accepted - not a valid SD card
SD_CARD_ERROR_CMD12 = 0X3, // card returned an error response for CMD12 (write stop)
SD_CARD_ERROR_CMD17 = 0X4, // card returned an error response for CMD17 (read block)
SD_CARD_ERROR_CMD18 = 0X5, // card returned an error response for CMD18 (read multiple block)
SD_CARD_ERROR_CMD24 = 0X6, // card returned an error response for CMD24 (write block)
SD_CARD_ERROR_CMD25 = 0X7, // WRITE_MULTIPLE_BLOCKS command failed
SD_CARD_ERROR_CMD58 = 0X8, // card returned an error response for CMD58 (read OCR)
SD_CARD_ERROR_ACMD23 = 0X9, // SET_WR_BLK_ERASE_COUNT failed
SD_CARD_ERROR_ACMD41 = 0XA, // ACMD41 initialization process timeout
SD_CARD_ERROR_BAD_CSD = 0XB, // card returned a bad CSR version field
SD_CARD_ERROR_ERASE = 0XC, // erase block group command failed
SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD, // card not capable of single block erase
SD_CARD_ERROR_ERASE_TIMEOUT = 0XE, // Erase sequence timed out
SD_CARD_ERROR_READ = 0XF, // card returned an error token instead of read data
SD_CARD_ERROR_READ_REG = 0x10, // read CID or CSD failed
SD_CARD_ERROR_READ_TIMEOUT = 0x11, // timeout while waiting for start of read data
SD_CARD_ERROR_STOP_TRAN = 0x12, // card did not accept STOP_TRAN_TOKEN
SD_CARD_ERROR_WRITE = 0x13, // card returned an error token as a response to a write operation
SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14, // REMOVE - not used ... attempt to write protected block zero
SD_CARD_ERROR_WRITE_MULTIPLE = 0x15, // card did not go ready for a multiple block write
SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16, // card returned an error to a CMD13 status check after a write
SD_CARD_ERROR_WRITE_TIMEOUT = 0x17, // timeout occurred during write programming
SD_CARD_ERROR_SCK_RATE = 0x18, // incorrect rate selected
SD_CARD_ERROR_INIT_NOT_CALLED = 0x19, // init() not called
SD_CARD_ERROR_CRC = 0x20; // crc check error
/** timeout error for command CMD0 (initialize card in SPI mode) */
uint8_t const SD_CARD_ERROR_CMD0 = 0X1;
/** CMD8 was not accepted - not a valid SD card*/
uint8_t const SD_CARD_ERROR_CMD8 = 0X2;
/** card returned an error response for CMD12 (write stop) */
uint8_t const SD_CARD_ERROR_CMD12 = 0X3;
/** card returned an error response for CMD17 (read block) */
uint8_t const SD_CARD_ERROR_CMD17 = 0X4;
/** card returned an error response for CMD18 (read multiple block) */
uint8_t const SD_CARD_ERROR_CMD18 = 0X5;
/** card returned an error response for CMD24 (write block) */
uint8_t const SD_CARD_ERROR_CMD24 = 0X6;
/** WRITE_MULTIPLE_BLOCKS command failed */
uint8_t const SD_CARD_ERROR_CMD25 = 0X7;
/** card returned an error response for CMD58 (read OCR) */
uint8_t const SD_CARD_ERROR_CMD58 = 0X8;
/** SET_WR_BLK_ERASE_COUNT failed */
uint8_t const SD_CARD_ERROR_ACMD23 = 0X9;
/** ACMD41 initialization process timeout */
uint8_t const SD_CARD_ERROR_ACMD41 = 0XA;
/** card returned a bad CSR version field */
uint8_t const SD_CARD_ERROR_BAD_CSD = 0XB;
/** erase block group command failed */
uint8_t const SD_CARD_ERROR_ERASE = 0XC;
/** card not capable of single block erase */
uint8_t const SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0XD;
/** Erase sequence timed out */
uint8_t const SD_CARD_ERROR_ERASE_TIMEOUT = 0XE;
/** card returned an error token instead of read data */
uint8_t const SD_CARD_ERROR_READ = 0XF;
/** read CID or CSD failed */
uint8_t const SD_CARD_ERROR_READ_REG = 0X10;
/** timeout while waiting for start of read data */
uint8_t const SD_CARD_ERROR_READ_TIMEOUT = 0X11;
/** card did not accept STOP_TRAN_TOKEN */
uint8_t const SD_CARD_ERROR_STOP_TRAN = 0X12;
/** card returned an error token as a response to a write operation */
uint8_t const SD_CARD_ERROR_WRITE = 0X13;
/** attempt to write protected block zero */
uint8_t const SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0X14; // REMOVE - not used
/** card did not go ready for a multiple block write */
uint8_t const SD_CARD_ERROR_WRITE_MULTIPLE = 0X15;
/** card returned an error to a CMD13 status check after a write */
uint8_t const SD_CARD_ERROR_WRITE_PROGRAMMING = 0X16;
/** timeout occurred during write programming */
uint8_t const SD_CARD_ERROR_WRITE_TIMEOUT = 0X17;
/** incorrect rate selected */
uint8_t const SD_CARD_ERROR_SCK_RATE = 0X18;
/** init() not called */
uint8_t const SD_CARD_ERROR_INIT_NOT_CALLED = 0X19;
/** crc check error */
uint8_t const SD_CARD_ERROR_CRC = 0X20;
//------------------------------------------------------------------------------
// card types
uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD card
SD_CARD_TYPE_SD2 = 2, // Standard capacity V2 SD card
SD_CARD_TYPE_SDHC = 3; // High Capacity SD card
/** Standard capacity V1 SD card */
uint8_t const SD_CARD_TYPE_SD1 = 1;
/** Standard capacity V2 SD card */
uint8_t const SD_CARD_TYPE_SD2 = 2;
/** High Capacity SD card */
uint8_t const SD_CARD_TYPE_SDHC = 3;
/**
* define SOFTWARE_SPI to use bit-bang SPI
*/
#if MEGA_SOFT_SPI
//------------------------------------------------------------------------------
#if MEGA_SOFT_SPI && (defined(__AVR_ATmega1280__)||defined(__AVR_ATmega2560__))
#define SOFTWARE_SPI
#elif USE_SOFTWARE_SPI
#define SOFTWARE_SPI
#endif
#endif // MEGA_SOFT_SPI
//------------------------------------------------------------------------------
// SPI pin definitions - do not edit here - change in SdFatConfig.h
//
#if DISABLED(SOFTWARE_SPI)
// hardware pin defs
#define SD_CHIP_SELECT_PIN SS_PIN // The default chip select pin for the SD card is SS.
/** The default chip select pin for the SD card is SS. */
#define SD_CHIP_SELECT_PIN SS_PIN
// The following three pins must not be redefined for hardware SPI.
#define SPI_MOSI_PIN MOSI_PIN // SPI Master Out Slave In pin
#define SPI_MISO_PIN MISO_PIN // SPI Master In Slave Out pin
#define SPI_SCK_PIN SCK_PIN // SPI Clock pin
#else // SOFTWARE_SPI
#define SD_CHIP_SELECT_PIN SOFT_SPI_CS_PIN // SPI chip select pin
#define SPI_MOSI_PIN SOFT_SPI_MOSI_PIN // SPI Master Out Slave In pin
#define SPI_MISO_PIN SOFT_SPI_MISO_PIN // SPI Master In Slave Out pin
#define SPI_SCK_PIN SOFT_SPI_SCK_PIN // SPI Clock pin
#endif // SOFTWARE_SPI
/** SPI Master Out Slave In pin */
#define SPI_MOSI_PIN MOSI_PIN
/** SPI Master In Slave Out pin */
#define SPI_MISO_PIN MISO_PIN
/** SPI Clock pin */
#define SPI_SCK_PIN SCK_PIN
#else // SOFTWARE_SPI
/** SPI chip select pin */
#define SD_CHIP_SELECT_PIN SOFT_SPI_CS_PIN
/** SPI Master Out Slave In pin */
#define SPI_MOSI_PIN SOFT_SPI_MOSI_PIN
/** SPI Master In Slave Out pin */
#define SPI_MISO_PIN SOFT_SPI_MISO_PIN
/** SPI Clock pin */
#define SPI_SCK_PIN SOFT_SPI_SCK_PIN
#endif // SOFTWARE_SPI
//------------------------------------------------------------------------------
/**
* \class Sd2Card
* \brief Raw access to SD and SDHC flash memory cards.
*/
class Sd2Card {
public:
public:
/** Construct an instance of Sd2Card. */
Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
uint32_t cardSize();
bool erase(uint32_t firstBlock, uint32_t lastBlock);
bool eraseSingleBlockEnable();
/**
* Set SD error code.
* \param[in] code value for error code.
*/
void error(uint8_t code) {errorCode_ = code;}
/**
* \return error code for last error. See Sd2Card.h for a list of error codes.
*/
int errorCode() const {return errorCode_;}
/** \return error data for last error. */
int errorData() const {return status_;}
/**
* Initialize an SD flash memory card with default clock rate and chip
* select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
@@ -140,9 +186,8 @@ class Sd2Card {
* \return true for success or false for failure.
*/
bool init(uint8_t sckRateID = SPI_FULL_SPEED,
pin_t chipSelectPin = SD_CHIP_SELECT_PIN);
uint8_t chipSelectPin = SD_CHIP_SELECT_PIN);
bool readBlock(uint32_t block, uint8_t* dst);
/**
* Read a card's CID register. The CID contains card identification
* information such as Manufacturer ID, Product name, Product serial
@@ -152,8 +197,9 @@ class Sd2Card {
*
* \return true for success or false for failure.
*/
bool readCID(cid_t* cid) { return readRegister(CMD10, cid); }
bool readCID(cid_t* cid) {
return readRegister(CMD10, cid);
}
/**
* Read a card's CSD register. The CSD contains Card-Specific Data that
* provides information regarding access to the card's contents.
@@ -162,14 +208,14 @@ class Sd2Card {
*
* \return true for success or false for failure.
*/
bool readCSD(csd_t* csd) { return readRegister(CMD9, csd); }
bool readCSD(csd_t* csd) {
return readRegister(CMD9, csd);
}
bool readData(uint8_t* dst);
bool readStart(uint32_t blockNumber);
bool readStop();
bool setSckRate(uint8_t sckRateID);
/**
* Return the card type: SD V1, SD V2 or SDHC
/** Return the card type: SD V1, SD V2 or SDHC
* \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
*/
int type() const {return type_;}
@@ -177,14 +223,13 @@ class Sd2Card {
bool writeData(const uint8_t* src);
bool writeStart(uint32_t blockNumber, uint32_t eraseCount);
bool writeStop();
private:
uint8_t chipSelectPin_,
errorCode_,
spiRate_,
status_,
type_;
private:
//----------------------------------------------------------------------------
uint8_t chipSelectPin_;
uint8_t errorCode_;
uint8_t spiRate_;
uint8_t status_;
uint8_t type_;
// private functions
uint8_t cardAcmd(uint8_t cmd, uint32_t arg) {
cardCommand(CMD55, 0);
@@ -196,9 +241,11 @@ class Sd2Card {
bool readRegister(uint8_t cmd, void* buf);
void chipSelectHigh();
void chipSelectLow();
void type(uint8_t value) { type_ = value; }
void type(uint8_t value) {type_ = value;}
bool waitNotBusy(uint16_t timeoutMillis);
bool writeData(uint8_t token, const uint8_t* src);
};
#endif // Sd2Card_h
#endif // _SD2CARD_H_
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -20,198 +20,208 @@
*
*/
/**
* \file
* \brief SdBaseFile class
*/
/**
* Arduino SdFat Library
* Copyright (C) 2009 by William Greiman
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SDBASEFILE_H_
#define _SDBASEFILE_H_
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#ifndef SdBaseFile_h
#define SdBaseFile_h
/**
* \file
* \brief SdBaseFile class
*/
#include "Marlin.h"
#include "SdFatConfig.h"
#include "SdVolume.h"
#include <stdint.h>
//------------------------------------------------------------------------------
/**
* \struct filepos_t
* \brief internal type for istream
* do not use in user apps
*/
struct filepos_t {
uint32_t position; // stream byte position
uint32_t cluster; // cluster of position
/** stream position */
uint32_t position;
/** cluster for position */
uint32_t cluster;
filepos_t() : position(0), cluster(0) {}
};
// use the gnu style oflag in open()
uint8_t const O_READ = 0x01, // open() oflag for reading
O_RDONLY = O_READ, // open() oflag - same as O_IN
O_WRITE = 0x02, // open() oflag for write
O_WRONLY = O_WRITE, // open() oflag - same as O_WRITE
O_RDWR = (O_READ | O_WRITE), // open() oflag for reading and writing
O_ACCMODE = (O_READ | O_WRITE), // open() oflag mask for access modes
O_APPEND = 0x04, // The file offset shall be set to the end of the file prior to each write.
O_SYNC = 0x08, // Synchronous writes - call sync() after each write
O_TRUNC = 0x10, // Truncate the file to zero length
O_AT_END = 0x20, // Set the initial position at the end of the file
O_CREAT = 0x40, // Create the file if nonexistent
O_EXCL = 0x80; // If O_CREAT and O_EXCL are set, open() shall fail if the file exists
/** open() oflag for reading */
uint8_t const O_READ = 0X01;
/** open() oflag - same as O_IN */
uint8_t const O_RDONLY = O_READ;
/** open() oflag for write */
uint8_t const O_WRITE = 0X02;
/** open() oflag - same as O_WRITE */
uint8_t const O_WRONLY = O_WRITE;
/** open() oflag for reading and writing */
uint8_t const O_RDWR = (O_READ | O_WRITE);
/** open() oflag mask for access modes */
uint8_t const O_ACCMODE = (O_READ | O_WRITE);
/** The file offset shall be set to the end of the file prior to each write. */
uint8_t const O_APPEND = 0X04;
/** synchronous writes - call sync() after each write */
uint8_t const O_SYNC = 0X08;
/** truncate the file to zero length */
uint8_t const O_TRUNC = 0X10;
/** set the initial position at the end of the file */
uint8_t const O_AT_END = 0X20;
/** create the file if nonexistent */
uint8_t const O_CREAT = 0X40;
/** If O_CREAT and O_EXCL are set, open() shall fail if the file exists */
uint8_t const O_EXCL = 0X80;
// SdBaseFile class static and const definitions
// flags for ls()
uint8_t const LS_DATE = 1, // ls() flag to print modify date
LS_SIZE = 2, // ls() flag to print file size
LS_R = 4; // ls() flag for recursive list of subdirectories
/** ls() flag to print modify date */
uint8_t const LS_DATE = 1;
/** ls() flag to print file size */
uint8_t const LS_SIZE = 2;
/** ls() flag for recursive list of subdirectories */
uint8_t const LS_R = 4;
// flags for timestamp
uint8_t const T_ACCESS = 1, // Set the file's last access date
T_CREATE = 2, // Set the file's creation date and time
T_WRITE = 4; // Set the file's write date and time
/** set the file's last access date */
uint8_t const T_ACCESS = 1;
/** set the file's creation date and time */
uint8_t const T_CREATE = 2;
/** Set the file's write date and time */
uint8_t const T_WRITE = 4;
// values for type_
uint8_t const FAT_FILE_TYPE_CLOSED = 0, // This file has not been opened.
FAT_FILE_TYPE_NORMAL = 1, // A normal file
FAT_FILE_TYPE_ROOT_FIXED = 2, // A FAT12 or FAT16 root directory
FAT_FILE_TYPE_ROOT32 = 3, // A FAT32 root directory
FAT_FILE_TYPE_SUBDIR = 4, // A subdirectory file
FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED; // Test value for directory type
/** This file has not been opened. */
uint8_t const FAT_FILE_TYPE_CLOSED = 0;
/** A normal file */
uint8_t const FAT_FILE_TYPE_NORMAL = 1;
/** A FAT12 or FAT16 root directory */
uint8_t const FAT_FILE_TYPE_ROOT_FIXED = 2;
/** A FAT32 root directory */
uint8_t const FAT_FILE_TYPE_ROOT32 = 3;
/** A subdirectory file*/
uint8_t const FAT_FILE_TYPE_SUBDIR = 4;
/** Test value for directory type */
uint8_t const FAT_FILE_TYPE_MIN_DIR = FAT_FILE_TYPE_ROOT_FIXED;
/**
* date field for FAT directory entry
/** date field for FAT directory entry
* \param[in] year [1980,2107]
* \param[in] month [1,12]
* \param[in] day [1,31]
*
* \return Packed date for dir_t entry.
*/
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) { return (year - 1980) << 9 | month << 5 | day; }
/**
* year part of FAT directory date field
static inline uint16_t FAT_DATE(uint16_t year, uint8_t month, uint8_t day) {
return (year - 1980) << 9 | month << 5 | day;
}
/** year part of FAT directory date field
* \param[in] fatDate Date in packed dir format.
*
* \return Extracted year [1980,2107]
*/
static inline uint16_t FAT_YEAR(uint16_t fatDate) { return 1980 + (fatDate >> 9); }
/**
* month part of FAT directory date field
static inline uint16_t FAT_YEAR(uint16_t fatDate) {
return 1980 + (fatDate >> 9);
}
/** month part of FAT directory date field
* \param[in] fatDate Date in packed dir format.
*
* \return Extracted month [1,12]
*/
static inline uint8_t FAT_MONTH(uint16_t fatDate) { return (fatDate >> 5) & 0XF; }
/**
* day part of FAT directory date field
static inline uint8_t FAT_MONTH(uint16_t fatDate) {
return (fatDate >> 5) & 0XF;
}
/** day part of FAT directory date field
* \param[in] fatDate Date in packed dir format.
*
* \return Extracted day [1,31]
*/
static inline uint8_t FAT_DAY(uint16_t fatDate) { return fatDate & 0x1F; }
/**
* time field for FAT directory entry
static inline uint8_t FAT_DAY(uint16_t fatDate) {
return fatDate & 0X1F;
}
/** time field for FAT directory entry
* \param[in] hour [0,23]
* \param[in] minute [0,59]
* \param[in] second [0,59]
*
* \return Packed time for dir_t entry.
*/
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) { return hour << 11 | minute << 5 | second >> 1; }
/**
* hour part of FAT directory time field
static inline uint16_t FAT_TIME(uint8_t hour, uint8_t minute, uint8_t second) {
return hour << 11 | minute << 5 | second >> 1;
}
/** hour part of FAT directory time field
* \param[in] fatTime Time in packed dir format.
*
* \return Extracted hour [0,23]
*/
static inline uint8_t FAT_HOUR(uint16_t fatTime) { return fatTime >> 11; }
/**
* minute part of FAT directory time field
static inline uint8_t FAT_HOUR(uint16_t fatTime) {
return fatTime >> 11;
}
/** minute part of FAT directory time field
* \param[in] fatTime Time in packed dir format.
*
* \return Extracted minute [0,59]
*/
static inline uint8_t FAT_MINUTE(uint16_t fatTime) { return (fatTime >> 5) & 0x3F; }
/**
* second part of FAT directory time field
static inline uint8_t FAT_MINUTE(uint16_t fatTime) {
return (fatTime >> 5) & 0X3F;
}
/** second part of FAT directory time field
* Note second/2 is stored in packed time.
*
* \param[in] fatTime Time in packed dir format.
*
* \return Extracted second [0,58]
*/
static inline uint8_t FAT_SECOND(uint16_t fatTime) { return 2 * (fatTime & 0x1F); }
// Default date for file timestamps is 1 Jan 2000
static inline uint8_t FAT_SECOND(uint16_t fatTime) {
return 2 * (fatTime & 0X1F);
}
/** Default date for file timestamps is 1 Jan 2000 */
uint16_t const FAT_DEFAULT_DATE = ((2000 - 1980) << 9) | (1 << 5) | 1;
// Default time for file timestamp is 1 am
/** Default time for file timestamp is 1 am */
uint16_t const FAT_DEFAULT_TIME = (1 << 11);
//------------------------------------------------------------------------------
/**
* \class SdBaseFile
* \brief Base class for SdFile with Print and C++ streams.
*/
class SdBaseFile {
public:
/** Create an instance. */
SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
SdBaseFile(const char* path, uint8_t oflag);
~SdBaseFile() { if (isOpen()) close(); }
~SdBaseFile() {if (isOpen()) close();}
/**
* writeError is set to true if an error occurs during a write().
* Set writeError to false before calling print() and/or write() and check
* for true after calls to print() and/or write().
*/
bool writeError;
//----------------------------------------------------------------------------
// helpers for stream classes
/**
* get position for streams
/** get position for streams
* \param[out] pos struct to receive position
*/
void getpos(filepos_t* pos);
/**
* set position for streams
/** set position for streams
* \param[out] pos struct with value for new position
*/
void setpos(filepos_t* pos);
//----------------------------------------------------------------------------
bool close();
bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
bool createContiguous(SdBaseFile* dirFile,
const char* path, uint32_t size);
/**
* \return The current cluster number for a file or directory.
*/
uint32_t curCluster() const { return curCluster_; }
/**
* \return The current position for a file or directory.
*/
uint32_t curPosition() const { return curPosition_; }
/**
* \return Current working directory
*/
static SdBaseFile* cwd() { return cwd_; }
/**
* Set the date/time callback function
/** \return The current cluster number for a file or directory. */
uint32_t curCluster() const {return curCluster_;}
/** \return The current position for a file or directory. */
uint32_t curPosition() const {return curPosition_;}
/** \return Current working directory */
static SdBaseFile* cwd() {return cwd_;}
/** Set the date/time callback function
*
* \param[in] dateTime The user's call back function. The callback
* function is of the form:
@@ -242,55 +252,35 @@ class SdBaseFile {
void (*dateTime)(uint16_t* date, uint16_t* time)) {
dateTime_ = dateTime;
}
/**
* Cancel the date/time callback function.
*/
static void dateTimeCallbackCancel() { dateTime_ = 0; }
/** Cancel the date/time callback function. */
static void dateTimeCallbackCancel() {dateTime_ = 0;}
bool dirEntry(dir_t* dir);
static void dirName(const dir_t& dir, char* name);
bool exists(const char* name);
int16_t fgets(char* str, int16_t num, char* delim = 0);
/**
* \return The total number of bytes in a file or directory.
*/
uint32_t fileSize() const { return fileSize_; }
/**
* \return The first cluster number for a file or directory.
*/
uint32_t firstCluster() const { return firstCluster_; }
/**
* \return True if this is a directory else false.
*/
bool isDir() const { return type_ >= FAT_FILE_TYPE_MIN_DIR; }
/**
* \return True if this is a normal file else false.
*/
bool isFile() const { return type_ == FAT_FILE_TYPE_NORMAL; }
/**
* \return True if this is an open file/directory else false.
*/
bool isOpen() const { return type_ != FAT_FILE_TYPE_CLOSED; }
/**
* \return True if this is a subdirectory else false.
*/
bool isSubDir() const { return type_ == FAT_FILE_TYPE_SUBDIR; }
/**
* \return True if this is the root directory.
*/
bool isRoot() const { return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32; }
bool getFilename(char * const name);
/** \return The total number of bytes in a file or directory. */
uint32_t fileSize() const {return fileSize_;}
/** \return The first cluster number for a file or directory. */
uint32_t firstCluster() const {return firstCluster_;}
bool getFilename(char* name);
/** \return True if this is a directory else false. */
bool isDir() const {return type_ >= FAT_FILE_TYPE_MIN_DIR;}
/** \return True if this is a normal file else false. */
bool isFile() const {return type_ == FAT_FILE_TYPE_NORMAL;}
/** \return True if this is an open file/directory else false. */
bool isOpen() const {return type_ != FAT_FILE_TYPE_CLOSED;}
/** \return True if this is a subdirectory else false. */
bool isSubDir() const {return type_ == FAT_FILE_TYPE_SUBDIR;}
/** \return True if this is the root directory. */
bool isRoot() const {
return type_ == FAT_FILE_TYPE_ROOT_FIXED || type_ == FAT_FILE_TYPE_ROOT32;
}
void ls(uint8_t flags = 0, uint8_t indent = 0);
bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true);
// alias for backward compactability
bool makeDir(SdBaseFile* dir, const char* path) {
return mkdir(dir, path, false);
}
bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
bool open(const char* path, uint8_t oflag = O_READ);
@@ -305,58 +295,53 @@ class SdBaseFile {
int8_t readDir(dir_t* dir, char* longFilename);
static bool remove(SdBaseFile* dirFile, const char* path);
bool remove();
/**
* Set the file's current position to zero.
*/
void rewind() { seekSet(0); }
/** Set the file's current position to zero. */
void rewind() {seekSet(0);}
bool rename(SdBaseFile* dirFile, const char* newPath);
bool rmdir();
// for backward compatibility
bool rmDir() {return rmdir();}
bool rmRfStar();
/**
* Set the files position to current position + \a pos. See seekSet().
/** Set the files position to current position + \a pos. See seekSet().
* \param[in] offset The new position in bytes from the current position.
* \return true for success or false for failure.
*/
bool seekCur(const int32_t offset) { return seekSet(curPosition_ + offset); }
/**
* Set the files position to end-of-file + \a offset. See seekSet().
bool seekCur(int32_t offset) {
return seekSet(curPosition_ + offset);
}
/** Set the files position to end-of-file + \a offset. See seekSet().
* \param[in] offset The new position in bytes from end-of-file.
* \return true for success or false for failure.
*/
bool seekEnd(const int32_t offset = 0) { return seekSet(fileSize_ + offset); }
bool seekSet(const uint32_t pos);
bool seekEnd(int32_t offset = 0) {return seekSet(fileSize_ + offset);}
bool seekSet(uint32_t pos);
bool sync();
bool timestamp(SdBaseFile* file);
bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
uint8_t hour, uint8_t minute, uint8_t second);
/**
* Type of file. Use isFile() or isDir() instead of type() if possible.
/** Type of file. You should use isFile() or isDir() instead of type()
* if possible.
*
* \return The file or directory type.
*/
uint8_t type() const { return type_; }
uint8_t type() const {return type_;}
bool truncate(uint32_t size);
/**
* \return SdVolume that contains this file.
*/
SdVolume* volume() const { return vol_; }
/** \return SdVolume that contains this file. */
SdVolume* volume() const {return vol_;}
int16_t write(const void* buf, uint16_t nbyte);
//------------------------------------------------------------------------------
private:
friend class SdFat; // allow SdFat to set cwd_
static SdBaseFile* cwd_; // global pointer to cwd dir
// allow SdFat to set cwd_
friend class SdFat;
// global pointer to cwd dir
static SdBaseFile* cwd_;
// data time callback function
static void (*dateTime_)(uint16_t* date, uint16_t* time);
// bits defined in flags_
static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC), // should be 0x0F
F_FILE_DIR_DIRTY = 0x80; // sync of directory entry required
// should be 0X0F
static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC);
// sync of directory entry required
static uint8_t const F_FILE_DIR_DIRTY = 0X80;
// private data
uint8_t flags_; // See above for definition of flags_ bits
@@ -370,11 +355,8 @@ class SdBaseFile {
uint32_t firstCluster_; // first cluster of file
SdVolume* vol_; // volume where file is located
/**
* EXPERIMENTAL - Don't use!
*/
//bool openParent(SdBaseFile* dir);
/** experimental don't use */
bool openParent(SdBaseFile* dir);
// private functions
bool addCluster();
bool addDirCluster();
@@ -385,6 +367,126 @@ class SdBaseFile {
bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag);
bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
dir_t* readDirCache();
//------------------------------------------------------------------------------
// to be deleted
static void printDirName(const dir_t& dir,
uint8_t width, bool printSlash);
//------------------------------------------------------------------------------
// Deprecated functions - suppress cpplint warnings with NOLINT comment
#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
public:
/** \deprecated Use:
* bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
* \param[out] bgnBlock the first block address for the file.
* \param[out] endBlock the last block address for the file.
* \return true for success or false for failure.
*/
bool contiguousRange(uint32_t& bgnBlock, uint32_t& endBlock) { // NOLINT
return contiguousRange(&bgnBlock, &endBlock);
}
/** \deprecated Use:
* bool createContiguous(SdBaseFile* dirFile,
* const char* path, uint32_t size)
* \param[in] dirFile The directory where the file will be created.
* \param[in] path A path with a valid DOS 8.3 file name.
* \param[in] size The desired file size.
* \return true for success or false for failure.
*/
bool createContiguous(SdBaseFile& dirFile, // NOLINT
const char* path, uint32_t size) {
return createContiguous(&dirFile, path, size);
}
/** \deprecated Use:
* static void dateTimeCallback(
* void (*dateTime)(uint16_t* date, uint16_t* time));
* \param[in] dateTime The user's call back function.
*/
static void dateTimeCallback(
void (*dateTime)(uint16_t& date, uint16_t& time)) { // NOLINT
oldDateTime_ = dateTime;
dateTime_ = dateTime ? oldToNew : 0;
}
/** \deprecated Use: bool dirEntry(dir_t* dir);
* \param[out] dir Location for return of the file's directory entry.
* \return true for success or false for failure.
*/
bool dirEntry(dir_t& dir) {return dirEntry(&dir);} // NOLINT
/** \deprecated Use:
* bool mkdir(SdBaseFile* dir, const char* path);
* \param[in] dir An open SdFat instance for the directory that will contain
* the new directory.
* \param[in] path A path with a valid 8.3 DOS name for the new directory.
* \return true for success or false for failure.
*/
bool mkdir(SdBaseFile& dir, const char* path) { // NOLINT
return mkdir(&dir, path);
}
/** \deprecated Use:
* bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
* \param[in] dirFile An open SdFat instance for the directory containing the
* file to be opened.
* \param[in] path A path with a valid 8.3 DOS name for the file.
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
* OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
* \return true for success or false for failure.
*/
bool open(SdBaseFile& dirFile, // NOLINT
const char* path, uint8_t oflag) {
return open(&dirFile, path, oflag);
}
/** \deprecated Do not use in new apps
* \param[in] dirFile An open SdFat instance for the directory containing the
* file to be opened.
* \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
* \return true for success or false for failure.
*/
bool open(SdBaseFile& dirFile, const char* path) { // NOLINT
return open(dirFile, path, O_RDWR);
}
/** \deprecated Use:
* bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
* \param[in] dirFile An open SdFat instance for the directory.
* \param[in] index The \a index of the directory entry for the file to be
* opened. The value for \a index is (directory file position)/32.
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
* OR of flags O_READ, O_WRITE, O_TRUNC, and O_SYNC.
* \return true for success or false for failure.
*/
bool open(SdBaseFile& dirFile, uint16_t index, uint8_t oflag) { // NOLINT
return open(&dirFile, index, oflag);
}
/** \deprecated Use: bool openRoot(SdVolume* vol);
* \param[in] vol The FAT volume containing the root directory to be opened.
* \return true for success or false for failure.
*/
bool openRoot(SdVolume& vol) {return openRoot(&vol);} // NOLINT
/** \deprecated Use: int8_t readDir(dir_t* dir);
* \param[out] dir The dir_t struct that will receive the data.
* \return bytes read for success zero for eof or -1 for failure.
*/
int8_t readDir(dir_t& dir, char* longFilename) {return readDir(&dir, longFilename);} // NOLINT
/** \deprecated Use:
* static uint8_t remove(SdBaseFile* dirFile, const char* path);
* \param[in] dirFile The directory that contains the file.
* \param[in] path The name of the file to be removed.
* \return true for success or false for failure.
*/
static bool remove(SdBaseFile& dirFile, const char* path) { // NOLINT
return remove(&dirFile, path);
}
//------------------------------------------------------------------------------
// rest are private
private:
static void (*oldDateTime_)(uint16_t& date, uint16_t& time); // NOLINT
static void oldToNew(uint16_t* date, uint16_t* time) {
uint16_t d;
uint16_t t;
oldDateTime_(d, t);
*date = d;
*time = t;
}
#endif // ALLOW_DEPRECATED_FUNCTIONS
};
#endif // _SDBASEFILE_H_
#endif // SdBaseFile_h
#endif

View File

@@ -21,96 +21,114 @@
*/
/**
* SdFatConfig.h
* Arduino SdFat Library
* Copyright (C) 2009 by William Greiman
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SDFATCONFIG_H_
#define _SDFATCONFIG_H_
#include "MarlinConfig.h"
/**
* To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
*
* Using multiple cards costs 400 - 500 bytes of flash.
*
* Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
* \file
* \brief configuration definitions
*/
#define USE_MULTIPLE_CARDS 0
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
/**
* Call flush for endl if ENDL_CALLS_FLUSH is nonzero
*
* The standard for iostreams is to call flush. This is very costly for
* SdFat. Each call to flush causes 2048 bytes of I/O to the SD.
*
* SdFat has a single 512 byte buffer for SD I/O so it must write the current
* data block to the SD, read the directory block from the SD, update the
* directory entry, write the directory block to the SD and read the data
* block back into the buffer.
*
* The SD flash memory controller is not designed for this many rewrites
* so performance may be reduced by more than a factor of 100.
*
* If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
* all data to be written to the SD.
*/
#define ENDL_CALLS_FLUSH 0
#ifndef SdFatConfig_h
#define SdFatConfig_h
#include <stdint.h>
//------------------------------------------------------------------------------
/**
* To use multiple SD cards set USE_MULTIPLE_CARDS nonzero.
*
* Using multiple cards costs 400 - 500 bytes of flash.
*
* Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
*/
#define USE_MULTIPLE_CARDS 0
//------------------------------------------------------------------------------
/**
* Call flush for endl if ENDL_CALLS_FLUSH is nonzero
*
* The standard for iostreams is to call flush. This is very costly for
* SdFat. Each call to flush causes 2048 bytes of I/O to the SD.
*
* SdFat has a single 512 byte buffer for SD I/O so it must write the current
* data block to the SD, read the directory block from the SD, update the
* directory entry, write the directory block to the SD and read the data
* block back into the buffer.
*
* The SD flash memory controller is not designed for this many rewrites
* so performance may be reduced by more than a factor of 100.
*
* If ENDL_CALLS_FLUSH is zero, you must call flush and/or close to force
* all data to be written to the SD.
*/
#define ENDL_CALLS_FLUSH 0
//------------------------------------------------------------------------------
/**
* Allow use of deprecated functions if ALLOW_DEPRECATED_FUNCTIONS is nonzero
*/
#define ALLOW_DEPRECATED_FUNCTIONS 1
//------------------------------------------------------------------------------
/**
* Allow FAT12 volumes if FAT12_SUPPORT is nonzero.
* FAT12 has not been well tested.
*/
#define FAT12_SUPPORT 0
//------------------------------------------------------------------------------
/**
* SPI init rate for SD initialization commands. Must be 5 (F_CPU/64)
* or 6 (F_CPU/128).
*/
#define SPI_SD_INIT_RATE 5
//------------------------------------------------------------------------------
/**
* Set the SS pin high for hardware SPI. If SS is chip select for another SPI
* device this will disable that device during the SD init phase.
*/
#define SET_SPI_SS_HIGH 1
//------------------------------------------------------------------------------
/**
* Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos.
* Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
*
* MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
* on Mega Arduinos. Software SPI works well with GPS Shield V1.1
* but many SD cards will fail with GPS Shield V1.0.
*/
#define MEGA_SOFT_SPI 0
//------------------------------------------------------------------------------
/**
* Set USE_SOFTWARE_SPI nonzero to always use software SPI.
*/
#define USE_SOFTWARE_SPI 0
// define software SPI pins so Mega can use unmodified 168/328 shields
/** Software SPI chip select pin for the SD */
#define SOFT_SPI_CS_PIN 10
/** Software SPI Master Out Slave In pin */
#define SOFT_SPI_MOSI_PIN 11
/** Software SPI Master In Slave Out pin */
#define SOFT_SPI_MISO_PIN 12
/** Software SPI Clock pin */
#define SOFT_SPI_SCK_PIN 13
//------------------------------------------------------------------------------
/**
* The __cxa_pure_virtual function is an error handler that is invoked when
* a pure virtual function is called.
*/
#define USE_CXA_PURE_VIRTUAL 1
/**
* Allow FAT12 volumes if FAT12_SUPPORT is nonzero.
* FAT12 has not been well tested.
*/
#define FAT12_SUPPORT 0
/** Number of UTF-16 characters per entry */
#define FILENAME_LENGTH 13
/**
* SPI init rate for SD initialization commands. Must be 5 (F_CPU/64)
* or 6 (F_CPU/128).
*/
#define SPI_SD_INIT_RATE 5
/**
* Defines for long (vfat) filenames
*/
/** Number of VFAT entries used. Every entry has 13 UTF-16 characters */
#define MAX_VFAT_ENTRIES (2)
/** Total size of the buffer used to store the long filenames */
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH*MAX_VFAT_ENTRIES+1)
#endif // SdFatConfig_h
/**
* Set the SS pin high for hardware SPI. If SS is chip select for another SPI
* device this will disable that device during the SD init phase.
*/
#define SET_SPI_SS_HIGH 1
/**
* Define MEGA_SOFT_SPI nonzero to use software SPI on Mega Arduinos.
* Pins used are SS 10, MOSI 11, MISO 12, and SCK 13.
*
* MEGA_SOFT_SPI allows an unmodified Adafruit GPS Shield to be used
* on Mega Arduinos. Software SPI works well with GPS Shield V1.1
* but many SD cards will fail with GPS Shield V1.0.
*/
#define MEGA_SOFT_SPI 0
// Set USE_SOFTWARE_SPI nonzero to ALWAYS use Software SPI.
#define USE_SOFTWARE_SPI 0
// Define software SPI pins so Mega can use unmodified 168/328 shields
#define SOFT_SPI_CS_PIN 10 // Software SPI chip select pin for the SD
#define SOFT_SPI_MOSI_PIN 11 // Software SPI Master Out Slave In pin
#define SOFT_SPI_MISO_PIN 12 // Software SPI Master In Slave Out pin
#define SOFT_SPI_SCK_PIN 13 // Software SPI Clock pin
/**
* The __cxa_pure_virtual function is an error handler that is invoked when
* a pure virtual function is called.
*/
#define USE_CXA_PURE_VIRTUAL 1
/**
* Defines for 8.3 and long (vfat) filenames
*/
#define FILENAME_LENGTH 13 // Number of UTF-16 characters per entry
// Total bytes needed to store a single long filename
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * MAX_VFAT_ENTRIES + 1)
#endif // _SDFATCONFIG_H_
#endif

View File

@@ -20,31 +20,35 @@
*
*/
/**
* \file
* \brief FAT file structures
*/
/**
* Arduino SdFat Library
* Copyright (C) 2009 by William Greiman
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef SDFATSTRUCTS_H
#define SDFATSTRUCTS_H
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#ifndef SdFatStructs_h
#define SdFatStructs_h
#define PACKED __attribute__((__packed__))
/**
* \file
* \brief FAT file structures
*/
/**
* mostly from Microsoft document fatgen103.doc
* http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
*/
uint8_t const BOOTSIG0 = 0x55, // Value for byte 510 of boot block or MBR
BOOTSIG1 = 0xAA, // Value for byte 511 of boot block or MBR
EXTENDED_BOOT_SIG = 0x29; // Value for bootSignature field int FAT/FAT32 boot sector
//------------------------------------------------------------------------------
/** Value for byte 510 of boot block or MBR */
uint8_t const BOOTSIG0 = 0X55;
/** Value for byte 511 of boot block or MBR */
uint8_t const BOOTSIG1 = 0XAA;
/** Value for bootSignature field int FAT/FAT32 boot sector */
uint8_t const EXTENDED_BOOT_SIG = 0X29;
//------------------------------------------------------------------------------
/**
* \struct partitionTable
* \brief MBR partition table entry
@@ -53,58 +57,59 @@ uint8_t const BOOTSIG0 = 0x55, // Value for byte 510 of boot block or M
* The MBR partition table has four entries.
*/
struct partitionTable {
/**
* Boot Indicator . Indicates whether the volume is the active
* partition. Legal values include: 0x00. Do not use for booting.
* 0x80 Active partition.
*/
/**
* Boot Indicator . Indicates whether the volume is the active
* partition. Legal values include: 0X00. Do not use for booting.
* 0X80 Active partition.
*/
uint8_t boot;
/**
* Head part of Cylinder-head-sector address of the first block in
* the partition. Legal values are 0-255. Only used in old PC BIOS.
*/
/**
* Head part of Cylinder-head-sector address of the first block in
* the partition. Legal values are 0-255. Only used in old PC BIOS.
*/
uint8_t beginHead;
/**
* Sector part of Cylinder-head-sector address of the first block in
* the partition. Legal values are 1-63. Only used in old PC BIOS.
*/
/**
* Sector part of Cylinder-head-sector address of the first block in
* the partition. Legal values are 1-63. Only used in old PC BIOS.
*/
unsigned beginSector : 6;
/** High bits cylinder for first block in partition. */
/** High bits cylinder for first block in partition. */
unsigned beginCylinderHigh : 2;
/**
* Combine beginCylinderLow with beginCylinderHigh. Legal values
* are 0-1023. Only used in old PC BIOS.
*/
/**
* Combine beginCylinderLow with beginCylinderHigh. Legal values
* are 0-1023. Only used in old PC BIOS.
*/
uint8_t beginCylinderLow;
/**
* Partition type. See defines that begin with PART_TYPE_ for
* some Microsoft partition types.
*/
/**
* Partition type. See defines that begin with PART_TYPE_ for
* some Microsoft partition types.
*/
uint8_t type;
/**
* head part of cylinder-head-sector address of the last sector in the
* partition. Legal values are 0-255. Only used in old PC BIOS.
*/
/**
* head part of cylinder-head-sector address of the last sector in the
* partition. Legal values are 0-255. Only used in old PC BIOS.
*/
uint8_t endHead;
/**
* Sector part of cylinder-head-sector address of the last sector in
* the partition. Legal values are 1-63. Only used in old PC BIOS.
*/
/**
* Sector part of cylinder-head-sector address of the last sector in
* the partition. Legal values are 1-63. Only used in old PC BIOS.
*/
unsigned endSector : 6;
/** High bits of end cylinder */
/** High bits of end cylinder */
unsigned endCylinderHigh : 2;
/**
* Combine endCylinderLow with endCylinderHigh. Legal values
* are 0-1023. Only used in old PC BIOS.
*/
/**
* Combine endCylinderLow with endCylinderHigh. Legal values
* are 0-1023. Only used in old PC BIOS.
*/
uint8_t endCylinderLow;
uint32_t firstSector; // Logical block address of the first block in the partition.
uint32_t totalSectors; // Length of the partition, in blocks.
/** Logical block address of the first block in the partition. */
uint32_t firstSector;
/** Length of the partition, in blocks. */
uint32_t totalSectors;
} PACKED;
typedef struct partitionTable part_t; // Type name for partitionTable
/** Type name for partitionTable */
typedef struct partitionTable part_t;
//------------------------------------------------------------------------------
/**
* \struct masterBootRecord
*
@@ -113,16 +118,22 @@ typedef struct partitionTable part_t; // Type name for partitionTable
* The first block of a storage device that is formatted with a MBR.
*/
struct masterBootRecord {
uint8_t codeArea[440]; // Code Area for master boot program.
uint32_t diskSignature; // Optional Windows NT disk signature. May contain boot code.
uint16_t usuallyZero; // Usually zero but may be more boot code.
part_t part[4]; // Partition tables.
uint8_t mbrSig0; // First MBR signature byte. Must be 0x55
uint8_t mbrSig1; // Second MBR signature byte. Must be 0xAA
/** Code Area for master boot program. */
uint8_t codeArea[440];
/** Optional Windows NT disk signature. May contain boot code. */
uint32_t diskSignature;
/** Usually zero but may be more boot code. */
uint16_t usuallyZero;
/** Partition tables. */
part_t part[4];
/** First MBR signature byte. Must be 0X55 */
uint8_t mbrSig0;
/** Second MBR signature byte. Must be 0XAA */
uint8_t mbrSig1;
} PACKED;
/** Type name for masterBootRecord */
typedef struct masterBootRecord mbr_t;
//------------------------------------------------------------------------------
/**
* \struct fat_boot
*
@@ -130,280 +141,285 @@ typedef struct masterBootRecord mbr_t;
*
*/
struct fat_boot {
/**
* The first three bytes of the boot sector must be valid,
* executable x 86-based CPU instructions. This includes a
* jump instruction that skips the next nonexecutable bytes.
*/
/**
* The first three bytes of the boot sector must be valid,
* executable x 86-based CPU instructions. This includes a
* jump instruction that skips the next nonexecutable bytes.
*/
uint8_t jump[3];
/**
* This is typically a string of characters that identifies
* the operating system that formatted the volume.
*/
/**
* This is typically a string of characters that identifies
* the operating system that formatted the volume.
*/
char oemId[8];
/**
* The size of a hardware sector. Valid decimal values for this
* field are 512, 1024, 2048, and 4096. For most disks used in
* the United States, the value of this field is 512.
*/
/**
* The size of a hardware sector. Valid decimal values for this
* field are 512, 1024, 2048, and 4096. For most disks used in
* the United States, the value of this field is 512.
*/
uint16_t bytesPerSector;
/**
* Number of sectors per allocation unit. This value must be a
* power of 2 that is greater than 0. The legal values are
* 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.
*/
/**
* Number of sectors per allocation unit. This value must be a
* power of 2 that is greater than 0. The legal values are
* 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.
*/
uint8_t sectorsPerCluster;
/**
* The number of sectors preceding the start of the first FAT,
* including the boot sector. The value of this field is always 1.
*/
/**
* The number of sectors preceding the start of the first FAT,
* including the boot sector. The value of this field is always 1.
*/
uint16_t reservedSectorCount;
/**
* The number of copies of the FAT on the volume.
* The value of this field is always 2.
*/
/**
* The number of copies of the FAT on the volume.
* The value of this field is always 2.
*/
uint8_t fatCount;
/**
* For FAT12 and FAT16 volumes, this field contains the count of
* 32-byte directory entries in the root directory. For FAT32 volumes,
* this field must be set to 0. For FAT12 and FAT16 volumes, this
* value should always specify a count that when multiplied by 32
* results in a multiple of bytesPerSector. FAT16 volumes should
* use the value 512.
*/
/**
* For FAT12 and FAT16 volumes, this field contains the count of
* 32-byte directory entries in the root directory. For FAT32 volumes,
* this field must be set to 0. For FAT12 and FAT16 volumes, this
* value should always specify a count that when multiplied by 32
* results in a multiple of bytesPerSector. FAT16 volumes should
* use the value 512.
*/
uint16_t rootDirEntryCount;
/**
* This field is the old 16-bit total count of sectors on the volume.
* This count includes the count of all sectors in all four regions
* of the volume. This field can be 0; if it is 0, then totalSectors32
* must be nonzero. For FAT32 volumes, this field must be 0. For
* FAT12 and FAT16 volumes, this field contains the sector count, and
* totalSectors32 is 0 if the total sector count fits
* (is less than 0x10000).
*/
/**
* This field is the old 16-bit total count of sectors on the volume.
* This count includes the count of all sectors in all four regions
* of the volume. This field can be 0; if it is 0, then totalSectors32
* must be nonzero. For FAT32 volumes, this field must be 0. For
* FAT12 and FAT16 volumes, this field contains the sector count, and
* totalSectors32 is 0 if the total sector count fits
* (is less than 0x10000).
*/
uint16_t totalSectors16;
/**
* This dates back to the old MS-DOS 1.x media determination and is
* no longer usually used for anything. 0xF8 is the standard value
* for fixed (nonremovable) media. For removable media, 0xF0 is
* frequently used. Legal values are 0xF0 or 0xF8-0xFF.
*/
/**
* This dates back to the old MS-DOS 1.x media determination and is
* no longer usually used for anything. 0xF8 is the standard value
* for fixed (nonremovable) media. For removable media, 0xF0 is
* frequently used. Legal values are 0xF0 or 0xF8-0xFF.
*/
uint8_t mediaType;
/**
* Count of sectors occupied by one FAT on FAT12/FAT16 volumes.
* On FAT32 volumes this field must be 0, and sectorsPerFat32
* contains the FAT size count.
*/
/**
* Count of sectors occupied by one FAT on FAT12/FAT16 volumes.
* On FAT32 volumes this field must be 0, and sectorsPerFat32
* contains the FAT size count.
*/
uint16_t sectorsPerFat16;
uint16_t sectorsPerTrack; // Sectors per track for interrupt 0x13. Not used otherwise.
uint16_t headCount; // Number of heads for interrupt 0x13. Not used otherwise.
/**
* Count of hidden sectors preceding the partition that contains this
* FAT volume. This field is generally only relevant for media
* visible on interrupt 0x13.
*/
/** Sectors per track for interrupt 0x13. Not used otherwise. */
uint16_t sectorsPerTrack;
/** Number of heads for interrupt 0x13. Not used otherwise. */
uint16_t headCount;
/**
* Count of hidden sectors preceding the partition that contains this
* FAT volume. This field is generally only relevant for media
* visible on interrupt 0x13.
*/
uint32_t hidddenSectors;
/**
* This field is the new 32-bit total count of sectors on the volume.
* This count includes the count of all sectors in all four regions
* of the volume. This field can be 0; if it is 0, then
* totalSectors16 must be nonzero.
*/
/**
* This field is the new 32-bit total count of sectors on the volume.
* This count includes the count of all sectors in all four regions
* of the volume. This field can be 0; if it is 0, then
* totalSectors16 must be nonzero.
*/
uint32_t totalSectors32;
/**
* Related to the BIOS physical drive number. Floppy drives are
* identified as 0x00 and physical hard disks are identified as
* 0x80, regardless of the number of physical disk drives.
* Typically, this value is set prior to issuing an INT 13h BIOS
* call to specify the device to access. The value is only
* relevant if the device is a boot device.
*/
/**
* Related to the BIOS physical drive number. Floppy drives are
* identified as 0x00 and physical hard disks are identified as
* 0x80, regardless of the number of physical disk drives.
* Typically, this value is set prior to issuing an INT 13h BIOS
* call to specify the device to access. The value is only
* relevant if the device is a boot device.
*/
uint8_t driveNumber;
uint8_t reserved1; // used by Windows NT - should be zero for FAT
uint8_t bootSignature; // 0x29 if next three fields are valid
/**
* A random serial number created when formatting a disk,
* which helps to distinguish between disks.
* Usually generated by combining date and time.
*/
/** used by Windows NT - should be zero for FAT */
uint8_t reserved1;
/** 0X29 if next three fields are valid */
uint8_t bootSignature;
/**
* A random serial number created when formatting a disk,
* which helps to distinguish between disks.
* Usually generated by combining date and time.
*/
uint32_t volumeSerialNumber;
/**
* A field once used to store the volume label. The volume label
* is now stored as a special file in the root directory.
*/
/**
* A field once used to store the volume label. The volume label
* is now stored as a special file in the root directory.
*/
char volumeLabel[11];
/**
* A field with a value of either FAT, FAT12 or FAT16,
* depending on the disk format.
*/
/**
* A field with a value of either FAT, FAT12 or FAT16,
* depending on the disk format.
*/
char fileSystemType[8];
uint8_t bootCode[448]; // X86 boot code
uint8_t bootSectorSig0; // must be 0x55
uint8_t bootSectorSig1; // must be 0xAA
/** X86 boot code */
uint8_t bootCode[448];
/** must be 0X55 */
uint8_t bootSectorSig0;
/** must be 0XAA */
uint8_t bootSectorSig1;
} PACKED;
typedef struct fat_boot fat_boot_t; // Type name for FAT Boot Sector
/** Type name for FAT Boot Sector */
typedef struct fat_boot fat_boot_t;
//------------------------------------------------------------------------------
/**
* \struct fat32_boot
*
* \brief Boot sector for a FAT32 volume.
*
*/
struct fat32_boot {
/**
* The first three bytes of the boot sector must be valid,
* executable x 86-based CPU instructions. This includes a
* jump instruction that skips the next nonexecutable bytes.
*/
/**
* The first three bytes of the boot sector must be valid,
* executable x 86-based CPU instructions. This includes a
* jump instruction that skips the next nonexecutable bytes.
*/
uint8_t jump[3];
/**
* This is typically a string of characters that identifies
* the operating system that formatted the volume.
*/
/**
* This is typically a string of characters that identifies
* the operating system that formatted the volume.
*/
char oemId[8];
/**
* The size of a hardware sector. Valid decimal values for this
* field are 512, 1024, 2048, and 4096. For most disks used in
* the United States, the value of this field is 512.
*/
/**
* The size of a hardware sector. Valid decimal values for this
* field are 512, 1024, 2048, and 4096. For most disks used in
* the United States, the value of this field is 512.
*/
uint16_t bytesPerSector;
/**
* Number of sectors per allocation unit. This value must be a
* power of 2 that is greater than 0. The legal values are
* 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.
*/
/**
* Number of sectors per allocation unit. This value must be a
* power of 2 that is greater than 0. The legal values are
* 1, 2, 4, 8, 16, 32, 64, and 128. 128 should be avoided.
*/
uint8_t sectorsPerCluster;
/**
* The number of sectors preceding the start of the first FAT,
* including the boot sector. Must not be zero
*/
/**
* The number of sectors preceding the start of the first FAT,
* including the boot sector. Must not be zero
*/
uint16_t reservedSectorCount;
/**
* The number of copies of the FAT on the volume.
* The value of this field is always 2.
*/
/**
* The number of copies of the FAT on the volume.
* The value of this field is always 2.
*/
uint8_t fatCount;
/**
* FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0.
*/
/**
* FAT12/FAT16 only. For FAT32 volumes, this field must be set to 0.
*/
uint16_t rootDirEntryCount;
/**
* For FAT32 volumes, this field must be 0.
*/
/**
* For FAT32 volumes, this field must be 0.
*/
uint16_t totalSectors16;
/**
* This dates back to the old MS-DOS 1.x media determination and is
* no longer usually used for anything. 0xF8 is the standard value
* for fixed (nonremovable) media. For removable media, 0xF0 is
* frequently used. Legal values are 0xF0 or 0xF8-0xFF.
*/
/**
* This dates back to the old MS-DOS 1.x media determination and is
* no longer usually used for anything. 0xF8 is the standard value
* for fixed (nonremovable) media. For removable media, 0xF0 is
* frequently used. Legal values are 0xF0 or 0xF8-0xFF.
*/
uint8_t mediaType;
/**
* On FAT32 volumes this field must be 0, and sectorsPerFat32
* contains the FAT size count.
*/
/**
* On FAT32 volumes this field must be 0, and sectorsPerFat32
* contains the FAT size count.
*/
uint16_t sectorsPerFat16;
uint16_t sectorsPerTrack; // Sectors per track for interrupt 0x13. Not used otherwise.
uint16_t headCount; // Number of heads for interrupt 0x13. Not used otherwise.
/**
* Count of hidden sectors preceding the partition that contains this
* FAT volume. This field is generally only relevant for media
* visible on interrupt 0x13.
*/
/** Sectors per track for interrupt 0x13. Not used otherwise. */
uint16_t sectorsPerTrack;
/** Number of heads for interrupt 0x13. Not used otherwise. */
uint16_t headCount;
/**
* Count of hidden sectors preceding the partition that contains this
* FAT volume. This field is generally only relevant for media
* visible on interrupt 0x13.
*/
uint32_t hidddenSectors;
/**
* Contains the total number of sectors in the FAT32 volume.
*/
/**
* Contains the total number of sectors in the FAT32 volume.
*/
uint32_t totalSectors32;
/**
* Count of sectors occupied by one FAT on FAT32 volumes.
*/
/**
* Count of sectors occupied by one FAT on FAT32 volumes.
*/
uint32_t sectorsPerFat32;
/**
* This field is only defined for FAT32 media and does not exist on
* FAT12 and FAT16 media.
* Bits 0-3 -- Zero-based number of active FAT.
* Only valid if mirroring is disabled.
* Bits 4-6 -- Reserved.
* Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
* -- 1 means only one FAT is active; it is the one referenced
* in bits 0-3.
* Bits 8-15 -- Reserved.
*/
/**
* This field is only defined for FAT32 media and does not exist on
* FAT12 and FAT16 media.
* Bits 0-3 -- Zero-based number of active FAT.
* Only valid if mirroring is disabled.
* Bits 4-6 -- Reserved.
* Bit 7 -- 0 means the FAT is mirrored at runtime into all FATs.
* -- 1 means only one FAT is active; it is the one referenced
* in bits 0-3.
* Bits 8-15 -- Reserved.
*/
uint16_t fat32Flags;
/**
* FAT32 version. High byte is major revision number.
* Low byte is minor revision number. Only 0.0 define.
*/
/**
* FAT32 version. High byte is major revision number.
* Low byte is minor revision number. Only 0.0 define.
*/
uint16_t fat32Version;
/**
* Cluster number of the first cluster of the root directory for FAT32.
* This usually 2 but not required to be 2.
*/
/**
* Cluster number of the first cluster of the root directory for FAT32.
* This usually 2 but not required to be 2.
*/
uint32_t fat32RootCluster;
/**
* Sector number of FSINFO structure in the reserved area of the
* FAT32 volume. Usually 1.
*/
/**
* Sector number of FSINFO structure in the reserved area of the
* FAT32 volume. Usually 1.
*/
uint16_t fat32FSInfo;
/**
* If nonzero, indicates the sector number in the reserved area
* of the volume of a copy of the boot record. Usually 6.
* No value other than 6 is recommended.
*/
/**
* If nonzero, indicates the sector number in the reserved area
* of the volume of a copy of the boot record. Usually 6.
* No value other than 6 is recommended.
*/
uint16_t fat32BackBootBlock;
/**
* Reserved for future expansion. Code that formats FAT32 volumes
* should always set all of the bytes of this field to 0.
*/
/**
* Reserved for future expansion. Code that formats FAT32 volumes
* should always set all of the bytes of this field to 0.
*/
uint8_t fat32Reserved[12];
/**
* Related to the BIOS physical drive number. Floppy drives are
* identified as 0x00 and physical hard disks are identified as
* 0x80, regardless of the number of physical disk drives.
* Typically, this value is set prior to issuing an INT 13h BIOS
* call to specify the device to access. The value is only
* relevant if the device is a boot device.
*/
/**
* Related to the BIOS physical drive number. Floppy drives are
* identified as 0x00 and physical hard disks are identified as
* 0x80, regardless of the number of physical disk drives.
* Typically, this value is set prior to issuing an INT 13h BIOS
* call to specify the device to access. The value is only
* relevant if the device is a boot device.
*/
uint8_t driveNumber;
uint8_t reserved1; // Used by Windows NT - should be zero for FAT
uint8_t bootSignature; // 0x29 if next three fields are valid
/**
* A random serial number created when formatting a disk,
* which helps to distinguish between disks.
* Usually generated by combining date and time.
*/
/** used by Windows NT - should be zero for FAT */
uint8_t reserved1;
/** 0X29 if next three fields are valid */
uint8_t bootSignature;
/**
* A random serial number created when formatting a disk,
* which helps to distinguish between disks.
* Usually generated by combining date and time.
*/
uint32_t volumeSerialNumber;
/**
* A field once used to store the volume label. The volume label
* is now stored as a special file in the root directory.
*/
/**
* A field once used to store the volume label. The volume label
* is now stored as a special file in the root directory.
*/
char volumeLabel[11];
/**
* A text field with a value of FAT32.
*/
/**
* A text field with a value of FAT32.
*/
char fileSystemType[8];
uint8_t bootCode[420]; // X86 boot code
uint8_t bootSectorSig0; // must be 0x55
uint8_t bootSectorSig1; // must be 0xAA
/** X86 boot code */
uint8_t bootCode[420];
/** must be 0X55 */
uint8_t bootSectorSig0;
/** must be 0XAA */
uint8_t bootSectorSig1;
} PACKED;
typedef struct fat32_boot fat32_boot_t; // Type name for FAT32 Boot Sector
uint32_t const FSINFO_LEAD_SIG = 0x41615252, // 'AaRR' Lead signature for a FSINFO sector
FSINFO_STRUCT_SIG = 0x61417272; // 'aArr' Struct signature for a FSINFO sector
/** Type name for FAT32 Boot Sector */
typedef struct fat32_boot fat32_boot_t;
//------------------------------------------------------------------------------
/** Lead signature for a FSINFO sector */
uint32_t const FSINFO_LEAD_SIG = 0x41615252;
/** Struct signature for a FSINFO sector */
uint32_t const FSINFO_STRUCT_SIG = 0x61417272;
/**
* \struct fat32_fsinfo
*
@@ -411,9 +427,12 @@ uint32_t const FSINFO_LEAD_SIG = 0x41615252, // 'AaRR' Lead signature for a F
*
*/
struct fat32_fsinfo {
uint32_t leadSignature; // must be 0x52, 0x52, 0x61, 0x41 'RRaA'
uint8_t reserved1[480]; // must be zero
uint32_t structSignature; // must be 0x72, 0x72, 0x41, 0x61 'rrAa'
/** must be 0X52, 0X52, 0X61, 0X41 */
uint32_t leadSignature;
/** must be zero */
uint8_t reserved1[480];
/** must be 0X72, 0X72, 0X41, 0X61 */
uint32_t structSignature;
/**
* Contains the last known free cluster count on the volume.
* If the value is 0xFFFFFFFF, then the free count is unknown
@@ -429,22 +448,30 @@ struct fat32_fsinfo {
* should start looking at cluster 2.
*/
uint32_t nextFree;
uint8_t reserved2[12]; // must be zero
uint8_t tailSignature[4]; // must be 0x00, 0x00, 0x55, 0xAA
/** must be zero */
uint8_t reserved2[12];
/** must be 0X00, 0X00, 0X55, 0XAA */
uint8_t tailSignature[4];
} PACKED;
typedef struct fat32_fsinfo fat32_fsinfo_t; // Type name for FAT32 FSINFO Sector
/** Type name for FAT32 FSINFO Sector */
typedef struct fat32_fsinfo fat32_fsinfo_t;
//------------------------------------------------------------------------------
// End Of Chain values for FAT entries
uint16_t const FAT12EOC = 0xFFF, // FAT12 end of chain value used by Microsoft.
FAT12EOC_MIN = 0xFF8, // Minimum value for FAT12 EOC. Use to test for EOC.
FAT16EOC = 0xFFFF, // FAT16 end of chain value used by Microsoft.
FAT16EOC_MIN = 0xFFF8; // Minimum value for FAT16 EOC. Use to test for EOC.
uint32_t const FAT32EOC = 0x0FFFFFFF, // FAT32 end of chain value used by Microsoft.
FAT32EOC_MIN = 0x0FFFFFF8, // Minimum value for FAT32 EOC. Use to test for EOC.
FAT32MASK = 0x0FFFFFFF; // Mask a for FAT32 entry. Entries are 28 bits.
/** FAT12 end of chain value used by Microsoft. */
uint16_t const FAT12EOC = 0XFFF;
/** Minimum value for FAT12 EOC. Use to test for EOC. */
uint16_t const FAT12EOC_MIN = 0XFF8;
/** FAT16 end of chain value used by Microsoft. */
uint16_t const FAT16EOC = 0XFFFF;
/** Minimum value for FAT16 EOC. Use to test for EOC. */
uint16_t const FAT16EOC_MIN = 0XFFF8;
/** FAT32 end of chain value used by Microsoft. */
uint32_t const FAT32EOC = 0X0FFFFFFF;
/** Minimum value for FAT32 EOC. Use to test for EOC. */
uint32_t const FAT32EOC_MIN = 0X0FFFFFF8;
/** Mask a for FAT32 entry. Entries are 28 bits. */
uint32_t const FAT32MASK = 0X0FFFFFFF;
//------------------------------------------------------------------------------
/**
* \struct directoryEntry
* \brief FAT short directory entry
@@ -476,54 +503,54 @@ uint32_t const FAT32EOC = 0x0FFFFFFF, // FAT32 end of chain value used by Mi
* The valid time range is from Midnight 00:00:00 to 23:59:58.
*/
struct directoryEntry {
/**
* Short 8.3 name.
*
* The first eight bytes contain the file name with blank fill.
* The last three bytes contain the file extension with blank fill.
*/
/** Short 8.3 name.
*
* The first eight bytes contain the file name with blank fill.
* The last three bytes contain the file extension with blank fill.
*/
uint8_t name[11];
/**
* Entry attributes.
*
* The upper two bits of the attribute byte are reserved and should
* always be set to 0 when a file is created and never modified or
* looked at after that. See defines that begin with DIR_ATT_.
*/
/** Entry attributes.
*
* The upper two bits of the attribute byte are reserved and should
* always be set to 0 when a file is created and never modified or
* looked at after that. See defines that begin with DIR_ATT_.
*/
uint8_t attributes;
/**
* Reserved for use by Windows NT. Set value to 0 when a file is
* created and never modify or look at it after that.
*/
/**
* Reserved for use by Windows NT. Set value to 0 when a file is
* created and never modify or look at it after that.
*/
uint8_t reservedNT;
/**
* The granularity of the seconds part of creationTime is 2 seconds
* so this field is a count of tenths of a second and it's valid
* value range is 0-199 inclusive. (WHG note - seems to be hundredths)
*/
/**
* The granularity of the seconds part of creationTime is 2 seconds
* so this field is a count of tenths of a second and its valid
* value range is 0-199 inclusive. (WHG note - seems to be hundredths)
*/
uint8_t creationTimeTenths;
uint16_t creationTime; // Time file was created.
uint16_t creationDate; // Date file was created.
/**
* Last access date. Note that there is no last access time, only
* a date. This is the date of last read or write. In the case of
* a write, this should be set to the same date as lastWriteDate.
*/
/** Time file was created. */
uint16_t creationTime;
/** Date file was created. */
uint16_t creationDate;
/**
* Last access date. Note that there is no last access time, only
* a date. This is the date of last read or write. In the case of
* a write, this should be set to the same date as lastWriteDate.
*/
uint16_t lastAccessDate;
/**
* High word of this entry's first cluster number (always 0 for a
* FAT12 or FAT16 volume).
*/
/**
* High word of this entry's first cluster number (always 0 for a
* FAT12 or FAT16 volume).
*/
uint16_t firstClusterHigh;
uint16_t lastWriteTime; // Time of last write. File creation is considered a write.
uint16_t lastWriteDate; // Date of last write. File creation is considered a write.
uint16_t firstClusterLow; // Low word of this entry's first cluster number.
uint32_t fileSize; // 32-bit unsigned holding this file's size in bytes.
/** Time of last write. File creation is considered a write. */
uint16_t lastWriteTime;
/** Date of last write. File creation is considered a write. */
uint16_t lastWriteDate;
/** Low word of this entry's first cluster number. */
uint16_t firstClusterLow;
/** 32-bit unsigned holding this file's size in bytes. */
uint32_t fileSize;
} PACKED;
/**
* \struct directoryVFATEntry
* \brief VFAT long filename directory entry
@@ -541,36 +568,54 @@ struct directoryVFATEntry {
* bit 0-4: the position of this long filename block (first block is 1)
*/
uint8_t sequenceNumber;
uint16_t name1[5]; // First set of UTF-16 characters
uint8_t attributes; // attributes (at the same location as in directoryEntry), always 0x0F
uint8_t reservedNT; // Reserved for use by Windows NT. Always 0.
uint8_t checksum; // Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation.
uint16_t name2[6]; // Second set of UTF-16 characters
uint16_t firstClusterLow; // firstClusterLow is always zero for longFilenames
uint16_t name3[2]; // Third set of UTF-16 characters
/** First set of UTF-16 characters */
uint16_t name1[5];//UTF-16
/** attributes (at the same location as in directoryEntry), always 0x0F */
uint8_t attributes;
/** Reserved for use by Windows NT. Always 0. */
uint8_t reservedNT;
/** Checksum of the short 8.3 filename, can be used to checked if the file system as modified by a not-long-filename aware implementation. */
uint8_t checksum;
/** Second set of UTF-16 characters */
uint16_t name2[6];//UTF-16
/** firstClusterLow is always zero for longFilenames */
uint16_t firstClusterLow;
/** Third set of UTF-16 characters */
uint16_t name3[2];//UTF-16
} PACKED;
//------------------------------------------------------------------------------
// Definitions for directory entries
//
typedef struct directoryEntry dir_t; // Type name for directoryEntry
typedef struct directoryVFATEntry vfat_t; // Type name for directoryVFATEntry
uint8_t const DIR_NAME_0xE5 = 0x05, // escape for name[0] = 0xE5
DIR_NAME_DELETED = 0xE5, // name[0] value for entry that is free after being "deleted"
DIR_NAME_FREE = 0x00, // name[0] value for entry that is free and no allocated entries follow
DIR_ATT_READ_ONLY = 0x01, // file is read-only
DIR_ATT_HIDDEN = 0x02, // File should hidden in directory listings
DIR_ATT_SYSTEM = 0x04, // Entry is for a system file
DIR_ATT_VOLUME_ID = 0x08, // Directory entry contains the volume label
DIR_ATT_DIRECTORY = 0x10, // Entry is for a directory
DIR_ATT_ARCHIVE = 0x20, // Old DOS archive bit for backup support
DIR_ATT_LONG_NAME = 0x0F, // Test value for long name entry. Test is (d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME.
DIR_ATT_LONG_NAME_MASK = 0x3F, // Test mask for long name entry
DIR_ATT_DEFINED_BITS = 0x3F; // defined attribute bits
/**
* Directory entry is part of a long name
/** Type name for directoryEntry */
typedef struct directoryEntry dir_t;
/** Type name for directoryVFATEntry */
typedef struct directoryVFATEntry vfat_t;
/** escape for name[0] = 0XE5 */
uint8_t const DIR_NAME_0XE5 = 0X05;
/** name[0] value for entry that is free after being "deleted" */
uint8_t const DIR_NAME_DELETED = 0XE5;
/** name[0] value for entry that is free and no allocated entries follow */
uint8_t const DIR_NAME_FREE = 0X00;
/** file is read-only */
uint8_t const DIR_ATT_READ_ONLY = 0X01;
/** File should hidden in directory listings */
uint8_t const DIR_ATT_HIDDEN = 0X02;
/** Entry is for a system file */
uint8_t const DIR_ATT_SYSTEM = 0X04;
/** Directory entry contains the volume label */
uint8_t const DIR_ATT_VOLUME_ID = 0X08;
/** Entry is for a directory */
uint8_t const DIR_ATT_DIRECTORY = 0X10;
/** Old DOS archive bit for backup support */
uint8_t const DIR_ATT_ARCHIVE = 0X20;
/** Test value for long name entry. Test is
(d->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME. */
uint8_t const DIR_ATT_LONG_NAME = 0X0F;
/** Test mask for long name entry */
uint8_t const DIR_ATT_LONG_NAME_MASK = 0X3F;
/** defined attribute bits */
uint8_t const DIR_ATT_DEFINED_BITS = 0X3F;
/** Directory entry is part of a long name
* \param[in] dir Pointer to a directory entry.
*
* \return true if the entry is for part of a long name else false.
@@ -578,12 +623,9 @@ uint8_t const DIR_NAME_0xE5 = 0x05, // escape for name[0] = 0xE5
static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME;
}
/** Mask for file/subdirectory tests */
uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
/**
* Directory entry is for a file
/** Directory entry is for a file
* \param[in] dir Pointer to a directory entry.
*
* \return true if the entry is for a normal file else false.
@@ -591,9 +633,7 @@ uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
}
/**
* Directory entry is for a subdirectory
/** Directory entry is for a subdirectory
* \param[in] dir Pointer to a directory entry.
*
* \return true if the entry is for a subdirectory else false.
@@ -601,9 +641,7 @@ static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
}
/**
* Directory entry is for a file or subdirectory
/** Directory entry is for a file or subdirectory
* \param[in] dir Pointer to a directory entry.
*
* \return true if the entry is for a normal file or subdirectory else false.
@@ -611,5 +649,7 @@ static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
}
#endif // SdFatStructs_h
#endif // SDFATSTRUCTS_H
#endif

View File

@@ -26,15 +26,13 @@
*
* This file is part of the Arduino Sd2Card Library
*/
#include "MarlinConfig.h"
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#include "SdFatUtil.h"
#include "serial.h"
/**
* Amount of free RAM
//------------------------------------------------------------------------------
/** Amount of free RAM
* \return The number of free bytes.
*/
#ifdef __arm__
@@ -46,8 +44,7 @@ int SdFatUtil::FreeRam() {
#else // __arm__
extern char* __brkval;
extern char __bss_end;
/**
* Amount of free RAM
/** Amount of free RAM
* \return The number of free bytes.
*/
int SdFatUtil::FreeRam() {
@@ -56,36 +53,39 @@ int SdFatUtil::FreeRam() {
}
#endif // __arm
/**
* %Print a string in flash memory.
//------------------------------------------------------------------------------
/** %Print a string in flash memory.
*
* \param[in] pr Print object for output.
* \param[in] str Pointer to string stored in flash memory.
*/
void SdFatUtil::print_P(PGM_P str) {
for (uint8_t c; (c = pgm_read_byte(str)); str++) SERIAL_CHAR(c);
for (uint8_t c; (c = pgm_read_byte(str)); str++) MYSERIAL.write(c);
}
/**
* %Print a string in flash memory followed by a CR/LF.
//------------------------------------------------------------------------------
/** %Print a string in flash memory followed by a CR/LF.
*
* \param[in] pr Print object for output.
* \param[in] str Pointer to string stored in flash memory.
*/
void SdFatUtil::println_P(PGM_P str) { print_P(str); SERIAL_EOL(); }
/**
* %Print a string in flash memory to Serial.
void SdFatUtil::println_P(PGM_P str) {
print_P(str);
MYSERIAL.println();
}
//------------------------------------------------------------------------------
/** %Print a string in flash memory to Serial.
*
* \param[in] str Pointer to string stored in flash memory.
*/
void SdFatUtil::SerialPrint_P(PGM_P str) { print_P(str); }
/**
* %Print a string in flash memory to Serial followed by a CR/LF.
void SdFatUtil::SerialPrint_P(PGM_P str) {
print_P(str);
}
//------------------------------------------------------------------------------
/** %Print a string in flash memory to Serial followed by a CR/LF.
*
* \param[in] str Pointer to string stored in flash memory.
*/
void SdFatUtil::SerialPrintln_P(PGM_P str) { println_P(str); }
#endif // SDSUPPORT
void SdFatUtil::SerialPrintln_P(PGM_P str) {
println_P(str);
}
#endif

View File

@@ -26,13 +26,17 @@
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SDFATUTIL_H_
#define _SDFATUTIL_H_
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#ifndef SdFatUtil_h
#define SdFatUtil_h
/**
* \file
* \brief Useful utility functions.
*/
#include "Marlin.h"
#include "MarlinSerial.h"
/** Store and print a string in flash memory.*/
#define PgmPrint(x) SerialPrint_P(PSTR(x))
/** Store and print a string in flash memory followed by a CR/LF.*/
@@ -47,5 +51,7 @@ namespace SdFatUtil {
}
using namespace SdFatUtil; // NOLINT
#endif //#define SdFatUtil_h
#endif // _SDFATUTIL_H_
#endif

View File

@@ -26,24 +26,21 @@
*
* This file is part of the Arduino Sd2Card Library
*/
#include "MarlinConfig.h"
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#include "SdFile.h"
/**
* Create a file object and open it in the current working directory.
/** Create a file object and open it in the current working directory.
*
* \param[in] path A path with a valid 8.3 DOS name for a file to be opened.
*
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
* OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t).
*/
SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { }
/**
* Write data to an open file.
SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) {
}
//------------------------------------------------------------------------------
/** Write data to an open file.
*
* \note Data is moved to the cache but may not be written to the
* storage device until sync() is called.
@@ -58,37 +55,41 @@ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { }
* for a read-only file, device is full, a corrupt file system or an I/O error.
*
*/
int16_t SdFile::write(const void* buf, uint16_t nbyte) { return SdBaseFile::write(buf, nbyte); }
/**
* Write a byte to a file. Required by the Arduino Print class.
int16_t SdFile::write(const void* buf, uint16_t nbyte) {
return SdBaseFile::write(buf, nbyte);
}
//------------------------------------------------------------------------------
/** Write a byte to a file. Required by the Arduino Print class.
* \param[in] b the byte to be written.
* Use writeError to check for errors.
*/
#if ARDUINO >= 100
size_t SdFile::write(uint8_t b) { return SdBaseFile::write(&b, 1); }
size_t SdFile::write(uint8_t b) {
return SdBaseFile::write(&b, 1);
}
#else
void SdFile::write(uint8_t b) { SdBaseFile::write(&b, 1); }
void SdFile::write(uint8_t b) {
SdBaseFile::write(&b, 1);
}
#endif
/**
* Write a string to a file. Used by the Arduino Print class.
//------------------------------------------------------------------------------
/** Write a string to a file. Used by the Arduino Print class.
* \param[in] str Pointer to the string.
* Use writeError to check for errors.
*/
void SdFile::write(const char* str) { SdBaseFile::write(str, strlen(str)); }
/**
* Write a PROGMEM string to a file.
void SdFile::write(const char* str) {
SdBaseFile::write(str, strlen(str));
}
//------------------------------------------------------------------------------
/** Write a PROGMEM string to a file.
* \param[in] str Pointer to the PROGMEM string.
* Use writeError to check for errors.
*/
void SdFile::write_P(PGM_P str) {
for (uint8_t c; (c = pgm_read_byte(str)); str++) write(c);
}
/**
* Write a PROGMEM string followed by CR/LF to a file.
//------------------------------------------------------------------------------
/** Write a PROGMEM string followed by CR/LF to a file.
* \param[in] str Pointer to the PROGMEM string.
* Use writeError to check for errors.
*/
@@ -97,4 +98,5 @@ void SdFile::writeln_P(PGM_P str) {
write_P(PSTR("\r\n"));
}
#endif // SDSUPPORT
#endif

View File

@@ -20,23 +20,24 @@
*
*/
/**
* \file
* \brief SdFile class
*/
/**
* Arduino SdFat Library
* Copyright (C) 2009 by William Greiman
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SDFILE_H_
#define _SDFILE_H_
/**
* \file
* \brief SdFile class
*/
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#include "SdBaseFile.h"
#include <Print.h>
#ifndef SdFile_h
#define SdFile_h
//------------------------------------------------------------------------------
/**
* \class SdFile
* \brief SdBaseFile with Print.
@@ -56,5 +57,7 @@ class SdFile : public SdBaseFile, public Print {
void write_P(PGM_P str);
void writeln_P(PGM_P str);
};
#endif // SdFile_h
#endif // _SDFILE_H_
#endif

View File

@@ -26,11 +26,12 @@
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SDINFO_H_
#define _SDINFO_H_
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#ifndef SdInfo_h
#define SdInfo_h
#include <stdint.h>
// Based on the document:
//
// SD Specifications
@@ -41,43 +42,63 @@
// May 18, 2010
//
// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs
//------------------------------------------------------------------------------
// SD card commands
uint8_t const CMD0 = 0x00, // GO_IDLE_STATE - init card in spi mode if CS low
CMD8 = 0x08, // SEND_IF_COND - verify SD Memory Card interface operating condition
CMD9 = 0x09, // SEND_CSD - read the Card Specific Data (CSD register)
CMD10 = 0x0A, // SEND_CID - read the card identification information (CID register)
CMD12 = 0x0C, // STOP_TRANSMISSION - end multiple block read sequence
CMD13 = 0x0D, // SEND_STATUS - read the card status register
CMD17 = 0x11, // READ_SINGLE_BLOCK - read a single data block from the card
CMD18 = 0x12, // READ_MULTIPLE_BLOCK - read a multiple data blocks from the card
CMD24 = 0x18, // WRITE_BLOCK - write a single data block to the card
CMD25 = 0x19, // WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION
CMD32 = 0x20, // ERASE_WR_BLK_START - sets the address of the first block to be erased
CMD33 = 0x21, // ERASE_WR_BLK_END - sets the address of the last block of the continuous range to be erased*/
CMD38 = 0x26, // ERASE - erase all previously selected blocks */
CMD55 = 0x37, // APP_CMD - escape for application specific command */
CMD58 = 0x3A, // READ_OCR - read the OCR register of a card */
ACMD23 = 0x17, // SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be pre-erased before writing */
ACMD41 = 0x29; // SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process */
/** GO_IDLE_STATE - init card in spi mode if CS low */
uint8_t const CMD0 = 0X00;
/** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
uint8_t const CMD8 = 0X08;
/** SEND_CSD - read the Card Specific Data (CSD register) */
uint8_t const CMD9 = 0X09;
/** SEND_CID - read the card identification information (CID register) */
uint8_t const CMD10 = 0X0A;
/** STOP_TRANSMISSION - end multiple block read sequence */
uint8_t const CMD12 = 0X0C;
/** SEND_STATUS - read the card status register */
uint8_t const CMD13 = 0X0D;
/** READ_SINGLE_BLOCK - read a single data block from the card */
uint8_t const CMD17 = 0X11;
/** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card */
uint8_t const CMD18 = 0X12;
/** WRITE_BLOCK - write a single data block to the card */
uint8_t const CMD24 = 0X18;
/** WRITE_MULTIPLE_BLOCK - write blocks of data until a STOP_TRANSMISSION */
uint8_t const CMD25 = 0X19;
/** ERASE_WR_BLK_START - sets the address of the first block to be erased */
uint8_t const CMD32 = 0X20;
/** ERASE_WR_BLK_END - sets the address of the last block of the continuous
range to be erased*/
uint8_t const CMD33 = 0X21;
/** ERASE - erase all previously selected blocks */
uint8_t const CMD38 = 0X26;
/** APP_CMD - escape for application specific command */
uint8_t const CMD55 = 0X37;
/** READ_OCR - read the OCR register of a card */
uint8_t const CMD58 = 0X3A;
/** SET_WR_BLK_ERASE_COUNT - Set the number of write blocks to be
pre-erased before writing */
uint8_t const ACMD23 = 0X17;
/** SD_SEND_OP_COMD - Sends host capacity support information and
activates the card's initialization process */
uint8_t const ACMD41 = 0X29;
//------------------------------------------------------------------------------
/** status for card in the ready state */
uint8_t const R1_READY_STATE = 0x00;
uint8_t const R1_READY_STATE = 0X00;
/** status for card in the idle state */
uint8_t const R1_IDLE_STATE = 0x01;
uint8_t const R1_IDLE_STATE = 0X01;
/** status bit for illegal command */
uint8_t const R1_ILLEGAL_COMMAND = 0x04;
uint8_t const R1_ILLEGAL_COMMAND = 0X04;
/** start data token for read or write single block*/
uint8_t const DATA_START_BLOCK = 0xFE;
uint8_t const DATA_START_BLOCK = 0XFE;
/** stop token for write multiple blocks*/
uint8_t const STOP_TRAN_TOKEN = 0xFD;
uint8_t const STOP_TRAN_TOKEN = 0XFD;
/** start data token for write multiple blocks*/
uint8_t const WRITE_MULTIPLE_TOKEN = 0xFC;
uint8_t const WRITE_MULTIPLE_TOKEN = 0XFC;
/** mask for data response tokens after a write block operation */
uint8_t const DATA_RES_MASK = 0x1F;
uint8_t const DATA_RES_MASK = 0X1F;
/** write data accepted token */
uint8_t const DATA_RES_ACCEPTED = 0x05;
uint8_t const DATA_RES_ACCEPTED = 0X05;
//------------------------------------------------------------------------------
/** Card IDentification (CID) register */
typedef struct CID {
// byte 0
@@ -113,7 +134,7 @@ typedef struct CID {
/** CRC7 checksum */
unsigned char crc : 7;
} cid_t;
//------------------------------------------------------------------------------
/** CSD for version 1.00 cards */
typedef struct CSDV1 {
// byte 0
@@ -175,14 +196,14 @@ typedef struct CSDV1 {
unsigned char always1 : 1;
unsigned char crc : 7;
} csd1_t;
//------------------------------------------------------------------------------
/** CSD for version 2.00 cards */
typedef struct CSDV2 {
// byte 0
unsigned char reserved1 : 6;
unsigned char csd_ver : 2;
// byte 1
/** fixed to 0x0E */
/** fixed to 0X0E */
unsigned char taac;
// byte 2
/** fixed to 0 */
@@ -257,11 +278,12 @@ typedef struct CSDV2 {
/** checksum */
unsigned char crc : 7;
} csd2_t;
//------------------------------------------------------------------------------
/** union of old and new style CSD register */
union csd_t {
csd1_t v1;
csd2_t v2;
};
#endif // SdInfo_h
#endif // _SDINFO_H_
#endif

View File

@@ -26,12 +26,11 @@
*
* This file is part of the Arduino Sd2Card Library
*/
#include "MarlinConfig.h"
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#include "SdVolume.h"
//------------------------------------------------------------------------------
#if !USE_MULTIPLE_CARDS
// raw block cache
uint32_t SdVolume::cacheBlockNumber_; // current block number
@@ -40,7 +39,7 @@
bool SdVolume::cacheDirty_; // cacheFlush() will write block if true
uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT
#endif // USE_MULTIPLE_CARDS
//------------------------------------------------------------------------------
// find a contiguous group of clusters
bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
// start of group
@@ -74,14 +73,14 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
// search the FAT for free clusters
for (uint32_t n = 0;; n++, endCluster++) {
// can't find space checked all clusters
if (n >= clusterCount_) return false;
if (n >= clusterCount_) goto fail;
// past end - start from beginning of FAT
if (endCluster > fatEnd) {
bgnCluster = endCluster = 2;
}
uint32_t f;
if (!fatGet(endCluster, &f)) return false;
if (!fatGet(endCluster, &f)) goto fail;
if (f != 0) {
// cluster in use try next cluster as bgnCluster
@@ -93,16 +92,16 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
}
}
// mark end of chain
if (!fatPutEOC(endCluster)) return false;
if (!fatPutEOC(endCluster)) goto fail;
// link clusters
while (endCluster > bgnCluster) {
if (!fatPut(endCluster - 1, endCluster)) return false;
if (!fatPut(endCluster - 1, endCluster)) goto fail;
endCluster--;
}
if (*curCluster != 0) {
// connect chains
if (!fatPut(*curCluster, bgnCluster)) return false;
if (!fatPut(*curCluster, bgnCluster)) goto fail;
}
// return first cluster number to caller
*curCluster = bgnCluster;
@@ -111,156 +110,179 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
if (setStart) allocSearchStart_ = bgnCluster + 1;
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
bool SdVolume::cacheFlush() {
if (cacheDirty_) {
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
return false;
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data)) {
goto fail;
}
// mirror FAT tables
if (cacheMirrorBlock_) {
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
return false;
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data)) {
goto fail;
}
cacheMirrorBlock_ = 0;
}
cacheDirty_ = 0;
}
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) {
if (cacheBlockNumber_ != blockNumber) {
if (!cacheFlush()) return false;
if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) return false;
if (!cacheFlush()) goto fail;
if (!sdCard_->readBlock(blockNumber, cacheBuffer_.data)) goto fail;
cacheBlockNumber_ = blockNumber;
}
if (dirty) cacheDirty_ = true;
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
// return the size in bytes of a cluster chain
bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) {
uint32_t s = 0;
do {
if (!fatGet(cluster, &cluster)) return false;
if (!fatGet(cluster, &cluster)) goto fail;
s += 512UL << clusterSizeShift_;
} while (!isEOC(cluster));
*size = s;
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
// Fetch a FAT entry
bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
uint32_t lba;
if (cluster > (clusterCount_ + 1)) return false;
if (cluster > (clusterCount_ + 1)) goto fail;
if (FAT12_SUPPORT && fatType_ == 12) {
uint16_t index = cluster;
index += index >> 1;
lba = fatStartBlock_ + (index >> 9);
if (!cacheRawBlock(lba, CACHE_FOR_READ)) return false;
index &= 0x1FF;
if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail;
index &= 0X1FF;
uint16_t tmp = cacheBuffer_.data[index];
index++;
if (index == 512) {
if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) return false;
if (!cacheRawBlock(lba + 1, CACHE_FOR_READ)) goto fail;
index = 0;
}
tmp |= cacheBuffer_.data[index] << 8;
*value = cluster & 1 ? tmp >> 4 : tmp & 0xFFF;
*value = cluster & 1 ? tmp >> 4 : tmp & 0XFFF;
return true;
}
if (fatType_ == 16)
if (fatType_ == 16) {
lba = fatStartBlock_ + (cluster >> 8);
else if (fatType_ == 32)
}
else if (fatType_ == 32) {
lba = fatStartBlock_ + (cluster >> 7);
else
return false;
if (lba != cacheBlockNumber_ && !cacheRawBlock(lba, CACHE_FOR_READ))
return false;
*value = (fatType_ == 16) ? cacheBuffer_.fat16[cluster & 0xFF] : (cacheBuffer_.fat32[cluster & 0x7F] & FAT32MASK);
}
else {
goto fail;
}
if (lba != cacheBlockNumber_) {
if (!cacheRawBlock(lba, CACHE_FOR_READ)) goto fail;
}
if (fatType_ == 16) {
*value = cacheBuffer_.fat16[cluster & 0XFF];
}
else {
*value = cacheBuffer_.fat32[cluster & 0X7F] & FAT32MASK;
}
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
// Store a FAT entry
bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
uint32_t lba;
// error if reserved cluster
if (cluster < 2) return false;
if (cluster < 2) goto fail;
// error if not in FAT
if (cluster > (clusterCount_ + 1)) return false;
if (cluster > (clusterCount_ + 1)) goto fail;
if (FAT12_SUPPORT && fatType_ == 12) {
uint16_t index = cluster;
index += index >> 1;
lba = fatStartBlock_ + (index >> 9);
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) return false;
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
// mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
index &= 0x1FF;
index &= 0X1FF;
uint8_t tmp = value;
if (cluster & 1) {
tmp = (cacheBuffer_.data[index] & 0xF) | tmp << 4;
tmp = (cacheBuffer_.data[index] & 0XF) | tmp << 4;
}
cacheBuffer_.data[index] = tmp;
index++;
if (index == 512) {
lba++;
index = 0;
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) return false;
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
// mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
}
tmp = value >> 4;
if (!(cluster & 1)) {
tmp = ((cacheBuffer_.data[index] & 0xF0)) | tmp >> 4;
tmp = ((cacheBuffer_.data[index] & 0XF0)) | tmp >> 4;
}
cacheBuffer_.data[index] = tmp;
return true;
}
if (fatType_ == 16)
if (fatType_ == 16) {
lba = fatStartBlock_ + (cluster >> 8);
else if (fatType_ == 32)
}
else if (fatType_ == 32) {
lba = fatStartBlock_ + (cluster >> 7);
else
return false;
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) return false;
}
else {
goto fail;
}
if (!cacheRawBlock(lba, CACHE_FOR_WRITE)) goto fail;
// store entry
if (fatType_ == 16)
cacheBuffer_.fat16[cluster & 0xFF] = value;
else
cacheBuffer_.fat32[cluster & 0x7F] = value;
if (fatType_ == 16) {
cacheBuffer_.fat16[cluster & 0XFF] = value;
}
else {
cacheBuffer_.fat32[cluster & 0X7F] = value;
}
// mirror second FAT
if (fatCount_ > 1) cacheMirrorBlock_ = lba + blocksPerFat_;
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
// free a cluster chain
bool SdVolume::freeChain(uint32_t cluster) {
uint32_t next;
// clear free cluster location
allocSearchStart_ = 2;
do {
uint32_t next;
if (!fatGet(cluster, &next)) return false;
if (!fatGet(cluster, &next)) goto fail;
// free cluster
if (!fatPut(cluster, 0)) return false;
if (!fatPut(cluster, 0)) goto fail;
cluster = next;
} while (!isEOC(cluster));
return true;
fail:
return false;
}
//------------------------------------------------------------------------------
/** Volume free space in clusters.
*
* \return Count of free clusters for success or -1 if an error occurs.
@@ -270,28 +292,34 @@ int32_t SdVolume::freeClusterCount() {
uint16_t n;
uint32_t todo = clusterCount_ + 2;
if (fatType_ == 16)
if (fatType_ == 16) {
n = 256;
else if (fatType_ == 32)
}
else if (fatType_ == 32) {
n = 128;
else // put FAT12 here
}
else {
// put FAT12 here
return -1;
}
for (uint32_t lba = fatStartBlock_; todo; todo -= n, lba++) {
if (!cacheRawBlock(lba, CACHE_FOR_READ)) return -1;
NOMORE(n, todo);
if (fatType_ == 16) {
for (uint16_t i = 0; i < n; i++)
for (uint16_t i = 0; i < n; i++) {
if (cacheBuffer_.fat16[i] == 0) free++;
}
}
else {
for (uint16_t i = 0; i < n; i++)
for (uint16_t i = 0; i < n; i++) {
if (cacheBuffer_.fat32[i] == 0) free++;
}
}
}
return free;
}
//------------------------------------------------------------------------------
/** Initialize a FAT volume.
*
* \param[in] dev The SD card where the volume is located.
@@ -301,12 +329,14 @@ int32_t SdVolume::freeClusterCount() {
* a MBR, Master Boot Record, or zero if the device is formatted as
* a super floppy with the FAT boot sector in block zero.
*
* \return true for success, false for failure.
* Reasons for failure include not finding a valid partition, not finding a valid
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure. Reasons for
* failure include not finding a valid partition, not finding a valid
* FAT file system in the specified partition or an I/O error.
*/
bool SdVolume::init(Sd2Card* dev, uint8_t part) {
uint32_t totalBlocks, volumeStartBlock = 0;
uint32_t totalBlocks;
uint32_t volumeStartBlock = 0;
fat32_boot_t* fbs;
sdCard_ = dev;
@@ -314,26 +344,30 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
allocSearchStart_ = 2;
cacheDirty_ = 0; // cacheFlush() will write block if true
cacheMirrorBlock_ = 0;
cacheBlockNumber_ = 0xFFFFFFFF;
cacheBlockNumber_ = 0XFFFFFFFF;
// if part == 0 assume super floppy with FAT boot sector in block zero
// if part > 0 assume mbr volume with partition table
if (part) {
if (part > 4) return false;
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
if (part > 4)goto fail;
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail;
part_t* p = &cacheBuffer_.mbr.part[part - 1];
if ((p->boot & 0x7F) != 0 || p->totalSectors < 100 || p->firstSector == 0)
return false; // not a valid partition
if ((p->boot & 0X7F) != 0 ||
p->totalSectors < 100 ||
p->firstSector == 0) {
// not a valid partition
goto fail;
}
volumeStartBlock = p->firstSector;
}
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) goto fail;
fbs = &cacheBuffer_.fbs32;
if (fbs->bytesPerSector != 512 ||
fbs->fatCount == 0 ||
fbs->reservedSectorCount == 0 ||
fbs->sectorsPerCluster == 0) {
// not valid FAT volume
return false;
goto fail;
}
fatCount_ = fbs->fatCount;
blocksPerCluster_ = fbs->sectorsPerCluster;
@@ -341,7 +375,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
clusterSizeShift_ = 0;
while (blocksPerCluster_ != _BV(clusterSizeShift_)) {
// error if not power of 2
if (clusterSizeShift_++ > 7) return false;
if (clusterSizeShift_++ > 7) goto fail;
}
blocksPerFat_ = fbs->sectorsPerFat16 ?
fbs->sectorsPerFat16 : fbs->sectorsPerFat32;
@@ -370,15 +404,17 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
// FAT type is determined by cluster count
if (clusterCount_ < 4085) {
fatType_ = 12;
if (!FAT12_SUPPORT) return false;
if (!FAT12_SUPPORT) goto fail;
}
else if (clusterCount_ < 65525)
else if (clusterCount_ < 65525) {
fatType_ = 16;
}
else {
rootDirStart_ = fbs->fat32RootCluster;
fatType_ = 32;
}
return true;
fail:
return false;
}
#endif // SDSUPPORT
#endif

View File

@@ -20,20 +20,20 @@
*
*/
/**
* \file
* \brief SdVolume class
*/
/**
* Arduino SdFat Library
* Copyright (C) 2009 by William Greiman
*
* This file is part of the Arduino Sd2Card Library
*/
#ifndef _SDVOLUME_H_
#define _SDVOLUME_H_
#include "Marlin.h"
#if ENABLED(SDSUPPORT)
#ifndef SdVolume_h
#define SdVolume_h
/**
* \file
* \brief SdVolume class
*/
#include "SdFatConfig.h"
#include "Sd2Card.h"
#include "SdFatStructs.h"
@@ -44,81 +44,89 @@
* \brief Cache for an SD data block
*/
union cache_t {
uint8_t data[512]; // Used to access cached file data blocks.
uint16_t fat16[256]; // Used to access cached FAT16 entries.
uint32_t fat32[128]; // Used to access cached FAT32 entries.
dir_t dir[16]; // Used to access cached directory entries.
mbr_t mbr; // Used to access a cached Master Boot Record.
fat_boot_t fbs; // Used to access to a cached FAT boot sector.
fat32_boot_t fbs32; // Used to access to a cached FAT32 boot sector.
fat32_fsinfo_t fsinfo; // Used to access to a cached FAT32 FSINFO sector.
/** Used to access cached file data blocks. */
uint8_t data[512];
/** Used to access cached FAT16 entries. */
uint16_t fat16[256];
/** Used to access cached FAT32 entries. */
uint32_t fat32[128];
/** Used to access cached directory entries. */
dir_t dir[16];
/** Used to access a cached Master Boot Record. */
mbr_t mbr;
/** Used to access to a cached FAT boot sector. */
fat_boot_t fbs;
/** Used to access to a cached FAT32 boot sector. */
fat32_boot_t fbs32;
/** Used to access to a cached FAT32 FSINFO sector. */
fat32_fsinfo_t fsinfo;
};
//------------------------------------------------------------------------------
/**
* \class SdVolume
* \brief Access FAT16 and FAT32 volumes on SD and SDHC cards.
*/
class SdVolume {
public:
// Create an instance of SdVolume
/** Create an instance of SdVolume */
SdVolume() : fatType_(0) {}
/**
* Clear the cache and returns a pointer to the cache. Used by the WaveRP
/** Clear the cache and returns a pointer to the cache. Used by the WaveRP
* recorder to do raw write to the SD card. Not for normal apps.
* \return A pointer to the cache buffer or zero if an error occurs.
*/
cache_t* cacheClear() {
if (!cacheFlush()) return 0;
cacheBlockNumber_ = 0xFFFFFFFF;
cacheBlockNumber_ = 0XFFFFFFFF;
return &cacheBuffer_;
}
/**
* Initialize a FAT volume. Try partition one first then try super
/** Initialize a FAT volume. Try partition one first then try super
* floppy format.
*
* \param[in] dev The Sd2Card where the volume is located.
*
* \return true for success, false for failure.
* Reasons for failure include not finding a valid partition, not finding
* a valid FAT file system or an I/O error.
* \return The value one, true, is returned for success and
* the value zero, false, is returned for failure. Reasons for
* failure include not finding a valid partition, not finding a valid
* FAT file system or an I/O error.
*/
bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0); }
bool init(Sd2Card* dev) { return init(dev, 1) ? true : init(dev, 0);}
bool init(Sd2Card* dev, uint8_t part);
// inline functions that return volume info
uint8_t blocksPerCluster() const { return blocksPerCluster_; } //> \return The volume's cluster size in blocks.
uint32_t blocksPerFat() const { return blocksPerFat_; } //> \return The number of blocks in one FAT.
uint32_t clusterCount() const { return clusterCount_; } //> \return The total number of clusters in the volume.
uint8_t clusterSizeShift() const { return clusterSizeShift_; } //> \return The shift count required to multiply by blocksPerCluster.
uint32_t dataStartBlock() const { return dataStartBlock_; } //> \return The logical block number for the start of file data.
uint8_t fatCount() const { return fatCount_; } //> \return The number of FAT structures on the volume.
uint32_t fatStartBlock() const { return fatStartBlock_; } //> \return The logical block number for the start of the first FAT.
uint8_t fatType() const { return fatType_; } //> \return The FAT type of the volume. Values are 12, 16 or 32.
/** \return The volume's cluster size in blocks. */
uint8_t blocksPerCluster() const {return blocksPerCluster_;}
/** \return The number of blocks in one FAT. */
uint32_t blocksPerFat() const {return blocksPerFat_;}
/** \return The total number of clusters in the volume. */
uint32_t clusterCount() const {return clusterCount_;}
/** \return The shift count required to multiply by blocksPerCluster. */
uint8_t clusterSizeShift() const {return clusterSizeShift_;}
/** \return The logical block number for the start of file data. */
uint32_t dataStartBlock() const {return dataStartBlock_;}
/** \return The number of FAT structures on the volume. */
uint8_t fatCount() const {return fatCount_;}
/** \return The logical block number for the start of the first FAT. */
uint32_t fatStartBlock() const {return fatStartBlock_;}
/** \return The FAT type of the volume. Values are 12, 16 or 32. */
uint8_t fatType() const {return fatType_;}
int32_t freeClusterCount();
uint32_t rootDirEntryCount() const { return rootDirEntryCount_; } /** \return The number of entries in the root directory for FAT16 volumes. */
/**
* \return The logical block number for the start of the root directory
* on FAT16 volumes or the first cluster number on FAT32 volumes.
*/
uint32_t rootDirStart() const { return rootDirStart_; }
/**
* Sd2Card object for this volume
/** \return The number of entries in the root directory for FAT16 volumes. */
uint32_t rootDirEntryCount() const {return rootDirEntryCount_;}
/** \return The logical block number for the start of the root directory
on FAT16 volumes or the first cluster number on FAT32 volumes. */
uint32_t rootDirStart() const {return rootDirStart_;}
/** Sd2Card object for this volume
* \return pointer to Sd2Card object.
*/
Sd2Card* sdCard() { return sdCard_; }
/**
* Debug access to FAT table
Sd2Card* sdCard() {return sdCard_;}
/** Debug access to FAT table
*
* \param[in] n cluster number.
* \param[out] v value of entry
* \return true for success or false for failure
*/
bool dbgFat(uint32_t n, uint32_t* v) { return fatGet(n, v); }
bool dbgFat(uint32_t n, uint32_t* v) {return fatGet(n, v);}
//------------------------------------------------------------------------------
private:
// Allow SdBaseFile access to SdVolume private data.
friend class SdBaseFile;
@@ -128,20 +136,19 @@ class SdVolume {
// value for dirty argument in cacheRawBlock to indicate write to cache
static bool const CACHE_FOR_WRITE = true;
#if USE_MULTIPLE_CARDS
cache_t cacheBuffer_; // 512 byte cache for device blocks
uint32_t cacheBlockNumber_; // Logical number of block in the cache
Sd2Card* sdCard_; // Sd2Card object for cache
bool cacheDirty_; // cacheFlush() will write block if true
uint32_t cacheMirrorBlock_; // block number for mirror FAT
#else
static cache_t cacheBuffer_; // 512 byte cache for device blocks
static uint32_t cacheBlockNumber_; // Logical number of block in the cache
static Sd2Card* sdCard_; // Sd2Card object for cache
static bool cacheDirty_; // cacheFlush() will write block if true
static uint32_t cacheMirrorBlock_; // block number for mirror FAT
#endif
#if USE_MULTIPLE_CARDS
cache_t cacheBuffer_; // 512 byte cache for device blocks
uint32_t cacheBlockNumber_; // Logical number of block in the cache
Sd2Card* sdCard_; // Sd2Card object for cache
bool cacheDirty_; // cacheFlush() will write block if true
uint32_t cacheMirrorBlock_; // block number for mirror FAT
#else // USE_MULTIPLE_CARDS
static cache_t cacheBuffer_; // 512 byte cache for device blocks
static uint32_t cacheBlockNumber_; // Logical number of block in the cache
static Sd2Card* sdCard_; // Sd2Card object for cache
static bool cacheDirty_; // cacheFlush() will write block if true
static uint32_t cacheMirrorBlock_; // block number for mirror FAT
#endif // USE_MULTIPLE_CARDS
uint32_t allocSearchStart_; // start cluster for alloc search
uint8_t blocksPerCluster_; // cluster size in blocks
uint32_t blocksPerFat_; // FAT size in blocks
@@ -153,59 +160,68 @@ class SdVolume {
uint8_t fatType_; // volume type (12, 16, OR 32)
uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir
uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32
//----------------------------------------------------------------------------
bool allocContiguous(uint32_t count, uint32_t* curCluster);
uint8_t blockOfCluster(uint32_t position) const { return (position >> 9) & (blocksPerCluster_ - 1); }
uint32_t clusterStartBlock(uint32_t cluster) const { return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_); }
uint32_t blockNumber(uint32_t cluster, uint32_t position) const { return clusterStartBlock(cluster) + blockOfCluster(position); }
cache_t* cache() { return &cacheBuffer_; }
uint32_t cacheBlockNumber() const { return cacheBlockNumber_; }
#if USE_MULTIPLE_CARDS
bool cacheFlush();
bool cacheRawBlock(uint32_t blockNumber, bool dirty);
#else
static bool cacheFlush();
static bool cacheRawBlock(uint32_t blockNumber, bool dirty);
#endif
uint8_t blockOfCluster(uint32_t position) const {
return (position >> 9) & (blocksPerCluster_ - 1);
}
uint32_t clusterStartBlock(uint32_t cluster) const {
return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_);
}
uint32_t blockNumber(uint32_t cluster, uint32_t position) const {
return clusterStartBlock(cluster) + blockOfCluster(position);
}
cache_t* cache() {return &cacheBuffer_;}
uint32_t cacheBlockNumber() {return cacheBlockNumber_;}
#if USE_MULTIPLE_CARDS
bool cacheFlush();
bool cacheRawBlock(uint32_t blockNumber, bool dirty);
#else // USE_MULTIPLE_CARDS
static bool cacheFlush();
static bool cacheRawBlock(uint32_t blockNumber, bool dirty);
#endif // USE_MULTIPLE_CARDS
// used by SdBaseFile write to assign cache to SD location
void cacheSetBlockNumber(uint32_t blockNumber, bool dirty) {
cacheDirty_ = dirty;
cacheBlockNumber_ = blockNumber;
}
void cacheSetDirty() { cacheDirty_ |= CACHE_FOR_WRITE; }
void cacheSetDirty() {cacheDirty_ |= CACHE_FOR_WRITE;}
bool chainSize(uint32_t beginCluster, uint32_t* size);
bool fatGet(uint32_t cluster, uint32_t* value);
bool fatPut(uint32_t cluster, uint32_t value);
bool fatPutEOC(uint32_t cluster) { return fatPut(cluster, 0x0FFFFFFF); }
bool fatPutEOC(uint32_t cluster) {
return fatPut(cluster, 0x0FFFFFFF);
}
bool freeChain(uint32_t cluster);
bool isEOC(uint32_t cluster) const {
if (FAT12_SUPPORT && fatType_ == 12) return cluster >= FAT12EOC_MIN;
if (fatType_ == 16) return cluster >= FAT16EOC_MIN;
return cluster >= FAT32EOC_MIN;
}
bool readBlock(uint32_t block, uint8_t* dst) { return sdCard_->readBlock(block, dst); }
bool writeBlock(uint32_t block, const uint8_t* dst) { return sdCard_->writeBlock(block, dst); }
// Deprecated functions
#if ALLOW_DEPRECATED_FUNCTIONS
public:
/**
* \deprecated Use: bool SdVolume::init(Sd2Card* dev);
* \param[in] dev The SD card where the volume is located.
* \return true for success or false for failure.
*/
bool init(Sd2Card& dev) { return init(&dev); }
/**
* \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol);
* \param[in] dev The SD card where the volume is located.
* \param[in] part The partition to be used.
* \return true for success or false for failure.
*/
bool init(Sd2Card& dev, uint8_t part) { return init(&dev, part); }
#endif // ALLOW_DEPRECATED_FUNCTIONS
bool readBlock(uint32_t block, uint8_t* dst) {
return sdCard_->readBlock(block, dst);
}
bool writeBlock(uint32_t block, const uint8_t* dst) {
return sdCard_->writeBlock(block, dst);
}
//------------------------------------------------------------------------------
// Deprecated functions - suppress cpplint warnings with NOLINT comment
#if ALLOW_DEPRECATED_FUNCTIONS && !defined(DOXYGEN)
public:
/** \deprecated Use: bool SdVolume::init(Sd2Card* dev);
* \param[in] dev The SD card where the volume is located.
* \return true for success or false for failure.
*/
bool init(Sd2Card& dev) {return init(&dev);} // NOLINT
/** \deprecated Use: bool SdVolume::init(Sd2Card* dev, uint8_t vol);
* \param[in] dev The SD card where the volume is located.
* \param[in] part The partition to be used.
* \return true for success or false for failure.
*/
bool init(Sd2Card& dev, uint8_t part) { // NOLINT
return init(&dev, part);
}
#endif // ALLOW_DEPRECATED_FUNCTIONS
};
#endif // _SDVOLUME_H_
#endif // SdVolume
#endif

View File

@@ -35,7 +35,7 @@
/**
* Marlin release version identifier
*/
#define SHORT_BUILD_VERSION "1.1.9.1"
#define SHORT_BUILD_VERSION "1.1.0-RC7"
/**
* Verbose version identifier which should contain a reference to the location
@@ -48,7 +48,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
#define STRING_DISTRIBUTION_DATE "2020-06-20"
#define STRING_DISTRIBUTION_DATE "2016-07-31 12:00"
/**
* Required minimum Configuration.h and Configuration_adv.h file versions.
@@ -57,13 +57,11 @@
* but not limited to: ADD, DELETE RENAME OR REPURPOSE any directive/option on
* the configuration files.
*/
#define REQUIRED_CONFIGURATION_H_VERSION 010109
#define REQUIRED_CONFIGURATION_ADV_H_VERSION 010109
#define REQUIRED_CONFIGURATION_H_VERSION 010100
#define REQUIRED_CONFIGURATION_ADV_H_VERSION 010100
/**
* The protocol for communication to the host. Protocol indicates communication
* standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc.
* (Other behaviors are given by the firmware version and capabilities report.)
* @todo: Missing documentation block
*/
#define PROTOCOL_VERSION "1.0"

View File

@@ -1,38 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016, 2017 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _BITMAP_FLAGS_H_
#define _BITMAP_FLAGS_H_
#include "macros.h"
/**
* These support functions allow the use of large bit arrays of flags that take very
* little RAM. Currently they are limited to being 16x16 in size. Changing the declaration
* to unsigned long will allow us to go to 32x32 if higher resolution meshes are needed
* in the future.
*/
FORCE_INLINE void bitmap_clear(uint16_t bits[16], const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
FORCE_INLINE void bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
FORCE_INLINE bool is_bitmap_set(uint16_t bits[16], const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
#endif // _BITMAP_FLAGS_H_

View File

@@ -21,26 +21,26 @@
*/
/**
* blinkm.cpp - Control a BlinkM over i2c
* blinkm.cpp - Library for controlling a BlinkM over i2c
* Created by Tim Koster, August 21 2013.
*/
#include "MarlinConfig.h"
#include "Marlin.h"
#if ENABLED(BLINKM)
#include "blinkm.h"
#include "leds.h"
#include <Wire.h>
void blinkm_set_led_color(const LEDColor &color) {
void SendColors(byte red, byte grn, byte blu) {
Wire.begin();
Wire.beginTransmission(0x09);
Wire.write('o'); //to disable ongoing script, only needs to be used once
Wire.write('n');
Wire.write(color.r);
Wire.write(color.g);
Wire.write(color.b);
Wire.write(red);
Wire.write(grn);
Wire.write(blu);
Wire.endTransmission();
}
#endif // BLINKM
#endif //BLINKM

View File

@@ -21,15 +21,11 @@
*/
/**
* blinkm.h - Control a BlinkM over i2c
* blinkm.h - Library for controlling a BlinkM over i2c
* Created by Tim Koster, August 21 2013.
*/
#ifndef _BLINKM_H_
#define _BLINKM_H_
#include "Arduino.h"
#include "Wire.h"
struct LEDColor;
typedef LEDColor LEDColor;
void blinkm_set_led_color(const LEDColor &color);
#endif // _BLINKM_H_
void SendColors(byte red, byte grn, byte blu);

View File

@@ -25,138 +25,76 @@
#define BOARD_UNKNOWN -1
//
// RAMPS 1.3 / 1.4 - ATmega1280, ATmega2560
//
#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics"
#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2
#define BOARD_GEN7_13 12 // Gen7 v1.3
#define BOARD_GEN7_14 13 // Gen7 v1.4
#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11
#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12
#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0
#define BOARD_SETHI 20 // Sethi 3D_1
#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2
#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan)
#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like)
#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard
#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2
#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan)
#define BOARD_GEN6 5 // Gen6
#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe
#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2
#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above
#define BOARD_MELZI 63 // Melzi
#define BOARD_STB_11 64 // STB V1.1
#define BOARD_AZTEEG_X1 65 // Azteeg X1
#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version)
#define BOARD_AZTEEG_X3 67 // Azteeg X3
#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro
#define BOARD_ULTIMAKER 7 // Ultimaker
#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare)
#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20)
#define BOARD_3DRAG 77 // 3Drag Controller
#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller)
#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller)
#define BOARD_TEENSYLU 8 // Teensylu
#define BOARD_RUMBA 80 // Rumba
#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286)
#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286)
#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646)
#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286)
#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: DEFINES=AT90USBxx_TEENSYPP_ASSIGNMENTS HARDWARE_MOTHERBOARD=84 make
#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286)
#define BOARD_GEN3_PLUS 9 // Gen3+
#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics
#define BOARD_MEGATRONICS 70 // Megatronics
#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0
#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1
#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0
#define BOARD_OMCA_A 90 // Alpha OMCA board
#define BOARD_OMCA 91 // Final OMCA board
#define BOARD_RAMBO 301 // Rambo
#define BOARD_MINIRAMBO 302 // Mini-Rambo
#define BOARD_AJ4P 303 // AJ4P
#define BOARD_MEGACONTROLLER 310 // Mega controller
#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3)
#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board
#define BOARD_LEAPFROG 999 // Leapfrog
#define BOARD_MKS_BASE 40 // MKS BASE 1.0
#define BOARD_MKS_13 47 // MKS v1.3 or 1.4 (maybe higher)
#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board
#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers
#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers
#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D
#define BOARD_RAMPS_OLD 3 // MEGA/RAMPS up to 1.2
#define BOARD_99 99 // This is in pins.h but...?
#define BOARD_RAMPS_13_EFB 33 // RAMPS 1.3 (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_13_EEB 34 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_13_EFF 35 // RAMPS 1.3 (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_13_EEF 36 // RAMPS 1.3 (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_13_SF 38 // RAMPS 1.3 (Power outputs: Spindle, Controller Fan)
#define MB(board) (MOTHERBOARD==BOARD_##board)
#define BOARD_RAMPS_14_EFB 43 // RAMPS 1.4 (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_14_EEB 44 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_14_EFF 45 // RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_14_EEF 46 // RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_14_SF 48 // RAMPS 1.4 (Power outputs: Spindle, Controller Fan)
#define BOARD_RAMPS_PLUS_EFB 143 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan, Bed)
#define BOARD_RAMPS_PLUS_EEB 144 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Bed)
#define BOARD_RAMPS_PLUS_EFF 145 // RAMPS Plus 3DYMY (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_PLUS_EEF 146 // RAMPS Plus 3DYMY (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_PLUS_SF 148 // RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan)
//
// RAMPS Derivatives - ATmega1280, ATmega2560
//
#define BOARD_3DRAG 77 // 3Drag Controller
#define BOARD_K8200 78 // Velleman K8200 Controller (derived from 3Drag Controller)
#define BOARD_K8400 79 // Velleman K8400 Controller (derived from 3Drag Controller)
#define BOARD_BAM_DICE 401 // 2PrintBeta BAM&DICE with STK drivers
#define BOARD_BAM_DICE_DUE 402 // 2PrintBeta BAM&DICE Due with STK drivers
#define BOARD_MKS_BASE 40 // MKS BASE v1.0
#define BOARD_MKS_BASE_15 405 // MKS v1.5 with Allegro A4982 stepper drivers
#define BOARD_MKS_BASE_HEROIC 41 // MKS BASE 1.0 with Heroic HR4982 stepper drivers
#define BOARD_MKS_GEN_13 47 // MKS GEN v1.3 or 1.4
#define BOARD_MKS_GEN_L 53 // MKS GEN L
#define BOARD_MKS_GEN_L_V2 54 // MKS GEN L V2
#define BOARD_ZRIB_V20 504 // zrib V2.0 control board (Chinese knock off RAMPS replica)
#define BOARD_FELIX2 37 // Felix 2.0+ Electronics Board (RAMPS like)
#define BOARD_RIGIDBOARD 42 // Invent-A-Part RigidBoard
#define BOARD_RIGIDBOARD_V2 52 // Invent-A-Part RigidBoard V2
#define BOARD_SAINSMART_2IN1 49 // Sainsmart 2-in-1 board
#define BOARD_ULTIMAKER 7 // Ultimaker
#define BOARD_ULTIMAKER_OLD 71 // Ultimaker (Older electronics. Pre 1.5.4. This is rare)
#define BOARD_AZTEEG_X3 67 // Azteeg X3
#define BOARD_AZTEEG_X3_PRO 68 // Azteeg X3 Pro
#define BOARD_ULTIMAIN_2 72 // Ultimainboard 2.x (Uses TEMP_SENSOR 20)
#define BOARD_RUMBA 80 // Rumba
#define BOARD_BQ_ZUM_MEGA_3D 503 // bq ZUM Mega 3D
#define BOARD_MAKEBOARD_MINI 431 // MakeBoard Mini v2.1.2 is a control board sold by MicroMake
#define BOARD_TRIGORILLA_13 343 // TriGorilla Anycubic version 1.3 based on RAMPS EFB
#define BOARD_TRIGORILLA_14 443 // TriGorilla Anycubic version 1.4 based on RAMPS EFB
#define BOARD_RAMPS_ENDER_4 243 // Creality: Ender-4, CR-8
//
// Other ATmega1280, ATmega2560
//
#define BOARD_CNCONTROLS_11 111 // Cartesio CN Controls V11
#define BOARD_CNCONTROLS_12 112 // Cartesio CN Controls V12
#define BOARD_CHEAPTRONIC 2 // Cheaptronic v1.0
#define BOARD_CHEAPTRONIC_V2 21 // Cheaptronic v2.0
#define BOARD_MIGHTYBOARD_REVE 200 // Makerbot Mightyboard Revision E
#define BOARD_MEGATRONICS 70 // Megatronics
#define BOARD_MEGATRONICS_2 701 // Megatronics v2.0
#define BOARD_MEGATRONICS_3 703 // Megatronics v3.0
#define BOARD_MEGATRONICS_31 704 // Megatronics v3.1
#define BOARD_RAMBO 301 // Rambo
#define BOARD_MINIRAMBO 302 // Mini-Rambo
#define BOARD_MINIRAMBO_10A 303 // Mini-Rambo 1.0a
#define BOARD_EINSY_RAMBO 304 // Einsy Rambo
#define BOARD_EINSY_RETRO 305 // Einsy Retro
#define BOARD_ELEFU_3 21 // Elefu Ra Board (v3)
#define BOARD_LEAPFROG 999 // Leapfrog
#define BOARD_MEGACONTROLLER 310 // Mega controller
#define BOARD_SCOOVO_X9H 321 // abee Scoovo X9H
#define BOARD_GT2560_REV_A 74 // Geeetech GT2560 Rev. A
#define BOARD_GT2560_REV_A_PLUS 75 // Geeetech GT2560 Rev. A+ (with auto level probe)
//
// ATmega1281, ATmega2561
//
#define BOARD_MINITRONICS 702 // Minitronics v1.0/1.1
#define BOARD_SILVER_GATE 25 // Silvergate v1.0
//
// Sanguinololu and Derivatives - ATmega644P, ATmega1284P
//
#define BOARD_SANGUINOLOLU_11 6 // Sanguinololu < 1.2
#define BOARD_SANGUINOLOLU_12 62 // Sanguinololu 1.2 and above
#define BOARD_MELZI 63 // Melzi
#define BOARD_MELZI_MAKR3D 66 // Melzi with ATmega1284 (MaKr3d version)
#define BOARD_MELZI_CREALITY 89 // Melzi Creality3D board (for CR-10 etc)
#define BOARD_MELZI_MALYAN 92 // Melzi Malyan M150 board
#define BOARD_MELZI_TRONXY 505 // Tronxy X5S
#define BOARD_STB_11 64 // STB V1.1
#define BOARD_AZTEEG_X1 65 // Azteeg X1
#define BOARD_ANET_10 69 // Anet 1.0 (Melzi clone)
//
// Other ATmega644P, ATmega644, ATmega1284P
//
#define BOARD_GEN3_MONOLITHIC 22 // Gen3 Monolithic Electronics
#define BOARD_GEN3_PLUS 9 // Gen3+
#define BOARD_GEN6 5 // Gen6
#define BOARD_GEN6_DELUXE 51 // Gen6 deluxe
#define BOARD_GEN7_CUSTOM 10 // Gen7 custom (Alfons3 Version) "https://github.com/Alfons3/Generation_7_Electronics"
#define BOARD_GEN7_12 11 // Gen7 v1.1, v1.2
#define BOARD_GEN7_13 12 // Gen7 v1.3
#define BOARD_GEN7_14 13 // Gen7 v1.4
#define BOARD_OMCA_A 90 // Alpha OMCA board
#define BOARD_OMCA 91 // Final OMCA board
#define BOARD_SETHI 20 // Sethi 3D_1
//
// Teensyduino - AT90USB1286, AT90USB1286P
//
#define BOARD_TEENSYLU 8 // Teensylu
#define BOARD_PRINTRBOARD 81 // Printrboard (AT90USB1286)
#define BOARD_PRINTRBOARD_REVF 811 // Printrboard Revision F (AT90USB1286)
#define BOARD_BRAINWAVE 82 // Brainwave (AT90USB646)
#define BOARD_BRAINWAVE_PRO 85 // Brainwave Pro (AT90USB1286)
#define BOARD_SAV_MKI 83 // SAV Mk-I (AT90USB1286)
#define BOARD_TEENSY2 84 // Teensy++2.0 (AT90USB1286) - CLI compile: HARDWARE_MOTHERBOARD=84 make
#define BOARD_5DPRINT 88 // 5DPrint D8 Driver Board
#define MB(board) (defined(BOARD_##board) && MOTHERBOARD==BOARD_##board)
#endif // __BOARDS_H
#endif //__BOARDS_H

View File

@@ -104,13 +104,12 @@ class Buzzer {
* @param duration Duration of the tone in milliseconds
* @param frequency Frequency of the tone in hertz
*/
void tone(const uint16_t &duration, const uint16_t &frequency=0) {
void tone(uint16_t const &duration, uint16_t const &frequency = 0) {
while (buffer.isFull()) {
this->tick();
thermalManager.manage_heater();
}
tone_t tone = { duration, frequency };
this->buffer.enqueue(tone);
this->buffer.enqueue((tone_t) { duration, frequency });
}
/**

File diff suppressed because it is too large Load Diff

View File

@@ -20,44 +20,41 @@
*
*/
#ifndef _CARDREADER_H_
#define _CARDREADER_H_
#ifndef CARDREADER_H
#define CARDREADER_H
#include "MarlinConfig.h"
#if ENABLED(SDSUPPORT)
#define SD_RESORT ENABLED(SDCARD_SORT_ALPHA) && ENABLED(SDSORT_DYNAMIC_RAM)
#define MAX_DIR_DEPTH 10 // Maximum folder depth
#include "SdFile.h"
#include "types.h"
#include "enum.h"
class CardReader {
public:
CardReader();
void initsd();
void write_command(char *buf);
//files auto[0-9].g on the sd card are performed in a row
//this is to delay autostart and hence the initialisaiton of the sd card to some seconds after the normal init, so the device is available quick after a reset
void beginautostart();
void checkautostart();
void openFile(char * const path, const bool read, const bool subcall=false);
void openLogFile(char * const path);
void removeFile(const char * const name);
void closefile(const bool store_location=false);
void checkautostart(bool x);
void openFile(char* name, bool read, bool push_current=false);
void openLogFile(char* name);
void removeFile(char* name);
void closefile(bool store_location=false);
void release();
void openAndPrintFile(const char *name);
void startFileprint();
void stopSDPrint(
#if SD_RESORT
const bool re_sort=false
#endif
);
void pauseSDPrint();
void stopSDPrint();
void getStatus();
void printingHasFinished();
void printFilename();
#if ENABLED(LONG_FILENAME_HOST_SUPPORT)
void printLongPath(char *path);
@@ -70,161 +67,63 @@ public:
void ls();
void chdir(const char *relpath);
int8_t updir();
void updir();
void setroot();
const char* diveToFile(SdFile*& curDir, const char * const path, const bool echo);
uint16_t get_num_Files();
#if ENABLED(SDCARD_SORT_ALPHA)
void presort();
void getfilename_sorted(const uint16_t nr);
#if ENABLED(SDSORT_GCODE)
FORCE_INLINE void setSortOn(bool b) { sort_alpha = b; presort(); }
FORCE_INLINE void setSortFolders(int i) { sort_folders = i; presort(); }
//FORCE_INLINE void setSortReverse(bool b) { sort_reverse = b; }
#endif
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
void openJobRecoveryFile(const bool read);
void closeJobRecoveryFile();
bool jobRecoverFileExists();
int16_t saveJobRecoveryInfo();
int16_t loadJobRecoveryInfo();
void removeJobRecoveryFile();
#endif
FORCE_INLINE void pauseSDPrint() { sdprinting = false; }
FORCE_INLINE bool isFileOpen() { return file.isOpen(); }
FORCE_INLINE bool eof() { return sdpos >= filesize; }
FORCE_INLINE int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); }
FORCE_INLINE void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); }
FORCE_INLINE uint32_t getIndex() { return sdpos; }
FORCE_INLINE void setIndex(long index) { sdpos = index; file.seekSet(index); }
FORCE_INLINE uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
FORCE_INLINE char* getWorkDirName() { workDir.getFilename(filename); return filename; }
#if ENABLED(AUTO_REPORT_SD_STATUS)
void auto_report_sd_status(void);
FORCE_INLINE void set_auto_report_interval(uint8_t v) {
NOMORE(v, 60);
auto_report_sd_interval = v;
next_sd_report_ms = millis() + 1000UL * v;
}
#endif
FORCE_INLINE char* longest_filename() { return longFilename[0] ? longFilename : filename; }
public:
bool saving, logging, sdprinting, cardOK, filenameIsDir, abort_sd_printing;
bool saving, logging, sdprinting, cardOK, filenameIsDir;
char filename[FILENAME_LENGTH], longFilename[LONG_FILENAME_LENGTH];
int8_t autostart_index;
int autostart_index;
private:
SdFile root, workDir, workDirParents[MAX_DIR_DEPTH];
SdFile root, *curDir, workDir, workDirParents[MAX_DIR_DEPTH];
uint8_t workDirDepth;
// Sort files and folders alphabetically.
#if ENABLED(SDCARD_SORT_ALPHA)
uint16_t sort_count; // Count of sorted items in the current directory
#if ENABLED(SDSORT_GCODE)
bool sort_alpha; // Flag to enable / disable the feature
int sort_folders; // Flag to enable / disable folder sorting
//bool sort_reverse; // Flag to enable / disable reverse sorting
#endif
// By default the sort index is static
#if ENABLED(SDSORT_DYNAMIC_RAM)
uint8_t *sort_order;
#else
uint8_t sort_order[SDSORT_LIMIT];
#endif
#if ENABLED(SDSORT_USES_RAM) && ENABLED(SDSORT_CACHE_NAMES) && DISABLED(SDSORT_DYNAMIC_RAM)
#define SORTED_LONGNAME_MAXLEN ((SDSORT_CACHE_VFATS) * (FILENAME_LENGTH) + 1)
#else
#define SORTED_LONGNAME_MAXLEN LONG_FILENAME_LENGTH
#endif
// Cache filenames to speed up SD menus.
#if ENABLED(SDSORT_USES_RAM)
// If using dynamic ram for names, allocate on the heap.
#if ENABLED(SDSORT_CACHE_NAMES)
#if ENABLED(SDSORT_DYNAMIC_RAM)
char **sortshort, **sortnames;
#else
char sortshort[SDSORT_LIMIT][FILENAME_LENGTH];
char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN];
#endif
#elif DISABLED(SDSORT_USES_STACK)
char sortnames[SDSORT_LIMIT][SORTED_LONGNAME_MAXLEN];
#endif
// Folder sorting uses an isDir array when caching items.
#if HAS_FOLDER_SORTING
#if ENABLED(SDSORT_DYNAMIC_RAM)
uint8_t *isDir;
#elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
uint8_t isDir[(SDSORT_LIMIT+7)>>3];
#endif
#endif
#endif // SDSORT_USES_RAM
#endif // SDCARD_SORT_ALPHA
Sd2Card sd2card;
Sd2Card card;
SdVolume volume;
SdFile file;
#if ENABLED(POWER_LOSS_RECOVERY)
SdFile jobRecoveryFile;
#endif
#define SD_PROCEDURE_DEPTH 1
#define MAXPATHNAMELENGTH (FILENAME_LENGTH*MAX_DIR_DEPTH + MAX_DIR_DEPTH + 1)
uint8_t file_subcall_ctr;
uint32_t filespos[SD_PROCEDURE_DEPTH];
char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
uint32_t filesize, sdpos;
uint32_t filesize;
uint32_t sdpos;
millis_t next_autostart_ms;
bool autostart_stilltocheck; //the sd start is delayed, because otherwise the serial cannot answer fast enought to make contact with the hostsoftware.
LsAction lsAction; //stored for recursion.
uint16_t nrFiles; //counter for the files in the current directory and recycled as position counter for getting the nrFiles'th name in the directory.
char* diveDirName;
void lsDive(const char *prepend, SdFile parent, const char * const match=NULL);
#if ENABLED(SDCARD_SORT_ALPHA)
void flush_presort();
#endif
#if ENABLED(AUTO_REPORT_SD_STATUS)
static uint8_t auto_report_sd_interval;
static millis_t next_sd_report_ms;
#endif
};
#if PIN_EXISTS(SD_DETECT)
#if ENABLED(SD_DETECT_INVERTED)
#define IS_SD_INSERTED() READ(SD_DETECT_PIN)
#else
#define IS_SD_INSERTED() !READ(SD_DETECT_PIN)
#endif
#else
// No card detect line? Assume the card is inserted.
#define IS_SD_INSERTED() true
#endif
extern CardReader card;
#endif // SDSUPPORT
#define IS_SD_PRINTING (card.sdprinting)
#if ENABLED(SDSUPPORT)
#define IS_SD_PRINTING() card.sdprinting
#define IS_SD_FILE_OPEN() card.isFileOpen()
#if PIN_EXISTS(SD_DETECT)
#if ENABLED(SD_DETECT_INVERTED)
#define IS_SD_INSERTED (READ(SD_DETECT_PIN) != 0)
#else
#define IS_SD_INSERTED (READ(SD_DETECT_PIN) == 0)
#endif
#else
#define IS_SD_PRINTING() false
#define IS_SD_FILE_OPEN() false
//No card detect line? Assume the card is inserted.
#define IS_SD_INSERTED true
#endif
#endif // _CARDREADER_H_
#else
#define IS_SD_PRINTING (false)
#endif //SDSUPPORT
#endif //__CARDREADER_H

File diff suppressed because it is too large Load Diff

View File

@@ -25,77 +25,20 @@
#include "MarlinConfig.h"
class MarlinSettings {
public:
MarlinSettings() { }
void Config_ResetDefault();
static uint16_t datasize();
#if DISABLED(DISABLE_M503)
void Config_PrintSettings(bool forReplay=false);
#else
FORCE_INLINE void Config_PrintSettings(bool forReplay=false) {}
#endif
static void reset();
static bool save(); // Return 'true' if data was saved
#if ENABLED(EEPROM_SETTINGS)
void Config_StoreSettings();
void Config_RetrieveSettings();
#else
FORCE_INLINE void Config_StoreSettings() {}
FORCE_INLINE void Config_RetrieveSettings() { Config_ResetDefault(); Config_PrintSettings(); }
#endif
FORCE_INLINE static bool init_eeprom() {
reset();
#if ENABLED(EEPROM_SETTINGS)
const bool success = save();
#if ENABLED(EEPROM_CHITCHAT)
if (success) report();
#endif
return success;
#else
return true;
#endif
}
#if ENABLED(EEPROM_SETTINGS)
static bool load(); // Return 'true' if data was loaded ok
static bool validate(); // Return 'true' if EEPROM data is ok
#if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
// That can store is enabled
static uint16_t meshes_start_index();
FORCE_INLINE static uint16_t meshes_end_index() { return meshes_end; }
static uint16_t calc_num_meshes();
static int mesh_slot_offset(const int8_t slot);
static void store_mesh(const int8_t slot);
static void load_mesh(const int8_t slot, void * const into=NULL);
//static void delete_mesh(); // necessary if we have a MAT
//static void defrag_meshes(); // "
#endif
#else
FORCE_INLINE
static bool load() { reset(); report(); return true; }
#endif
#if DISABLED(DISABLE_M503)
static void report(const bool forReplay=false);
#else
FORCE_INLINE
static void report(const bool forReplay=false) { UNUSED(forReplay); }
#endif
private:
static void postprocess();
#if ENABLED(EEPROM_SETTINGS)
static bool eeprom_error, validating;
#if ENABLED(AUTO_BED_LEVELING_UBL) // Eventually make these available if any leveling system
// That can store is enabled
static constexpr uint16_t meshes_end = E2END - 128; // 128 is a placeholder for the size of the MAT; the MAT will always
// live at the very end of the eeprom
#endif
static bool _load();
static void write_data(int &pos, const uint8_t *value, uint16_t size, uint16_t *crc);
static void read_data(int &pos, uint8_t *value, uint16_t size, uint16_t *crc, const bool force=false);
static bool size_error(const uint16_t size);
#endif
};
extern MarlinSettings settings;
#endif // CONFIGURATION_STORE_H
#endif //CONFIGURATION_STORE_H

View File

@@ -30,14 +30,11 @@
* http://arduino.cc/forum/index.php/topic,51842.0.html
*/
#include "MarlinConfig.h"
#include "dac_mcp4728.h"
#if ENABLED(DAC_STEPPER_CURRENT)
#include "dac_mcp4728.h"
#include "enum.h"
uint16_t mcp4728_values[XYZE];
uint16_t mcp4728_values[4];
/**
* Begin I2C, get current values (input register and eeprom) of mcp4728
@@ -45,13 +42,16 @@ uint16_t mcp4728_values[XYZE];
void mcp4728_init() {
Wire.begin();
Wire.requestFrom(int(DAC_DEV_ADDRESS), 24);
while (Wire.available()) {
char deviceID = Wire.read(),
hiByte = Wire.read(),
loByte = Wire.read();
while(Wire.available()) {
int deviceID = Wire.read();
int hiByte = Wire.read();
int loByte = Wire.read();
if (!(deviceID & 0x08))
mcp4728_values[(deviceID & 0x30) >> 4] = word((hiByte & 0x0F), loByte);
int isEEPROM = (deviceID & 0B00001000) >> 3;
int channel = (deviceID & 0B00110000) >> 4;
if (isEEPROM != 1) {
mcp4728_values[channel] = word((hiByte & 0B00001111), loByte);
}
}
}
@@ -63,7 +63,6 @@ uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value) {
mcp4728_values[channel] = value;
return mcp4728_fastWrite();
}
/**
* Write all input resistor values to EEPROM using SequencialWrite method.
* This will update both input register and EEPROM value
@@ -72,9 +71,9 @@ uint8_t mcp4728_analogWrite(uint8_t channel, uint16_t value) {
uint8_t mcp4728_eepromWrite() {
Wire.beginTransmission(DAC_DEV_ADDRESS);
Wire.write(SEQWRITE);
LOOP_XYZE(i) {
Wire.write(DAC_STEPPER_VREF << 7 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[i]));
Wire.write(lowByte(mcp4728_values[i]));
for (uint8_t channel=0; channel <= 3; channel++) {
Wire.write(DAC_STEPPER_VREF << 7 | 0 << 5 | DAC_STEPPER_GAIN << 4 | highByte(mcp4728_values[channel]));
Wire.write(lowByte(mcp4728_values[channel]));
}
return Wire.endTransmission();
}
@@ -84,7 +83,7 @@ uint8_t mcp4728_eepromWrite() {
*/
uint8_t mcp4728_setVref_all(uint8_t value) {
Wire.beginTransmission(DAC_DEV_ADDRESS);
Wire.write(VREFWRITE | (value ? 0x0F : 0x00));
Wire.write(VREFWRITE | value << 3 | value << 2 | value << 1 | value);
return Wire.endTransmission();
}
/**
@@ -92,12 +91,12 @@ uint8_t mcp4728_setVref_all(uint8_t value) {
*/
uint8_t mcp4728_setGain_all(uint8_t value) {
Wire.beginTransmission(DAC_DEV_ADDRESS);
Wire.write(GAINWRITE | (value ? 0x0F : 0x00));
Wire.write(GAINWRITE | value << 3 | value << 2 | value << 1 | value);
return Wire.endTransmission();
}
/**
* Return Input Register value
* Return Input Regiter value
*/
uint16_t mcp4728_getValue(uint8_t channel) { return mcp4728_values[channel]; }
@@ -106,27 +105,13 @@ uint16_t mcp4728_getValue(uint8_t channel) { return mcp4728_values[channel]; }
* Return Vout
*
uint16_t mcp4728_getVout(uint8_t channel) {
uint32_t vref = 2048,
vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096;
uint32_t vref = 2048;
uint32_t vOut = (vref * mcp4728_values[channel] * (_DAC_STEPPER_GAIN + 1)) / 4096;
if (vOut > defaultVDD) vOut = defaultVDD;
return vOut;
}
*/
/**
* Returns DAC values as a 0-100 percentage of drive strength
*/
uint8_t mcp4728_getDrvPct(uint8_t channel) { return uint8_t(100.0 * mcp4728_values[channel] / (DAC_STEPPER_MAX) + 0.5); }
/**
* Receives all Drive strengths as 0-100 percent values, updates
* DAC Values array and calls fastwrite to update the DAC.
*/
void mcp4728_setDrvPct(uint8_t pct[XYZE]) {
LOOP_XYZE(i) mcp4728_values[i] = 0.01 * pct[i] * (DAC_STEPPER_MAX);
mcp4728_fastWrite();
}
/**
* FastWrite input register values - All DAC ouput update. refer to DATASHEET 5.6.1
* DAC Input and PowerDown bits update.
@@ -134,9 +119,9 @@ void mcp4728_setDrvPct(uint8_t pct[XYZE]) {
*/
uint8_t mcp4728_fastWrite() {
Wire.beginTransmission(DAC_DEV_ADDRESS);
LOOP_XYZE(i) {
Wire.write(highByte(mcp4728_values[i]));
Wire.write(lowByte(mcp4728_values[i]));
for (uint8_t channel=0; channel <= 3; channel++) {
Wire.write(highByte(mcp4728_values[channel]));
Wire.write(lowByte(mcp4728_values[channel]));
}
return Wire.endTransmission();
}

View File

@@ -24,15 +24,15 @@
* Arduino library for MicroChip MCP4728 I2C D/A converter.
*/
#ifndef DAC_MCP4728_H
#define DAC_MCP4728_H
#ifndef mcp4728_h
#define mcp4728_h
#include "MarlinConfig.h"
#if ENABLED(DAC_STEPPER_CURRENT)
#include "Wire.h"
#define defaultVDD DAC_STEPPER_MAX //was 5000 but differs with internal Vref
#define defaultVDD 5000
#define BASE_ADDR 0x60
#define RESET 0B00000110
#define WAKE 0B00001001
@@ -59,8 +59,7 @@ uint8_t mcp4728_setGain_all(uint8_t value);
uint16_t mcp4728_getValue(uint8_t channel);
uint8_t mcp4728_fastWrite();
uint8_t mcp4728_simpleCommand(byte simpleCommand);
uint8_t mcp4728_getDrvPct(uint8_t channel);
void mcp4728_setDrvPct(uint8_t pct[XYZE]);
#endif
#endif // DAC_MCP4728_H
#endif

View File

@@ -1,77 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* AVR busy wait delay Cycles routines:
*
* DELAY_CYCLES(count): Delay execution in cycles
* DELAY_NS(count): Delay execution in nanoseconds
* DELAY_US(count): Delay execution in microseconds
*/
#ifndef MARLIN_DELAY_H
#define MARLIN_DELAY_H
#define nop() __asm__ __volatile__("nop;\n\t":::)
FORCE_INLINE static void __delay_4cycles(uint8_t cy) {
__asm__ __volatile__(
L("1")
A("dec %[cnt]")
A("nop")
A("brne 1b")
: [cnt] "+r"(cy) // output: +r means input+output
: // input:
: "cc" // clobbers:
);
}
/* ---------------- Delay in cycles */
FORCE_INLINE static void DELAY_CYCLES(uint16_t x) {
if (__builtin_constant_p(x)) {
#define MAXNOPS 4
if (x <= (MAXNOPS)) {
switch (x) { case 4: nop(); case 3: nop(); case 2: nop(); case 1: nop(); }
}
else {
const uint32_t rem = (x) % (MAXNOPS);
switch (rem) { case 3: nop(); case 2: nop(); case 1: nop(); }
if ((x = (x) / (MAXNOPS)))
__delay_4cycles(x); // if need more then 4 nop loop is more optimal
}
#undef MAXNOPS
}
else
__delay_4cycles(x / 4);
}
#undef nop
/* ---------------- Delay in nanoseconds */
#define DELAY_NS(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) / 1000L )
/* ---------------- Delay in microseconds */
#define DELAY_US(x) DELAY_CYCLES( (x) * (F_CPU/1000000L) )
#endif // MARLIN_DELAY_H

View File

@@ -1,106 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "MarlinConfig.h"
#if ENABLED(DIGIPOT_I2C) && ENABLED(DIGIPOT_MCP4018)
#include "enum.h"
#include "Stream.h"
#include "utility/twi.h"
#include <SlowSoftI2CMaster.h> //https://github.com/stawel/SlowSoftI2CMaster
// Settings for the I2C based DIGIPOT (MCP4018) based on WT150
#define DIGIPOT_I2C_ADDRESS 0x2F
#define DIGIPOT_A4988_Rsx 0.250
#define DIGIPOT_A4988_Vrefmax 1.666
#define DIGIPOT_A4988_MAX_VALUE 127
#define DIGIPOT_A4988_Itripmax(Vref) ((Vref)/(8.0*DIGIPOT_A4988_Rsx))
#define DIGIPOT_A4988_FACTOR ((DIGIPOT_A4988_MAX_VALUE)/DIGIPOT_A4988_Itripmax(DIGIPOT_A4988_Vrefmax))
#define DIGIPOT_A4988_MAX_CURRENT 2.0
static byte current_to_wiper(const float current) {
const int16_t value = ceil(float(DIGIPOT_A4988_FACTOR) * current);
return byte(constrain(value, 0, DIGIPOT_A4988_MAX_VALUE));
}
const uint8_t sda_pins[DIGIPOT_I2C_NUM_CHANNELS] = {
DIGIPOTS_I2C_SDA_X
#if DIGIPOT_I2C_NUM_CHANNELS > 1
, DIGIPOTS_I2C_SDA_Y
#if DIGIPOT_I2C_NUM_CHANNELS > 2
, DIGIPOTS_I2C_SDA_Z
#if DIGIPOT_I2C_NUM_CHANNELS > 3
, DIGIPOTS_I2C_SDA_E0
#if DIGIPOT_I2C_NUM_CHANNELS > 4
, DIGIPOTS_I2C_SDA_E1
#endif
#endif
#endif
#endif
};
static SlowSoftI2CMaster pots[DIGIPOT_I2C_NUM_CHANNELS] = {
SlowSoftI2CMaster { sda_pins[X_AXIS], DIGIPOTS_I2C_SCL }
#if DIGIPOT_I2C_NUM_CHANNELS > 1
, SlowSoftI2CMaster { sda_pins[Y_AXIS], DIGIPOTS_I2C_SCL }
#if DIGIPOT_I2C_NUM_CHANNELS > 2
, SlowSoftI2CMaster { sda_pins[Z_AXIS], DIGIPOTS_I2C_SCL }
#if DIGIPOT_I2C_NUM_CHANNELS > 3
, SlowSoftI2CMaster { sda_pins[E_AXIS], DIGIPOTS_I2C_SCL }
#if DIGIPOT_I2C_NUM_CHANNELS > 4
, SlowSoftI2CMaster { sda_pins[E_AXIS + 1], DIGIPOTS_I2C_SCL }
#endif
#endif
#endif
#endif
};
static void i2c_send(const uint8_t channel, const byte v) {
if (WITHIN(channel, 0, DIGIPOT_I2C_NUM_CHANNELS - 1)) {
pots[channel].i2c_start(((DIGIPOT_I2C_ADDRESS) << 1) | I2C_WRITE);
pots[channel].i2c_write(v);
pots[channel].i2c_stop();
}
}
// This is for the MCP4018 I2C based digipot
void digipot_i2c_set_current(uint8_t channel, float current) {
i2c_send(channel, current_to_wiper(MIN(MAX(current, 0), float(DIGIPOT_A4988_MAX_CURRENT))));
}
void digipot_i2c_init() {
static const float digipot_motor_current[] PROGMEM = DIGIPOT_I2C_MOTOR_CURRENTS;
for (uint8_t i = 0; i < DIGIPOT_I2C_NUM_CHANNELS; i++)
pots[i].i2c_init();
// setup initial currents as defined in Configuration_adv.h
for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++)
digipot_i2c_set_current(i, pgm_read_float(&digipot_motor_current[i]));
}
#endif // DIGIPOT_I2C && DIGIPOT_MCP4018

View File

@@ -22,7 +22,7 @@
#include "MarlinConfig.h"
#if ENABLED(DIGIPOT_I2C) && DISABLED(DIGIPOT_MCP4018)
#if ENABLED(DIGIPOT_I2C)
#include "Stream.h"
#include "utility/twi.h"
@@ -37,11 +37,11 @@
#define DIGIPOT_I2C_MAX_CURRENT 2.5
#endif
static byte current_to_wiper(const float current) {
return byte(CEIL(float((DIGIPOT_I2C_FACTOR * current))));
static byte current_to_wiper(float current) {
return byte(ceil(float((DIGIPOT_I2C_FACTOR * current))));
}
static void i2c_send(const byte addr, const byte a, const byte b) {
static void i2c_send(byte addr, byte a, byte b) {
Wire.beginTransmission(addr);
Wire.write(a);
Wire.write(b);
@@ -49,8 +49,8 @@ static void i2c_send(const byte addr, const byte a, const byte b) {
}
// This is for the MCP4451 I2C based digipot
void digipot_i2c_set_current(uint8_t channel, float current) {
current = MIN((float) MAX(current, 0), DIGIPOT_I2C_MAX_CURRENT);
void digipot_i2c_set_current(int channel, float current) {
current = min((float) max(current, 0.0f), DIGIPOT_I2C_MAX_CURRENT);
// these addresses are specific to Azteeg X3 Pro, can be set to others,
// In this case first digipot is at address A0=0, A1= 0, second one is at A0=0, A1= 1
byte addr = 0x2C; // channel 0-3
@@ -60,8 +60,8 @@ void digipot_i2c_set_current(uint8_t channel, float current) {
}
// Initial setup
i2c_send(addr, 0x40, 0xFF);
i2c_send(addr, 0xA0, 0xFF);
i2c_send(addr, 0x40, 0xff);
i2c_send(addr, 0xA0, 0xff);
// Set actual wiper value
byte addresses[4] = { 0x00, 0x10, 0x60, 0x70 };
@@ -69,11 +69,11 @@ void digipot_i2c_set_current(uint8_t channel, float current) {
}
void digipot_i2c_init() {
static const float digipot_motor_current[] PROGMEM = DIGIPOT_I2C_MOTOR_CURRENTS;
const float digipot_motor_current[] = DIGIPOT_I2C_MOTOR_CURRENTS;
Wire.begin();
// setup initial currents as defined in Configuration_adv.h
for (uint8_t i = 0; i < COUNT(digipot_motor_current); i++)
digipot_i2c_set_current(i, pgm_read_float(&digipot_motor_current[i]));
for (int i = 0; i < COUNT(digipot_motor_current); i++)
digipot_i2c_set_current(i, digipot_motor_current[i]);
}
#endif // DIGIPOT_I2C
#endif //DIGIPOT_I2C

File diff suppressed because it is too large Load Diff

View File

@@ -32,255 +32,167 @@
Max Font ascent = 8 descent=-1
*/
#include <U8glib.h>
#if defined(__AVR__) && ENABLED(NOT_EXTENDED_ISO10646_1_5X7)
//
// Reduced font (only symbols 32 - 127) - About 1400 bytes smaller
//
const u8g_fntpgm_uint8_t ISO10646_1_5x7[] U8G_SECTION(".progmem.ISO10646_1_5x7") = {
0,6,9,0,254,7,1,146,3,33,32,127,255,7,255,7,
255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
6,0,2,104,144,0,0,0,6,0,0};
#else
//
// Extended (original) font (symbols 32 - 255)
//
const u8g_fntpgm_uint8_t ISO10646_1_5x7[] U8G_SECTION(".progmem.ISO10646_1_5x7") = {
0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7,
255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104,
2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32,
64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32,
32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5,
5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192,
64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192,
192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6,
0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64,
192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112,
128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240,
5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7,
6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0,
112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16,
32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136,
112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5,
5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192,
192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64,
32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1,
0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136,
8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168,
168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5,
7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6,
0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240,
136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240,
128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128,
5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7,
6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0,
128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16,
16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144,
136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7,
7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0,
0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136,
136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128,
128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5,
7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6,
0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248,
32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136,
136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32,
5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7,
6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0,
136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16,
32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128,
224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6,
1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32,
80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128,
64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6,
0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112,
128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136,
120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6,
0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112,
136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136,
136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3,
8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7,
6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0,
192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168,
168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5,
6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136,
136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8,
5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0,
0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64,
64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5,
5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136,
136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5,
6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0,
0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128,
64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128,
3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2,
6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7,
7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0,
0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112,
80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32,
1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8,
6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1,
7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5,
7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6,
0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8,
2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136,
168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6,
0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32,
32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5,
5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64,
128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5,
7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6,
2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6,
0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136,
136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5,
7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6,
0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192,
64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32,
64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248,
136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136,
5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8,
8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6,
0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0,
32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96,
160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136,
112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128,
248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5,
8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7,
6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0,
128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64,
0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224,
64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64,
224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8,
8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6,
0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0,
16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80,
0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112,
136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136,
136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8,
6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0,
0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16,
32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0,
136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136,
136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32,
32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224,
4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8,
8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6,
0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0,
32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144,
0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8,
120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136,
120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6,
6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64,
32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0,
112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136,
248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112,
3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8,
8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6,
1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0,
160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160,
16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136,
136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112,
5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8,
8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6,
0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0,
80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248,
0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5,
8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8,
6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0,
0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80,
0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136,
136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96,
64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112
};
#endif
const u8g_fntpgm_uint8_t ISO10646_1_5x7[2592] U8G_SECTION(".progmem.ISO10646_1_5x7") = {
0, 6, 9, 0, 254, 7, 1, 146, 3, 33, 32, 255, 255, 8, 255, 7,
255, 0, 0, 0, 6, 0, 0, 1, 7, 7, 6, 2, 0, 128, 128, 128,
128, 128, 0, 128, 3, 2, 2, 6, 1, 5, 160, 160, 5, 7, 7, 6,
0, 0, 80, 80, 248, 80, 248, 80, 80, 5, 7, 7, 6, 0, 0, 32,
120, 160, 112, 40, 240, 32, 5, 7, 7, 6, 0, 0, 192, 200, 16, 32,
64, 152, 24, 5, 7, 7, 6, 0, 0, 96, 144, 160, 64, 168, 144, 104,
2, 3, 3, 6, 1, 4, 192, 64, 128, 3, 7, 7, 6, 1, 0, 32,
64, 128, 128, 128, 64, 32, 3, 7, 7, 6, 1, 0, 128, 64, 32, 32,
32, 64, 128, 5, 5, 5, 6, 0, 1, 32, 168, 112, 168, 32, 5, 5,
5, 6, 0, 1, 32, 32, 248, 32, 32, 2, 3, 3, 6, 2, 255, 192,
64, 128, 5, 1, 1, 6, 0, 3, 248, 2, 2, 2, 6, 2, 0, 192,
192, 5, 5, 5, 6, 0, 1, 8, 16, 32, 64, 128, 5, 7, 7, 6,
0, 0, 112, 136, 136, 136, 136, 136, 112, 3, 7, 7, 6, 1, 0, 64,
192, 64, 64, 64, 64, 224, 5, 7, 7, 6, 0, 0, 112, 136, 8, 112,
128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 16, 32, 16, 8, 8, 240,
5, 7, 7, 6, 0, 0, 16, 48, 80, 144, 248, 16, 16, 5, 7, 7,
6, 0, 0, 248, 128, 240, 8, 8, 136, 112, 5, 7, 7, 6, 0, 0,
112, 128, 128, 240, 136, 136, 112, 5, 7, 7, 6, 0, 0, 248, 8, 16,
32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 112, 136, 136, 112, 136, 136,
112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 120, 8, 8, 112, 2, 5,
5, 6, 2, 0, 192, 192, 0, 192, 192, 2, 6, 6, 6, 2, 255, 192,
192, 0, 192, 64, 128, 4, 7, 7, 6, 0, 0, 16, 32, 64, 128, 64,
32, 16, 5, 3, 3, 6, 0, 2, 248, 0, 248, 4, 7, 7, 6, 1,
0, 128, 64, 32, 16, 32, 64, 128, 5, 7, 7, 6, 0, 0, 112, 136,
8, 16, 32, 0, 32, 5, 7, 7, 6, 0, 0, 112, 136, 8, 104, 168,
168, 112, 5, 7, 7, 6, 0, 0, 112, 136, 136, 248, 136, 136, 136, 5,
7, 7, 6, 0, 0, 240, 136, 136, 240, 136, 136, 240, 5, 7, 7, 6,
0, 0, 112, 136, 128, 128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 240,
136, 136, 136, 136, 136, 240, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240,
128, 128, 248, 5, 7, 7, 6, 0, 0, 248, 128, 128, 240, 128, 128, 128,
5, 7, 7, 6, 0, 0, 112, 136, 128, 184, 136, 136, 112, 5, 7, 7,
6, 0, 0, 136, 136, 136, 248, 136, 136, 136, 1, 7, 7, 6, 2, 0,
128, 128, 128, 128, 128, 128, 128, 5, 7, 7, 6, 0, 0, 56, 16, 16,
16, 16, 144, 96, 5, 7, 7, 6, 0, 0, 136, 144, 160, 192, 160, 144,
136, 5, 7, 7, 6, 0, 0, 128, 128, 128, 128, 128, 128, 248, 5, 7,
7, 6, 0, 0, 136, 216, 168, 136, 136, 136, 136, 5, 7, 7, 6, 0,
0, 136, 136, 200, 168, 152, 136, 136, 5, 7, 7, 6, 0, 0, 112, 136,
136, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0, 240, 136, 136, 240, 128,
128, 128, 5, 7, 7, 6, 0, 0, 112, 136, 136, 136, 168, 144, 104, 5,
7, 7, 6, 0, 0, 240, 136, 136, 240, 160, 144, 136, 5, 7, 7, 6,
0, 0, 120, 128, 128, 112, 8, 8, 240, 5, 7, 7, 6, 0, 0, 248,
32, 32, 32, 32, 32, 32, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136,
136, 136, 112, 5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 80, 32,
5, 7, 7, 6, 0, 0, 136, 136, 136, 136, 136, 168, 80, 5, 7, 7,
6, 0, 0, 136, 136, 80, 32, 80, 136, 136, 5, 7, 7, 6, 0, 0,
136, 136, 136, 80, 32, 32, 32, 5, 7, 7, 6, 0, 0, 248, 8, 16,
32, 64, 128, 248, 3, 7, 7, 6, 1, 0, 224, 128, 128, 128, 128, 128,
224, 5, 5, 5, 6, 0, 1, 128, 64, 32, 16, 8, 3, 7, 7, 6,
1, 0, 224, 32, 32, 32, 32, 32, 224, 5, 3, 3, 6, 0, 4, 32,
80, 136, 5, 1, 1, 6, 0, 0, 248, 2, 2, 2, 6, 2, 5, 128,
64, 5, 5, 5, 6, 0, 0, 112, 8, 120, 136, 120, 5, 7, 7, 6,
0, 0, 128, 128, 176, 200, 136, 136, 240, 5, 5, 5, 6, 0, 0, 112,
128, 128, 136, 112, 5, 7, 7, 6, 0, 0, 8, 8, 104, 152, 136, 136,
120, 5, 5, 5, 6, 0, 0, 112, 136, 248, 128, 112, 5, 7, 7, 6,
0, 0, 48, 72, 224, 64, 64, 64, 64, 5, 6, 6, 6, 0, 255, 112,
136, 136, 120, 8, 112, 5, 7, 7, 6, 0, 0, 128, 128, 176, 200, 136,
136, 136, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 3,
8, 8, 6, 1, 255, 32, 0, 32, 32, 32, 32, 160, 64, 4, 7, 7,
6, 0, 0, 128, 128, 144, 160, 192, 160, 144, 3, 7, 7, 6, 1, 0,
192, 64, 64, 64, 64, 64, 224, 5, 5, 5, 6, 0, 0, 208, 168, 168,
168, 168, 5, 5, 5, 6, 0, 0, 176, 200, 136, 136, 136, 5, 5, 5,
6, 0, 0, 112, 136, 136, 136, 112, 5, 6, 6, 6, 0, 255, 240, 136,
136, 240, 128, 128, 5, 6, 6, 6, 0, 255, 120, 136, 136, 120, 8, 8,
5, 5, 5, 6, 0, 0, 176, 200, 128, 128, 128, 5, 5, 5, 6, 0,
0, 112, 128, 112, 8, 240, 4, 7, 7, 6, 0, 0, 64, 64, 224, 64,
64, 64, 48, 5, 5, 5, 6, 0, 0, 136, 136, 136, 152, 104, 5, 5,
5, 6, 0, 0, 136, 136, 136, 80, 32, 5, 5, 5, 6, 0, 0, 136,
136, 168, 168, 80, 5, 5, 5, 6, 0, 0, 136, 80, 32, 80, 136, 5,
6, 6, 6, 0, 255, 136, 136, 136, 120, 8, 112, 5, 5, 5, 6, 0,
0, 248, 16, 32, 64, 248, 3, 7, 7, 6, 1, 0, 32, 64, 64, 128,
64, 64, 32, 1, 7, 7, 6, 2, 0, 128, 128, 128, 128, 128, 128, 128,
3, 7, 7, 6, 1, 0, 128, 64, 64, 32, 64, 64, 128, 5, 2, 2,
6, 0, 2, 104, 144, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0,
6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0,
0, 0, 6, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 6, 0,
0, 1, 7, 7, 6, 2, 0, 128, 0, 128, 128, 128, 128, 128, 5, 7,
7, 6, 0, 0, 32, 112, 168, 160, 168, 112, 32, 5, 7, 7, 6, 0,
0, 48, 64, 64, 224, 64, 80, 168, 5, 5, 5, 6, 0, 0, 136, 112,
80, 112, 136, 5, 7, 7, 6, 0, 0, 136, 80, 32, 248, 32, 248, 32,
1, 7, 7, 6, 2, 0, 128, 128, 128, 0, 128, 128, 128, 5, 8, 8,
6, 0, 0, 48, 72, 32, 80, 80, 32, 144, 96, 3, 1, 1, 6, 1,
7, 160, 5, 7, 7, 6, 0, 0, 248, 136, 184, 184, 184, 136, 248, 5,
7, 7, 6, 0, 1, 112, 8, 120, 136, 120, 0, 248, 5, 5, 5, 6,
0, 1, 40, 80, 160, 80, 40, 5, 3, 3, 6, 0, 1, 248, 8, 8,
2, 2, 2, 6, 2, 6, 64, 128, 5, 7, 7, 6, 0, 0, 248, 136,
168, 136, 152, 168, 248, 5, 1, 1, 6, 0, 6, 248, 4, 4, 4, 6,
0, 3, 96, 144, 144, 96, 5, 7, 7, 6, 0, 0, 32, 32, 248, 32,
32, 0, 248, 4, 5, 5, 6, 0, 3, 96, 144, 32, 64, 240, 3, 5,
5, 6, 0, 3, 224, 32, 224, 32, 224, 2, 2, 2, 6, 2, 6, 64,
128, 5, 8, 8, 6, 0, 255, 136, 136, 136, 136, 152, 232, 128, 128, 5,
7, 7, 6, 0, 0, 120, 152, 152, 120, 24, 24, 24, 2, 2, 2, 6,
2, 2, 192, 192, 2, 2, 2, 6, 2, 255, 64, 128, 3, 5, 5, 6,
0, 3, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 1, 112, 136, 136,
136, 112, 0, 248, 5, 5, 5, 6, 0, 1, 160, 80, 40, 80, 160, 5,
7, 7, 6, 0, 0, 136, 144, 168, 88, 184, 8, 8, 5, 7, 7, 6,
0, 0, 136, 144, 184, 72, 152, 32, 56, 5, 8, 8, 6, 0, 0, 192,
64, 192, 72, 216, 56, 8, 8, 5, 7, 7, 6, 0, 0, 32, 0, 32,
64, 128, 136, 112, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 248,
136, 136, 5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 248, 136, 136,
5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136, 248, 136, 136, 5, 8,
8, 6, 0, 0, 104, 144, 0, 112, 136, 248, 136, 136, 5, 8, 8, 6,
0, 0, 80, 0, 112, 136, 136, 248, 136, 136, 5, 8, 8, 6, 0, 0,
32, 80, 32, 112, 136, 248, 136, 136, 5, 7, 7, 6, 0, 0, 56, 96,
160, 184, 224, 160, 184, 5, 8, 8, 6, 0, 255, 112, 136, 128, 128, 136,
112, 32, 96, 5, 8, 8, 6, 0, 0, 64, 32, 0, 248, 128, 240, 128,
248, 5, 8, 8, 6, 0, 0, 8, 16, 0, 248, 128, 240, 128, 248, 5,
8, 8, 6, 0, 0, 32, 80, 0, 248, 128, 240, 128, 248, 5, 7, 7,
6, 0, 0, 80, 0, 248, 128, 240, 128, 248, 3, 8, 8, 6, 1, 0,
128, 64, 0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 32, 64,
0, 224, 64, 64, 64, 224, 3, 8, 8, 6, 1, 0, 64, 160, 0, 224,
64, 64, 64, 224, 3, 7, 7, 6, 1, 0, 160, 0, 224, 64, 64, 64,
224, 5, 7, 7, 6, 0, 0, 112, 72, 72, 232, 72, 72, 112, 5, 8,
8, 6, 0, 0, 104, 144, 0, 136, 200, 168, 152, 136, 5, 8, 8, 6,
0, 0, 64, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0,
16, 32, 112, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80,
0, 112, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 112,
136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 112, 136, 136, 136,
136, 112, 5, 5, 5, 6, 0, 1, 136, 80, 32, 80, 136, 5, 8, 8,
6, 0, 255, 16, 112, 168, 168, 168, 168, 112, 64, 5, 8, 8, 6, 0,
0, 64, 32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 16,
32, 136, 136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0,
136, 136, 136, 136, 112, 5, 8, 8, 6, 0, 0, 80, 0, 136, 136, 136,
136, 136, 112, 5, 8, 8, 6, 0, 0, 16, 32, 136, 80, 32, 32, 32,
32, 5, 9, 9, 6, 0, 255, 192, 64, 112, 72, 72, 112, 64, 64, 224,
4, 8, 8, 6, 1, 255, 96, 144, 144, 160, 144, 144, 224, 128, 5, 8,
8, 6, 0, 0, 64, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6,
0, 0, 16, 32, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0,
32, 80, 0, 112, 8, 120, 136, 120, 5, 8, 8, 6, 0, 0, 104, 144,
0, 112, 8, 120, 136, 120, 5, 7, 7, 6, 0, 0, 80, 0, 112, 8,
120, 136, 120, 5, 8, 8, 6, 0, 0, 32, 80, 32, 112, 8, 120, 136,
120, 5, 6, 6, 6, 0, 0, 208, 40, 120, 160, 168, 80, 5, 6, 6,
6, 0, 255, 112, 128, 136, 112, 32, 96, 5, 8, 8, 6, 0, 0, 64,
32, 0, 112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 16, 32, 0,
112, 136, 248, 128, 112, 5, 8, 8, 6, 0, 0, 32, 80, 0, 112, 136,
248, 128, 112, 5, 7, 7, 6, 0, 0, 80, 0, 112, 136, 248, 128, 112,
3, 8, 8, 6, 1, 0, 128, 64, 0, 64, 192, 64, 64, 224, 3, 8,
8, 6, 1, 0, 32, 64, 0, 64, 192, 64, 64, 224, 3, 8, 8, 6,
1, 0, 64, 160, 0, 64, 192, 64, 64, 224, 3, 7, 7, 6, 1, 0,
160, 0, 64, 192, 64, 64, 224, 5, 7, 7, 6, 0, 0, 160, 64, 160,
16, 120, 136, 112, 5, 8, 8, 6, 0, 0, 104, 144, 0, 176, 200, 136,
136, 136, 5, 8, 8, 6, 0, 0, 64, 32, 0, 112, 136, 136, 136, 112,
5, 8, 8, 6, 0, 0, 16, 32, 0, 112, 136, 136, 136, 112, 5, 8,
8, 6, 0, 0, 32, 80, 0, 112, 136, 136, 136, 112, 5, 8, 8, 6,
0, 0, 104, 144, 0, 112, 136, 136, 136, 112, 5, 7, 7, 6, 0, 0,
80, 0, 112, 136, 136, 136, 112, 5, 5, 5, 6, 0, 1, 32, 0, 248,
0, 32, 5, 7, 7, 6, 0, 255, 16, 112, 168, 168, 168, 112, 64, 5,
8, 8, 6, 0, 0, 64, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8,
6, 0, 0, 16, 32, 0, 136, 136, 136, 152, 104, 5, 8, 8, 6, 0,
0, 32, 80, 0, 136, 136, 136, 152, 104, 5, 7, 7, 6, 0, 0, 80,
0, 136, 136, 136, 152, 104, 5, 9, 9, 6, 0, 255, 16, 32, 0, 136,
136, 136, 248, 8, 112, 4, 7, 7, 6, 1, 255, 192, 64, 96, 80, 96,
64, 224, 5, 8, 8, 6, 0, 255, 80, 0, 136, 136, 136, 120, 8, 112
};

View File

@@ -1,184 +0,0 @@
/*
Fontname: ISO10646-1-PL
Copyright: A.Hardtung, public domain
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-2 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
X Font ascent = 7 descent=-1
Max Font ascent = 8 descent=-2
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_1_PL_5x7[2732] U8G_FONT_SECTION(".progmem.ISO10646_1_PL_5x7") = {
0,6,9,0,254,7,1,146,3,33,32,255,255,8,254,7,
255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
6,0,2,104,144,0,0,0,6,0,0,5,9,9,6,0,
254,112,136,136,248,136,136,136,16,32,5,7,7,6,0,254,
112,8,120,136,120,16,32,5,8,8,6,0,0,16,32,112,
136,128,128,136,112,5,7,7,6,0,0,16,32,112,128,128,
136,112,5,9,9,6,0,254,248,128,128,240,128,128,248,8,
16,5,7,7,6,0,254,112,136,248,128,112,16,32,5,7,
7,6,0,0,128,144,160,192,128,128,248,5,7,7,6,0,
0,96,40,48,96,160,32,112,5,8,8,6,0,0,16,168,
136,200,168,152,136,136,5,8,8,6,0,0,8,16,0,176,
200,136,136,136,5,8,8,6,0,0,16,32,112,136,136,136,
136,112,5,8,8,6,0,0,16,32,0,112,136,136,136,112,
5,8,8,6,0,0,16,120,128,128,112,8,8,240,5,8,
8,6,0,0,16,32,0,112,128,112,8,240,5,8,8,6,
0,0,32,248,8,16,32,64,128,248,5,8,8,6,0,0,
16,32,0,248,16,32,64,248,5,7,7,6,0,0,248,8,
16,248,64,128,248,5,8,8,6,0,0,48,48,0,248,16,
32,64,248,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,1,7,7,
6,2,0,128,0,128,128,128,128,128,5,7,7,6,0,0,
32,112,168,160,168,112,32,5,7,7,6,0,0,48,64,64,
224,64,80,168,5,5,5,6,0,0,136,112,80,112,136,5,
7,7,6,0,0,136,80,32,248,32,248,32,1,7,7,6,
2,0,128,128,128,0,128,128,128,5,8,8,6,0,0,48,
72,32,80,80,32,144,96,3,1,1,6,1,7,160,5,7,
7,6,0,0,248,136,184,184,184,136,248,5,7,7,6,0,
1,112,8,120,136,120,0,248,5,5,5,6,0,1,40,80,
160,80,40,5,3,3,6,0,1,248,8,8,2,2,2,6,
2,6,64,128,5,7,7,6,0,0,248,136,168,136,152,168,
248,5,1,1,6,0,6,248,4,4,4,6,0,3,96,144,
144,96,5,7,7,6,0,0,32,32,248,32,32,0,248,4,
5,5,6,0,3,96,144,32,64,240,3,5,5,6,0,3,
224,32,224,32,224,2,2,2,6,2,6,64,128,5,8,8,
6,0,255,136,136,136,136,152,232,128,128,5,7,7,6,0,
0,120,152,152,120,24,24,24,2,2,2,6,2,2,192,192,
2,2,2,6,2,255,64,128,3,5,5,6,0,3,64,192,
64,64,224,5,7,7,6,0,1,112,136,136,136,112,0,248,
5,5,5,6,0,1,160,80,40,80,160,5,7,7,6,0,
0,136,144,168,88,184,8,8,5,7,7,6,0,0,136,144,
184,72,152,32,56,5,8,8,6,0,0,192,64,192,72,216,
56,8,8,5,7,7,6,0,0,32,0,32,64,128,136,112,
5,8,8,6,0,0,64,32,0,112,136,248,136,136,5,8,
8,6,0,0,16,32,0,112,136,248,136,136,5,8,8,6,
0,0,32,80,0,112,136,248,136,136,5,8,8,6,0,0,
104,144,0,112,136,248,136,136,5,8,8,6,0,0,80,0,
112,136,136,248,136,136,5,8,8,6,0,0,32,80,32,112,
136,248,136,136,5,7,7,6,0,0,56,96,160,184,224,160,
184,5,8,8,6,0,255,112,136,128,128,136,112,32,96,5,
8,8,6,0,0,64,32,0,248,128,240,128,248,5,8,8,
6,0,0,8,16,0,248,128,240,128,248,5,8,8,6,0,
0,32,80,0,248,128,240,128,248,5,7,7,6,0,0,80,
0,248,128,240,128,248,3,8,8,6,1,0,128,64,0,224,
64,64,64,224,3,8,8,6,1,0,32,64,0,224,64,64,
64,224,3,8,8,6,1,0,64,160,0,224,64,64,64,224,
3,7,7,6,1,0,160,0,224,64,64,64,224,5,7,7,
6,0,0,112,72,72,232,72,72,112,5,8,8,6,0,0,
104,144,0,136,200,168,152,136,5,8,8,6,0,0,64,32,
112,136,136,136,136,112,5,8,8,6,0,0,16,32,112,136,
136,136,136,112,5,8,8,6,0,0,32,80,0,112,136,136,
136,112,5,8,8,6,0,0,104,144,0,112,136,136,136,112,
5,8,8,6,0,0,80,0,112,136,136,136,136,112,5,5,
5,6,0,1,136,80,32,80,136,5,8,8,6,0,255,16,
112,168,168,168,168,112,64,5,8,8,6,0,0,64,32,136,
136,136,136,136,112,5,8,8,6,0,0,16,32,136,136,136,
136,136,112,5,8,8,6,0,0,32,80,0,136,136,136,136,
112,5,8,8,6,0,0,80,0,136,136,136,136,136,112,5,
8,8,6,0,0,16,32,136,80,32,32,32,32,5,9,9,
6,0,255,192,64,112,72,72,112,64,64,224,4,8,8,6,
1,255,96,144,144,160,144,144,224,128,5,8,8,6,0,0,
64,32,0,112,8,120,136,120,5,8,8,6,0,0,16,32,
0,112,8,120,136,120,5,8,8,6,0,0,32,80,0,112,
8,120,136,120,5,8,8,6,0,0,104,144,0,112,8,120,
136,120,5,7,7,6,0,0,80,0,112,8,120,136,120,5,
8,8,6,0,0,32,80,32,112,8,120,136,120,5,6,6,
6,0,0,208,40,120,160,168,80,5,6,6,6,0,255,112,
128,136,112,32,96,5,8,8,6,0,0,64,32,0,112,136,
248,128,112,5,8,8,6,0,0,16,32,0,112,136,248,128,
112,5,8,8,6,0,0,32,80,0,112,136,248,128,112,5,
7,7,6,0,0,80,0,112,136,248,128,112,3,8,8,6,
1,0,128,64,0,64,192,64,64,224,3,8,8,6,1,0,
32,64,0,64,192,64,64,224,3,8,8,6,1,0,64,160,
0,64,192,64,64,224,3,7,7,6,1,0,160,0,64,192,
64,64,224,5,7,7,6,0,0,160,64,160,16,120,136,112,
5,8,8,6,0,0,104,144,0,176,200,136,136,136,5,8,
8,6,0,0,64,32,0,112,136,136,136,112,5,8,8,6,
0,0,16,32,0,112,136,136,136,112,5,8,8,6,0,0,
32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,144,
0,112,136,136,136,112,5,7,7,6,0,0,80,0,112,136,
136,136,112,5,5,5,6,0,1,32,0,248,0,32,5,7,
7,6,0,255,16,112,168,168,168,112,64,5,8,8,6,0,
0,64,32,0,136,136,136,152,104,5,8,8,6,0,0,16,
32,0,136,136,136,152,104,5,8,8,6,0,0,32,80,0,
136,136,136,152,104,5,7,7,6,0,0,80,0,136,136,136,
152,104,5,9,9,6,0,255,16,32,0,136,136,136,248,8,
112,4,7,7,6,1,255,192,64,96,80,96,64,224,5,8,
8,6,0,255,80,0,136,136,136,120,8,112};

View File

@@ -1,197 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/*
Fontname: ISO10646-1-tr
Copyright: public domain
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 5 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
X Font ascent = 7 descent=-1
Max Font ascent = 8 descent=-1
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_TR[2591] U8G_SECTION(".progmem.ISO10646_TR") = {
0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7,
255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
6,0,2,104,144,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,1,7,7,6,2,0,128,0,128,128,128,128,128,5,7,
7,6,0,0,32,112,168,160,168,112,32,5,7,7,6,0,
0,48,64,64,224,64,80,168,5,5,5,6,0,0,136,112,
80,112,136,5,7,7,6,0,0,136,80,32,248,32,248,32,
1,7,7,6,2,0,128,128,128,0,128,128,128,5,8,8,
6,0,0,48,72,32,80,80,32,144,96,3,1,1,6,1,
7,160,5,7,7,6,0,0,248,136,184,184,184,136,248,5,
7,7,6,0,1,112,8,120,136,120,0,248,5,5,5,6,
0,1,40,80,160,80,40,5,3,3,6,0,1,248,8,8,
2,2,2,6,2,6,64,128,5,7,7,6,0,0,248,136,
168,136,152,168,248,5,1,1,6,0,6,248,4,4,4,6,
0,3,96,144,144,96,5,7,7,6,0,0,32,32,248,32,
32,0,248,4,5,5,6,0,3,96,144,32,64,240,3,5,
5,6,0,3,224,32,224,32,224,2,2,2,6,2,6,64,
128,5,8,8,6,0,255,136,136,136,136,152,232,128,128,5,
7,7,6,0,0,120,152,152,120,24,24,24,2,2,2,6,
2,2,192,192,2,2,2,6,2,255,64,128,3,5,5,6,
0,3,64,192,64,64,224,5,7,7,6,0,1,112,136,136,
136,112,0,248,5,5,5,6,0,1,160,80,40,80,160,5,
7,7,6,0,0,136,144,168,88,184,8,8,5,7,7,6,
0,0,136,144,184,72,152,32,56,5,8,8,6,0,0,192,
64,192,72,216,56,8,8,5,7,7,6,0,0,32,0,32,
64,128,136,112,5,8,8,6,0,0,64,32,0,112,136,248,
136,136,5,8,8,6,0,0,16,32,0,112,136,248,136,136,
5,8,8,6,0,0,32,80,0,112,136,248,136,136,5,8,
8,6,0,0,104,144,0,112,136,248,136,136,5,8,8,6,
0,0,80,0,112,136,136,248,136,136,5,8,8,6,0,0,
32,80,32,112,136,248,136,136,5,7,7,6,0,0,56,96,
160,184,224,160,184,5,8,8,6,0,255,112,136,128,128,136,
112,32,96,5,8,8,6,0,0,64,32,0,248,128,240,128,
248,5,8,8,6,0,0,8,16,0,248,128,240,128,248,5,
8,8,6,0,0,32,80,0,248,128,240,128,248,5,7,7,
6,0,0,80,0,248,128,240,128,248,3,8,8,6,1,0,
128,64,0,224,64,64,64,224,3,8,8,6,1,0,32,64,
0,224,64,64,64,224,3,8,8,6,1,0,64,160,0,224,
64,64,64,224,3,7,7,6,1,0,160,0,224,64,64,64,
224,5,9,9,6,0,255,80,32,112,136,128,184,136,136,112,
5,8,8,6,0,0,104,144,0,136,200,168,152,136,5,8,
8,6,0,0,64,32,112,136,136,136,136,112,5,8,8,6,
0,0,16,32,112,136,136,136,136,112,5,8,8,6,0,0,
32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,144,
0,112,136,136,136,112,5,8,8,6,0,0,80,0,112,136,
136,136,136,112,5,5,5,6,0,1,136,80,32,80,136,5,
8,8,6,0,255,16,112,168,168,168,168,112,64,5,8,8,
6,0,0,64,32,136,136,136,136,136,112,5,8,8,6,0,
0,16,32,136,136,136,136,136,112,5,8,8,6,0,0,32,
80,0,136,136,136,136,112,5,8,8,6,0,0,80,0,136,
136,136,136,136,112,1,7,7,6,2,0,128,0,128,128,128,
128,128,5,9,9,6,0,255,120,128,128,112,8,8,240,32,
96,4,8,8,6,1,255,96,144,144,160,144,144,224,128,5,
8,8,6,0,0,64,32,0,112,8,120,136,120,5,8,8,
6,0,0,16,32,0,112,8,120,136,120,5,8,8,6,0,
0,32,80,0,112,8,120,136,120,5,8,8,6,0,0,104,
144,0,112,8,120,136,120,5,7,7,6,0,0,80,0,112,
8,120,136,120,5,8,8,6,0,0,32,80,32,112,8,120,
136,120,5,6,6,6,0,0,208,40,120,160,168,80,5,7,
7,6,0,255,112,128,128,136,112,32,96,5,8,8,6,0,
0,64,32,0,112,136,248,128,112,5,8,8,6,0,0,16,
32,0,112,136,248,128,112,5,8,8,6,0,0,32,80,0,
112,136,248,128,112,5,7,7,6,0,0,80,0,112,136,248,
128,112,3,8,8,6,1,0,128,64,0,64,192,64,64,224,
3,8,8,6,1,0,32,64,0,64,192,64,64,224,3,8,
8,6,1,0,64,160,0,64,192,64,64,224,3,7,7,6,
1,0,160,0,64,192,64,64,224,5,8,8,6,0,255,80,
32,112,136,136,120,8,112,5,8,8,6,0,0,104,144,0,
176,200,136,136,136,5,8,8,6,0,0,64,32,0,112,136,
136,136,112,5,8,8,6,0,0,16,32,0,112,136,136,136,
112,5,8,8,6,0,0,32,80,0,112,136,136,136,112,5,
8,8,6,0,0,104,144,0,112,136,136,136,112,5,7,7,
6,0,0,80,0,112,136,136,136,112,5,5,5,6,0,1,
32,0,248,0,32,5,7,7,6,0,255,16,112,168,168,168,
112,64,5,8,8,6,0,0,64,32,0,136,136,136,152,104,
5,8,8,6,0,0,16,32,0,136,136,136,152,104,5,8,
8,6,0,0,32,80,0,136,136,136,152,104,5,7,7,6,
0,0,80,0,136,136,136,152,104,1,5,5,6,2,0,128,
128,128,128,128,5,7,7,6,0,255,112,128,112,8,240,32,
96,5,8,8,6,0,255,80,0,136,136,136,120,8,112};

View File

@@ -1,192 +0,0 @@
/*
Fontname: ISO10646_CZ
Copyright: A. Hardtung, public domain
Modified for Czech accents by Petr Zahradnik, http://www.zahradniksebavi.cz
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 6 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
X Font ascent = 7 descent=-1
Max Font ascent = 8 descent=-1
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_CZ[2832] U8G_SECTION(".progmem.ISO10646_CZ") = {
0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7,
255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
6,0,2,104,144,0,0,0,6,0,0,5,8,8,6,0,
0,16,32,112,136,136,248,136,136,5,8,8,6,0,0,8,
16,248,128,128,240,128,248,3,8,8,6,1,0,32,64,224,
64,64,64,64,224,5,8,8,6,0,0,16,32,112,136,136,
136,136,112,5,8,8,6,0,0,16,32,136,136,136,136,136,
112,5,8,8,6,0,0,16,32,136,136,80,32,32,32,5,
8,8,6,0,0,16,32,0,112,8,120,136,120,5,8,8,
6,0,0,16,32,0,112,136,248,128,112,2,8,8,6,2,
0,64,128,0,128,128,128,128,128,5,8,8,6,0,0,16,
32,0,112,136,136,136,112,5,8,8,6,0,0,16,32,0,
136,136,136,152,104,5,9,9,6,0,255,16,32,0,136,136,
136,120,8,112,5,8,8,6,0,0,80,32,112,136,128,128,
136,112,5,8,8,6,0,0,80,32,0,112,128,128,136,112,
5,8,8,6,0,0,80,32,240,136,136,136,136,240,6,8,
8,6,0,0,4,20,24,112,144,144,144,112,5,8,8,6,
0,0,80,32,248,128,128,240,128,248,5,8,8,6,0,0,
80,32,0,112,136,248,128,112,5,8,8,6,0,0,80,32,
136,200,168,152,136,136,5,8,8,6,0,0,80,32,0,176,
200,136,136,136,5,8,8,6,0,0,80,32,240,136,240,160,
144,136,5,8,8,6,0,0,80,32,0,176,200,128,128,128,
5,8,8,6,0,0,80,32,120,128,128,112,8,240,5,8,
8,6,0,0,80,32,0,112,128,112,8,240,5,8,8,6,
0,0,80,32,248,32,32,32,32,32,6,8,8,6,0,0,
4,68,72,224,64,64,64,48,5,8,8,6,0,0,32,80,
168,136,136,136,136,112,5,8,8,6,0,0,32,80,32,136,
136,136,152,104,5,8,8,6,0,0,80,32,248,8,48,64,
128,248,5,8,8,6,0,0,80,32,0,248,16,32,64,248,
0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,
0,0,1,7,7,6,2,0,128,0,128,128,128,128,128,5,
7,7,6,0,0,32,112,168,160,168,112,32,5,7,7,6,
0,0,48,64,64,224,64,80,168,5,5,5,6,0,0,136,
112,80,112,136,5,7,7,6,0,0,136,80,32,248,32,248,
32,1,7,7,6,2,0,128,128,128,0,128,128,128,5,8,
8,6,0,0,48,72,32,80,80,32,144,96,3,1,1,6,
1,7,160,5,7,7,6,0,0,248,136,184,184,184,136,248,
5,7,7,6,0,1,112,8,120,136,120,0,248,5,5,5,
6,0,1,40,80,160,80,40,5,3,3,6,0,1,248,8,
8,2,2,2,6,2,6,64,128,5,7,7,6,0,0,248,
136,168,136,152,168,248,5,1,1,6,0,6,248,4,4,4,
6,0,3,96,144,144,96,5,7,7,6,0,0,32,32,248,
32,32,0,248,4,5,5,6,0,3,96,144,32,64,240,3,
5,5,6,0,3,224,32,224,32,224,2,2,2,6,2,6,
64,128,5,8,8,6,0,255,136,136,136,136,152,232,128,128,
5,7,7,6,0,0,120,152,152,120,24,24,24,2,2,2,
6,2,2,192,192,2,2,2,6,2,255,64,128,3,5,5,
6,0,3,64,192,64,64,224,5,7,7,6,0,1,112,136,
136,136,112,0,248,5,5,5,6,0,1,160,80,40,80,160,
5,7,7,6,0,0,136,144,168,88,184,8,8,5,7,7,
6,0,0,136,144,184,72,152,32,56,5,8,8,6,0,0,
192,64,192,72,216,56,8,8,5,7,7,6,0,0,32,0,
32,64,128,136,112,5,8,8,6,0,0,64,32,0,112,136,
248,136,136,5,8,8,6,0,0,16,32,0,112,136,248,136,
136,5,8,8,6,0,0,32,80,0,112,136,248,136,136,5,
8,8,6,0,0,104,144,0,112,136,248,136,136,5,8,8,
6,0,0,80,0,112,136,136,248,136,136,5,8,8,6,0,
0,32,80,32,112,136,248,136,136,5,7,7,6,0,0,56,
96,160,184,224,160,184,5,8,8,6,0,255,112,136,128,128,
136,112,32,96,5,8,8,6,0,0,64,32,0,248,128,240,
128,248,5,8,8,6,0,0,8,16,0,248,128,240,128,248,
5,8,8,6,0,0,32,80,0,248,128,240,128,248,5,7,
7,6,0,0,80,0,248,128,240,128,248,3,8,8,6,1,
0,128,64,0,224,64,64,64,224,3,8,8,6,1,0,32,
64,0,224,64,64,64,224,3,8,8,6,1,0,64,160,0,
224,64,64,64,224,3,7,7,6,1,0,160,0,224,64,64,
64,224,5,9,9,6,0,255,80,32,112,136,128,184,136,136,
112,5,8,8,6,0,0,104,144,0,136,200,168,152,136,5,
8,8,6,0,0,64,32,112,136,136,136,136,112,5,8,8,
6,0,0,16,32,112,136,136,136,136,112,5,8,8,6,0,
0,32,80,0,112,136,136,136,112,5,8,8,6,0,0,104,
144,0,112,136,136,136,112,5,8,8,6,0,0,80,0,112,
136,136,136,136,112,5,5,5,6,0,1,136,80,32,80,136,
5,8,8,6,0,255,16,112,168,168,168,168,112,64,5,8,
8,6,0,0,64,32,136,136,136,136,136,112,5,8,8,6,
0,0,16,32,136,136,136,136,136,112,5,8,8,6,0,0,
32,80,0,136,136,136,136,112,5,8,8,6,0,0,80,0,
136,136,136,136,136,112,1,7,7,6,2,0,128,0,128,128,
128,128,128,5,9,9,6,0,255,120,128,128,112,8,8,240,
32,96,4,8,8,6,1,255,96,144,144,160,144,144,224,128,
5,8,8,6,0,0,64,32,0,112,8,120,136,120,5,8,
8,6,0,0,16,32,0,112,8,120,136,120,5,8,8,6,
0,0,32,80,0,112,8,120,136,120,5,8,8,6,0,0,
104,144,0,112,8,120,136,120,5,7,7,6,0,0,80,0,
112,8,120,136,120,5,8,8,6,0,0,32,80,32,112,8,
120,136,120,5,6,6,6,0,0,208,40,120,160,168,80,5,
7,7,6,0,255,112,128,128,136,112,32,96,5,8,8,6,
0,0,64,32,0,112,136,248,128,112,5,8,8,6,0,0,
16,32,0,112,136,248,128,112,5,8,8,6,0,0,32,80,
0,112,136,248,128,112,5,7,7,6,0,0,80,0,112,136,
248,128,112,3,8,8,6,1,0,128,64,0,64,192,64,64,
224,3,8,8,6,1,0,32,64,0,64,192,64,64,224,3,
8,8,6,1,0,64,160,0,64,192,64,64,224,3,7,7,
6,1,0,160,0,64,192,64,64,224,5,8,8,6,0,255,
80,32,112,136,136,120,8,112,5,8,8,6,0,0,104,144,
0,176,200,136,136,136,5,8,8,6,0,0,64,32,0,112,
136,136,136,112,5,8,8,6,0,0,16,32,0,112,136,136,
136,112,5,8,8,6,0,0,32,80,0,112,136,136,136,112,
5,8,8,6,0,0,104,144,0,112,136,136,136,112,5,7,
7,6,0,0,80,0,112,136,136,136,112,5,5,5,6,0,
1,32,0,248,0,32,5,7,7,6,0,255,16,112,168,168,
168,112,64,5,8,8,6,0,0,64,32,0,136,136,136,152,
104,5,8,8,6,0,0,16,32,0,136,136,136,152,104,5,
8,8,6,0,0,32,80,0,136,136,136,152,104,5,7,7,
6,0,0,80,0,136,136,136,152,104,1,5,5,6,2,0,
128,128,128,128,128,5,7,7,6,0,255,112,128,112,8,240,
32,96,5,8,8,6,0,255,80,0,136,136,136,120,8,112
};

View File

@@ -24,16 +24,16 @@
Fontname: ISO10646_4_Greek
Copyright: A. Hardtung, public domain
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 5 h= 9 x= 2 y= 6 dx= 6 dy= 0 ascent= 8 len= 9
Calculated Max Values w= 5 h=10 x= 2 y= 6 dx= 6 dy= 0 ascent= 8 len=10
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
Calculated Min Values x= 0 y=-2 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
X Font ascent = 7 descent=-1
Max Font ascent = 8 descent=-1
Max Font ascent = 8 descent=-2
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_Greek_5x7[2715] U8G_SECTION(".progmem.ISO10646_Greek_5x7") = {
0,6,9,0,254,7,1,145,3,32,32,255,255,8,255,7,
const u8g_fntpgm_uint8_t ISO10646_Greek_5x7[2728] U8G_SECTION(".progmem.ISO10646_Greek_5x7") = {
0,6,9,0,254,7,1,145,3,32,32,255,255,8,254,7,
255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
@@ -139,67 +139,68 @@ const u8g_fntpgm_uint8_t ISO10646_Greek_5x7[2715] U8G_SECTION(".progmem.ISO10646
80,80,216,3,8,8,6,1,0,160,0,224,64,64,64,64,
224,5,8,8,6,0,0,80,0,136,136,136,80,32,32,5,
8,8,6,0,0,32,64,8,104,152,144,144,104,5,8,8,
6,0,0,32,64,0,112,136,224,136,112,5,9,9,6,0,
255,32,64,0,112,136,136,136,136,8,2,8,8,6,1,0,
64,128,0,128,128,128,128,64,5,8,8,6,0,0,16,32,
80,0,136,136,136,112,5,6,6,6,0,0,8,104,152,144,
144,104,4,6,6,6,0,255,96,144,240,144,224,128,5,6,
6,6,0,255,136,72,80,32,32,64,5,6,6,6,0,0,
48,64,112,136,136,112,5,5,5,6,0,0,112,136,224,136,
112,5,8,8,6,0,255,128,112,64,128,128,112,8,112,5,
6,6,6,0,255,184,200,136,136,136,8,5,5,5,6,0,
0,112,136,248,136,112,3,5,5,6,1,0,128,128,128,128,
96,4,5,5,6,0,0,144,160,192,160,144,5,6,6,6,
0,0,64,32,32,80,80,136,5,6,6,6,0,255,136,136,
136,216,168,128,5,5,5,6,0,0,136,136,80,96,32,5,
9,9,6,0,255,128,224,128,112,32,64,240,8,112,5,5,
5,6,0,0,112,136,136,136,112,5,5,5,6,0,0,248,
80,80,80,80,5,6,6,6,0,255,112,136,136,200,176,128,
5,7,7,6,0,255,48,64,128,64,48,8,112,5,5,5,
6,0,0,104,144,144,144,96,4,5,5,6,0,0,240,64,
64,64,48,5,5,5,6,0,0,136,136,144,144,224,5,7,
7,6,0,255,32,168,168,168,112,32,32,5,6,6,6,0,
255,136,80,32,32,80,136,5,6,6,6,0,255,168,168,168,
168,112,32,5,5,5,6,0,0,80,136,136,168,112,4,7,
7,6,0,0,160,0,64,64,64,64,48,5,7,7,6,0,
0,80,0,136,136,144,144,224,4,8,8,6,0,0,32,64,
0,96,144,144,144,96,5,8,8,6,0,0,32,64,0,136,
136,144,144,96,5,8,8,6,0,0,32,64,0,80,136,136,
168,112,5,7,7,6,0,255,144,160,192,160,144,136,16,5,
8,8,6,0,0,96,144,160,128,240,136,136,112,5,7,7,
6,0,0,112,80,56,144,144,144,96,5,6,6,6,0,0,
152,80,32,32,32,32,5,8,8,6,0,0,64,128,152,80,
32,32,32,32,5,8,8,6,0,0,80,0,152,80,32,32,
32,32,5,7,7,6,0,255,48,168,168,168,168,112,32,5,
5,5,6,0,0,248,80,80,80,88,5,6,6,6,0,255,
136,80,112,80,136,16,5,7,7,6,0,255,112,136,136,136,
112,32,112,5,6,6,6,0,255,112,136,136,112,32,112,5,
6,6,6,0,0,112,136,128,112,32,112,5,7,7,6,0,
255,8,8,112,128,112,16,96,5,6,6,6,0,0,248,128,
128,240,128,128,4,5,5,6,0,0,240,128,224,128,128,5,
6,6,6,0,0,248,0,0,112,0,248,4,5,5,6,0,
0,64,128,240,16,32,5,7,7,6,0,0,224,80,40,40,
8,8,16,5,7,7,6,0,0,192,32,80,40,8,8,8,
5,7,7,6,0,255,168,168,168,168,88,8,112,5,6,6,
6,0,255,168,168,168,88,8,112,5,6,6,6,0,0,104,
136,136,120,8,8,5,6,6,6,0,255,104,136,136,120,8,
8,4,8,8,6,0,255,128,224,144,144,144,144,32,192,5,
5,5,6,0,0,104,144,112,16,224,5,6,6,6,0,0,
96,144,16,96,136,112,4,6,6,6,0,0,96,144,16,96,
128,112,5,6,6,6,0,0,136,80,32,80,136,248,5,5,
5,6,0,0,136,80,32,80,112,5,6,6,6,0,0,120,
128,240,136,136,112,4,5,5,6,0,0,240,128,224,144,96,
3,6,6,6,1,0,64,224,64,64,64,64,3,6,6,6,
1,255,64,224,64,64,64,128,5,5,5,6,0,0,136,80,
112,80,136,5,6,6,6,0,255,112,136,136,240,128,112,4,
5,5,6,0,0,112,128,128,128,112,2,8,8,6,1,255,
64,0,192,64,64,64,64,128,5,7,7,6,0,0,112,136,
136,248,136,136,112,4,5,5,6,0,0,112,128,224,128,112,
4,5,5,6,0,0,224,16,112,16,224,5,7,7,6,0,
0,128,240,136,136,136,240,128,4,7,7,6,0,255,128,224,
144,144,144,224,128,5,6,6,6,0,0,112,136,128,128,136,
112,5,6,6,6,0,0,136,216,168,136,136,136,5,6,6,
6,0,255,136,216,168,136,136,128,5,8,8,6,0,255,112,
136,136,136,112,64,224,64,5,6,6,6,0,0,112,136,8,
8,136,112,5,6,6,6,0,0,112,136,160,128,136,112,5,
6,6,6,0,0,112,136,40,8,136,112};
6,0,0,32,64,0,112,136,224,136,112,5,10,10,6,0,
254,32,64,0,112,136,136,136,136,8,8,2,8,8,6,1,
0,64,128,0,128,128,128,128,64,5,8,8,6,0,0,16,
32,80,0,136,136,136,112,5,6,6,6,0,0,8,104,152,
144,144,104,4,7,7,6,0,254,96,144,240,144,224,128,128,
5,6,6,6,0,255,136,72,80,32,32,64,5,6,6,6,
0,0,48,64,112,136,136,112,5,5,5,6,0,0,112,136,
224,136,112,5,9,9,6,0,254,128,112,64,128,128,128,112,
8,112,5,7,7,6,0,254,184,200,136,136,136,8,8,5,
5,5,6,0,0,112,136,248,136,112,3,5,5,6,1,0,
128,128,128,128,96,4,5,5,6,0,0,144,160,192,160,144,
5,6,6,6,0,0,64,32,32,80,80,136,5,7,7,6,
0,254,136,136,136,216,168,128,128,5,5,5,6,0,0,136,
136,80,96,32,5,10,10,6,0,254,128,224,128,112,32,64,
128,112,8,112,5,5,5,6,0,0,112,136,136,136,112,5,
5,5,6,0,0,248,80,80,80,80,5,7,7,6,0,254,
112,136,136,200,176,128,128,5,7,7,6,0,254,48,64,128,
64,48,8,112,5,5,5,6,0,0,104,144,144,144,96,4,
5,5,6,0,0,240,64,64,64,48,5,5,5,6,0,0,
136,136,144,144,224,5,8,8,6,0,254,48,168,168,168,168,
112,32,32,5,6,6,6,0,255,136,80,32,32,80,136,5,
7,7,6,0,254,168,168,168,168,112,32,32,5,5,5,6,
0,0,80,136,136,168,112,4,7,7,6,0,0,160,0,64,
64,64,64,48,5,7,7,6,0,0,80,0,136,136,144,144,
224,4,8,8,6,0,0,32,64,0,96,144,144,144,96,5,
8,8,6,0,0,32,64,0,136,136,144,144,96,5,8,8,
6,0,0,32,64,0,80,136,136,168,112,5,7,7,6,0,
255,144,160,192,160,144,136,16,5,8,8,6,0,0,96,144,
160,128,240,136,136,112,5,7,7,6,0,0,112,80,56,144,
144,144,96,5,6,6,6,0,0,152,80,32,32,32,32,5,
8,8,6,0,0,64,128,152,80,32,32,32,32,5,8,8,
6,0,0,80,0,152,80,32,32,32,32,5,7,7,6,0,
255,48,168,168,168,168,112,32,5,5,5,6,0,0,248,80,
80,80,88,5,6,6,6,0,255,136,80,112,80,136,16,5,
7,7,6,0,255,112,136,136,136,112,32,112,5,6,6,6,
0,255,112,136,136,112,32,112,5,6,6,6,0,0,112,136,
128,112,32,112,5,7,7,6,0,254,8,112,128,128,112,16,
96,5,6,6,6,0,0,248,128,128,240,128,128,4,5,5,
6,0,0,240,128,224,128,128,5,6,6,6,0,0,248,0,
0,112,0,248,4,5,5,6,0,0,64,128,240,16,32,5,
7,7,6,0,0,224,80,40,40,8,8,16,5,7,7,6,
0,0,192,32,80,40,8,8,8,5,8,8,6,0,254,168,
168,168,168,168,88,8,112,5,7,7,6,0,254,168,168,168,
168,88,8,112,5,6,6,6,0,0,104,136,136,120,8,8,
5,6,6,6,0,255,104,136,136,120,8,8,4,8,8,6,
0,254,128,224,144,144,144,144,32,192,5,5,5,6,0,0,
104,144,112,16,224,5,6,6,6,0,0,96,144,16,96,136,
112,4,6,6,6,0,0,96,144,16,96,128,112,5,6,6,
6,0,0,136,80,32,80,136,248,5,5,5,6,0,0,136,
80,32,80,112,5,6,6,6,0,0,120,128,240,136,136,112,
4,5,5,6,0,0,240,128,224,144,96,3,6,6,6,1,
0,64,224,64,64,64,64,3,6,6,6,1,255,64,224,64,
64,64,128,5,5,5,6,0,0,136,80,112,80,136,5,7,
7,6,0,254,112,136,136,136,240,128,112,4,5,5,6,0,
0,112,128,128,128,112,2,8,8,6,1,255,64,0,192,64,
64,64,64,128,5,7,7,6,0,0,112,136,136,248,136,136,
112,4,5,5,6,0,0,112,128,224,128,112,4,5,5,6,
0,0,224,16,112,16,224,5,7,7,6,0,0,128,240,136,
136,136,240,128,4,7,7,6,0,255,128,224,144,144,144,224,
128,5,6,6,6,0,0,112,136,128,128,136,112,5,6,6,
6,0,0,136,216,168,136,136,136,5,7,7,6,0,254,136,
216,168,136,136,128,128,5,8,8,6,0,254,112,136,136,136,
112,64,224,64,5,6,6,6,0,0,112,136,8,8,136,112,
5,6,6,6,0,0,112,136,160,128,136,112,5,6,6,6,
0,0,112,136,40,8,136,112};

View File

@@ -1,151 +0,0 @@
/*
Fontname: ISO10646_SK
Copyright: A. Hardtung, modified by Roman Moravcik
Capital A Height: 7, '1' Height: 7
Calculated Max Values w= 6 h= 9 x= 2 y= 7 dx= 6 dy= 0 ascent= 8 len= 9
Font Bounding box w= 6 h= 9 x= 0 y=-2
Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
X Font ascent = 7 descent=-1
Max Font ascent = 8 descent=-1
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_SK[2203] U8G_SECTION(".progmem.ISO10646_SK") = {
0,6,9,0,254,7,1,146,3,33,32,255,255,8,255,7,
255,0,0,0,6,0,0,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
0,0,112,136,136,136,136,136,112,3,7,7,6,1,0,64,
192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,1,
0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
32,64,128,248,3,7,7,6,1,0,224,128,128,128,128,128,
224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
1,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
6,0,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
6,0,2,104,144,0,0,0,6,0,0,5,8,8,6,0,
0,16,32,112,136,136,248,136,136,5,8,8,6,0,0,80,
0,112,136,136,248,136,136,5,8,8,6,0,0,8,16,248,
128,128,240,128,248,3,8,8,6,1,0,32,64,224,64,64,
64,64,224,5,8,8,6,0,0,16,32,112,136,136,136,136,
112,5,8,8,6,0,0,32,80,112,136,136,136,136,112,5,
8,8,6,0,0,16,32,136,136,136,136,136,112,5,8,8,
6,0,0,16,32,136,136,80,32,32,32,5,8,8,6,0,
0,16,32,0,112,8,120,136,120,5,7,7,6,0,0,80,
0,112,8,120,136,120,5,8,8,6,0,0,16,32,0,112,
136,248,128,112,2,8,8,6,2,0,64,128,0,128,128,128,
128,128,5,8,8,6,0,0,16,32,0,112,136,136,136,112,
5,8,8,6,0,0,32,80,0,112,136,136,136,112,5,8,
8,6,0,0,16,32,0,136,136,136,152,104,5,9,9,6,
0,255,16,32,0,136,136,136,120,8,112,5,8,8,6,0,
0,80,32,112,136,128,128,136,112,5,8,8,6,0,0,80,
32,0,112,128,128,136,112,5,8,8,6,0,0,80,32,240,
136,136,136,136,240,6,8,8,6,0,0,4,20,24,112,144,
144,144,112,5,8,8,6,0,0,16,32,128,128,128,128,128,
248,3,8,8,6,1,0,32,64,0,192,64,64,64,224,5,
8,8,6,0,0,16,144,160,128,128,128,128,248,5,8,8,
6,1,0,8,200,80,64,64,64,64,224,5,8,8,6,0,
0,80,32,136,200,168,152,136,136,5,8,8,6,0,0,80,
32,0,176,200,136,136,136,5,8,8,6,0,0,16,32,240,
136,240,160,144,136,5,8,8,6,0,0,16,32,0,176,200,
128,128,128,5,8,8,6,0,0,80,32,120,128,128,112,8,
240,5,8,8,6,0,0,80,32,0,112,128,112,8,240,5,
8,8,6,0,0,80,32,248,32,32,32,32,32,6,8,8,
6,0,0,4,68,72,224,64,64,64,48,5,8,8,6,0,
0,80,32,248,8,48,64,128,248,5,8,8,6,0,0,80,
32,0,248,16,32,64,248,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0,0,0,0,6,0,
0,0,0,0,6,0,0,0,0,0,6,0,0,0,0,0,
6,0,0,0,0,0,6,0,0,0,0,0,6,0,0,0,
0,0,6,0,0,0,0,0,6,0,0};

View File

@@ -1,304 +0,0 @@
/*
Fontname: ISO10646_ko_KR
Copyright: A. Hardtung, public domain
Korean Font : Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/) , NanumGothic, SIL OPEN FONT LICENSE
Capital A Height: 7, '1' Height: 7
Calculated Max Values w=12 h=11 x=12 y= 5 dx=13 dy= 0 ascent=10 len=22
Font Bounding box w=13 h=12 x= 0 y=-2
Calculated Min Values x= 0 y=-1 dx= 0 dy= 0
Pure Font ascent = 7 descent=-1
X Font ascent = 7 descent=-1
Max Font ascent =10 descent=-1
*/
#include <U8glib.h>
const u8g_fntpgm_uint8_t ISO10646_ko_KR[4639] U8G_SECTION(".progmem.ISO10646_ko_KR") = {
0,12,14,0,253,7,1,146,3,33,32,255,255,11,253,7,
255,0,0,0,6,5,255,1,7,7,6,2,0,128,128,128,
128,128,0,128,3,2,2,6,1,5,160,160,5,7,7,6,
0,0,80,80,248,80,248,80,80,5,7,7,6,0,0,32,
120,160,112,40,240,32,5,7,7,6,0,0,192,200,16,32,
64,152,24,5,7,7,6,0,0,96,144,160,64,168,144,104,
2,3,3,6,1,4,192,64,128,3,7,7,6,1,0,32,
64,128,128,128,64,32,3,7,7,6,1,0,128,64,32,32,
32,64,128,5,5,5,6,0,1,32,168,112,168,32,5,5,
5,6,0,1,32,32,248,32,32,2,3,3,6,2,255,192,
64,128,5,1,1,6,0,3,248,2,2,2,6,2,0,192,
192,5,5,5,6,0,1,8,16,32,64,128,5,7,7,6,
0,0,112,136,152,168,200,136,112,3,7,7,6,1,0,64,
192,64,64,64,64,224,5,7,7,6,0,0,112,136,8,112,
128,128,248,5,7,7,6,0,0,248,16,32,16,8,8,240,
5,7,7,6,0,0,16,48,80,144,248,16,16,5,7,7,
6,0,0,248,128,240,8,8,136,112,5,7,7,6,0,0,
112,128,128,240,136,136,112,5,7,7,6,0,0,248,8,16,
32,32,32,32,5,7,7,6,0,0,112,136,136,112,136,136,
112,5,7,7,6,0,0,112,136,136,120,8,8,112,2,5,
5,6,2,0,192,192,0,192,192,2,6,6,6,2,255,192,
192,0,192,64,128,4,7,7,6,0,0,16,32,64,128,64,
32,16,5,3,3,6,0,2,248,0,248,4,7,7,6,0,
0,128,64,32,16,32,64,128,5,7,7,6,0,0,112,136,
8,16,32,0,32,5,7,7,6,0,0,112,136,8,104,168,
168,112,5,7,7,6,0,0,112,136,136,248,136,136,136,5,
7,7,6,0,0,240,136,136,240,136,136,240,5,7,7,6,
0,0,112,136,128,128,128,136,112,5,7,7,6,0,0,240,
136,136,136,136,136,240,5,7,7,6,0,0,248,128,128,240,
128,128,248,5,7,7,6,0,0,248,128,128,240,128,128,128,
5,7,7,6,0,0,112,136,128,184,136,136,112,5,7,7,
6,0,0,136,136,136,248,136,136,136,1,7,7,6,2,0,
128,128,128,128,128,128,128,5,7,7,6,0,0,56,16,16,
16,16,144,96,5,7,7,6,0,0,136,144,160,192,160,144,
136,5,7,7,6,0,0,128,128,128,128,128,128,248,5,7,
7,6,0,0,136,216,168,136,136,136,136,5,7,7,6,0,
0,136,136,200,168,152,136,136,5,7,7,6,0,0,112,136,
136,136,136,136,112,5,7,7,6,0,0,240,136,136,240,128,
128,128,5,7,7,6,0,0,112,136,136,136,168,144,104,5,
7,7,6,0,0,240,136,136,240,160,144,136,5,7,7,6,
0,0,120,128,128,112,8,8,240,5,7,7,6,0,0,248,
32,32,32,32,32,32,5,7,7,6,0,0,136,136,136,136,
136,136,112,5,7,7,6,0,0,136,136,136,136,136,80,32,
5,7,7,6,0,0,136,136,136,136,136,168,80,5,7,7,
6,0,0,136,136,80,32,80,136,136,5,7,7,6,0,0,
136,136,136,80,32,32,32,5,7,7,6,0,0,248,8,16,
32,64,128,248,3,7,7,6,0,0,224,128,128,128,128,128,
224,5,5,5,6,0,1,128,64,32,16,8,3,7,7,6,
0,0,224,32,32,32,32,32,224,5,3,3,6,0,4,32,
80,136,5,1,1,6,0,0,248,2,2,2,6,2,5,128,
64,5,5,5,6,0,0,112,8,120,136,120,5,7,7,6,
0,0,128,128,176,200,136,136,240,5,5,5,6,0,0,112,
128,128,136,112,5,7,7,6,0,0,8,8,104,152,136,136,
120,5,5,5,6,0,0,112,136,248,128,112,5,7,7,6,
0,0,48,72,224,64,64,64,64,5,6,6,6,0,255,112,
136,136,120,8,112,5,7,7,6,0,0,128,128,176,200,136,
136,136,1,7,7,6,2,0,128,0,128,128,128,128,128,3,
8,8,6,1,255,32,0,32,32,32,32,160,64,4,7,7,
6,1,0,128,128,144,160,192,160,144,3,7,7,6,1,0,
192,64,64,64,64,64,224,5,5,5,6,0,0,208,168,168,
168,168,5,5,5,6,0,0,176,200,136,136,136,5,5,5,
6,0,0,112,136,136,136,112,5,6,6,6,0,255,240,136,
136,240,128,128,5,6,6,6,0,255,120,136,136,120,8,8,
5,5,5,6,0,0,176,200,128,128,128,5,5,5,6,0,
0,112,128,112,8,240,4,7,7,6,0,0,64,64,224,64,
64,64,48,5,5,5,6,0,0,136,136,136,152,104,5,5,
5,6,0,0,136,136,136,80,32,5,5,5,6,0,0,136,
136,168,168,80,5,5,5,6,0,0,136,80,32,80,136,5,
6,6,6,0,255,136,136,136,120,8,112,5,5,5,6,0,
0,248,16,32,64,248,3,7,7,6,1,0,32,64,64,128,
64,64,32,1,7,7,6,2,0,128,128,128,128,128,128,128,
3,7,7,6,1,0,128,64,64,32,64,64,128,5,2,2,
6,0,3,104,144,0,0,0,6,5,255,0,0,0,12,11,
255,0,0,0,12,11,255,10,12,24,12,1,255,0,128,248,
128,8,128,8,128,8,192,16,128,32,128,192,128,0,128,0,
128,0,128,0,128,11,12,24,12,1,255,248,128,8,128,8,
128,8,224,16,128,32,128,192,128,0,0,63,128,0,128,0,
128,0,128,11,12,24,12,1,255,248,128,8,128,8,128,8,
224,16,128,32,128,192,128,31,0,32,128,32,128,32,128,31,
0,9,11,22,12,1,0,2,128,250,128,10,128,10,128,10,
128,19,128,34,128,194,128,2,128,2,128,2,128,9,12,24,
12,1,255,0,128,252,128,4,128,4,128,5,128,8,128,16,
128,32,128,64,128,0,128,0,128,0,128,9,12,24,12,1,
255,252,128,4,128,4,128,9,128,16,128,32,128,192,128,31,
128,16,128,16,128,16,128,31,128,11,9,18,12,0,0,127,
192,0,64,0,64,0,64,4,64,4,64,4,0,4,0,255,
224,11,12,24,12,1,255,127,128,0,128,0,128,8,128,8,
128,255,224,0,0,31,0,32,128,32,128,32,128,31,0,12,
12,24,12,0,255,0,64,126,64,2,64,2,64,18,64,18,
112,18,64,16,64,255,64,0,64,0,64,0,64,11,9,18,
12,0,0,127,192,0,64,0,64,0,64,18,64,18,64,18,
0,18,0,255,224,10,12,24,12,1,255,127,128,0,128,0,
128,0,128,255,192,0,0,0,0,64,128,127,128,64,128,64,
128,127,128,9,12,24,12,1,255,0,128,252,128,4,128,4,
128,4,128,8,128,16,128,32,128,192,128,0,128,0,128,0,
128,10,12,24,12,1,255,130,64,130,64,130,64,131,192,130,
64,250,64,0,0,31,0,32,128,32,128,32,128,31,0,11,
9,18,12,0,0,32,0,32,0,32,0,32,0,63,192,4,
0,4,0,4,0,255,224,11,12,24,12,0,255,32,0,32,
0,32,0,32,0,63,192,0,0,255,224,4,0,4,0,4,
0,4,0,4,0,11,12,24,12,1,255,0,128,252,128,128,
128,128,128,128,128,128,224,128,128,254,128,0,128,0,128,0,
128,0,128,10,12,24,12,1,255,2,64,250,64,130,64,130,
64,130,64,131,192,130,64,250,64,2,64,2,64,2,64,2,
64,11,9,18,12,0,0,63,192,32,0,32,0,32,0,63,
192,4,0,4,0,4,0,255,224,11,12,24,12,0,255,63,
192,32,0,32,0,63,192,4,0,255,224,0,0,63,192,0,
64,63,192,32,0,63,192,11,12,24,12,0,255,127,192,64,
0,64,0,127,192,4,0,4,0,255,224,0,0,63,128,64,
64,64,64,63,128,9,12,24,12,1,255,0,128,254,128,128,
128,128,128,128,128,254,128,16,128,16,128,255,128,0,128,0,
128,0,128,11,9,18,12,0,0,63,192,32,0,32,0,32,
0,63,192,0,0,0,0,0,0,255,224,9,12,24,12,1,
255,252,128,128,128,128,128,128,128,128,128,252,128,0,128,31,
0,32,128,32,128,32,128,31,0,11,12,24,12,1,255,0,
128,252,128,4,128,4,128,252,128,128,224,128,128,128,128,252,
128,0,128,0,128,0,128,10,12,24,12,1,255,250,64,10,
64,10,64,251,192,130,64,130,64,250,64,0,0,63,192,0,
64,0,64,0,64,11,12,24,12,1,255,252,128,4,128,4,
224,252,128,128,224,252,128,0,128,31,0,32,128,32,128,32,
128,31,0,10,12,24,12,1,255,1,64,241,64,17,64,17,
64,247,64,129,64,129,64,129,64,241,64,1,64,1,64,1,
64,9,12,24,12,1,255,0,128,248,128,8,128,11,128,248,
128,128,128,131,128,128,128,252,128,0,128,0,128,0,128,9,
12,24,12,1,255,248,128,8,128,11,128,248,128,131,128,128,
128,248,128,0,0,63,128,0,128,0,128,0,128,11,10,20,
12,0,0,63,192,0,64,0,64,63,192,32,0,32,0,63,
192,4,0,4,0,255,224,11,10,20,12,0,0,63,192,0,
64,0,64,63,192,32,0,32,0,63,192,9,0,9,0,255,
224,11,10,20,12,0,0,63,192,0,64,0,64,63,192,32,
0,32,0,63,192,0,0,0,0,255,224,9,12,24,12,1,
255,0,128,252,128,4,128,4,128,252,128,128,128,128,128,128,
128,252,128,0,128,0,128,0,128,9,12,24,12,1,255,252,
128,4,128,4,128,252,128,128,128,128,128,252,128,0,128,32,
128,32,0,32,0,63,128,9,12,24,12,1,255,252,128,4,
128,4,128,252,128,128,128,252,128,0,128,31,0,32,128,32,
128,32,128,31,0,9,12,24,12,1,255,2,128,250,128,138,
128,138,128,142,128,138,128,138,128,250,128,2,128,2,128,2,
128,2,128,10,12,24,12,1,255,1,64,249,64,137,64,139,
64,137,64,249,64,1,64,1,64,33,64,32,0,32,0,63,
192,9,12,24,12,1,255,252,128,132,128,133,128,132,128,133,
128,252,128,0,128,0,128,32,0,32,0,32,0,63,128,11,
9,18,12,0,0,127,192,64,64,64,64,64,64,127,192,4,
0,4,0,4,0,255,224,9,12,24,12,1,255,132,128,132,
128,132,128,132,128,255,128,132,128,132,128,252,128,0,128,0,
128,0,128,0,128,10,12,24,12,1,255,1,64,137,64,137,
64,137,64,251,64,137,64,137,64,249,64,1,64,1,64,1,
64,1,64,9,12,24,12,1,255,138,128,138,128,250,128,142,
128,138,128,250,128,0,0,63,128,0,128,63,128,32,0,63,
128,11,10,20,12,0,1,32,64,32,64,63,192,32,64,32,
64,63,192,4,0,4,0,4,0,255,224,10,11,22,12,1,
0,64,128,64,128,127,128,64,128,127,128,0,0,255,192,8,
0,8,0,8,0,8,0,11,12,24,12,0,255,32,64,63,
192,32,64,32,64,63,192,0,0,255,224,2,0,34,0,32,
0,32,0,63,192,9,12,24,12,1,255,132,128,132,128,132,
128,132,128,252,128,132,128,132,128,252,128,0,128,0,128,0,
128,0,128,10,12,24,12,1,255,16,128,16,128,16,192,40,
128,68,128,130,128,0,0,64,128,127,128,64,128,64,128,127,
128,11,12,24,12,0,255,0,160,16,160,16,160,16,160,16,
160,16,224,40,160,68,160,130,160,0,160,0,160,0,160,10,
12,24,12,0,255,0,64,16,64,16,64,16,64,17,192,40,
64,68,64,130,64,0,64,0,64,0,64,0,64,10,12,24,
12,0,255,16,64,16,64,17,192,40,64,68,64,130,64,0,
0,31,192,0,64,31,192,16,0,31,192,11,12,24,12,0,
255,0,160,16,160,16,160,16,160,17,160,16,160,40,160,68,
160,130,160,0,160,0,160,0,160,11,12,24,12,0,255,16,
160,16,160,16,160,17,160,40,160,68,160,130,160,0,160,16,
160,16,0,16,0,31,224,10,12,24,12,1,255,1,64,33,
64,33,64,35,64,81,64,137,64,1,64,5,64,4,0,10,
0,17,0,32,128,11,10,20,12,0,0,4,0,4,0,4,
0,10,0,17,0,32,128,68,64,4,0,4,0,255,224,11,
12,24,12,0,255,4,0,4,0,10,0,17,0,36,128,4,
0,255,224,0,0,63,128,0,128,0,128,0,128,11,9,18,
12,0,0,4,0,4,0,10,0,17,0,32,128,64,64,128,
32,0,0,255,224,9,12,24,12,1,255,0,128,16,128,16,
128,16,128,16,128,40,128,68,128,130,128,0,128,0,128,0,
128,0,128,9,12,24,12,1,255,0,128,16,128,16,128,40,
128,68,128,130,128,0,0,63,128,0,128,63,128,32,0,63,
128,11,12,24,12,1,255,120,128,132,128,132,128,132,224,132,
128,120,128,0,0,64,128,127,128,64,128,64,128,127,128,9,
12,24,12,1,255,0,128,120,128,132,128,132,128,133,128,132,
128,132,128,132,128,120,128,0,128,0,128,0,128,10,12,24,
12,1,255,120,128,132,128,132,128,133,128,132,128,120,128,0,
128,72,0,121,0,73,0,74,128,124,64,9,12,24,12,1,
255,120,128,133,128,132,128,132,128,133,128,120,128,0,0,63,
128,0,128,63,128,32,0,63,128,10,12,24,12,1,255,1,
64,113,64,139,64,137,64,137,64,137,64,139,64,137,64,113,
64,1,64,1,64,1,64,11,9,18,12,0,0,31,0,32,
128,32,128,32,128,31,0,0,0,4,0,4,0,255,224,12,
12,24,12,0,255,31,128,32,64,32,64,32,64,31,128,4,
0,255,240,0,0,32,0,32,0,32,0,63,192,12,12,24,
12,0,255,60,64,66,64,66,64,66,64,60,112,16,64,255,
64,0,64,32,64,32,0,32,0,63,192,11,9,18,12,0,
0,31,128,32,64,32,64,32,64,31,128,0,0,16,128,16,
128,255,224,12,12,24,12,0,255,31,128,32,64,32,64,31,
128,0,0,17,0,255,240,0,0,31,128,32,64,32,64,31,
128,9,12,24,12,1,255,120,128,132,128,132,128,120,128,0,
128,255,128,16,128,23,128,16,128,64,0,64,0,127,128,10,
12,24,12,0,255,60,64,66,64,66,64,66,64,60,64,0,
64,255,192,8,64,8,64,8,64,8,64,8,64,12,9,18,
12,0,0,31,128,32,64,32,64,32,64,31,128,0,0,0,
0,0,0,255,240,12,12,24,12,0,255,31,128,32,64,32,
64,31,128,0,0,255,240,0,0,63,192,32,64,32,64,32,
64,63,192,10,12,24,12,0,255,0,64,60,64,66,64,66,
64,66,64,60,64,0,64,0,64,255,192,0,64,0,64,0,
64,9,12,24,12,1,255,0,128,120,128,132,128,132,128,132,
128,132,128,132,128,132,128,120,128,0,128,0,128,0,128,9,
12,24,12,1,255,120,128,132,128,132,128,132,128,132,128,120,
128,0,128,0,128,32,128,32,0,32,0,63,128,9,12,24,
12,1,255,120,128,132,128,132,128,132,128,132,128,120,128,0,
0,63,128,0,128,63,128,32,0,63,128,9,12,24,12,1,
255,120,128,132,128,132,128,132,128,132,128,120,128,0,0,32,
128,32,128,63,128,32,128,63,128,11,12,24,12,1,255,0,
128,248,128,8,128,8,128,16,128,40,224,68,128,130,128,0,
128,0,128,0,128,0,128,11,12,24,12,1,255,248,128,8,
128,8,128,16,224,40,128,198,128,0,128,127,0,0,128,0,
128,0,128,0,128,11,12,24,12,1,255,248,128,8,128,8,
128,16,224,40,128,198,128,0,0,31,0,32,128,32,128,32,
128,31,0,11,12,24,12,0,255,0,160,248,160,8,160,8,
160,16,160,40,224,68,160,130,160,0,160,0,160,0,160,0,
160,9,12,24,12,1,255,0,128,248,128,8,128,8,128,19,
128,40,128,68,128,130,128,0,128,0,128,0,128,0,128,9,
12,24,12,1,255,248,128,8,128,9,128,16,128,40,128,198,
128,0,0,63,128,0,128,0,128,0,128,0,128,9,12,24,
12,1,255,248,128,8,128,8,128,17,128,40,128,198,128,0,
128,0,128,32,0,32,0,32,0,63,128,9,12,24,12,1,
255,248,128,8,128,9,128,16,128,40,128,198,128,0,0,63,
128,0,128,63,128,32,0,63,128,9,12,24,12,1,255,248,
128,8,128,8,128,17,128,40,128,198,128,0,0,63,128,32,
128,32,128,32,128,63,128,9,12,24,12,1,255,248,128,8,
128,8,128,17,128,40,128,198,128,0,0,31,0,32,128,32,
128,32,128,31,0,11,12,24,12,0,255,0,160,248,160,8,
160,8,160,17,160,40,160,68,160,130,160,0,160,0,160,0,
160,0,160,11,12,24,12,0,255,63,128,4,0,10,0,17,
0,32,128,4,0,255,224,0,0,63,128,0,128,0,128,0,
128,11,12,24,12,0,255,127,192,4,0,10,0,17,0,96,
192,4,0,255,224,0,0,63,128,64,64,64,64,63,128,11,
12,24,12,0,255,0,64,127,64,8,64,28,64,34,64,65,
96,8,64,8,64,255,192,0,64,0,64,0,64,11,12,24,
10,0,255,127,192,4,0,10,0,17,0,96,192,0,0,255,
224,4,0,36,0,32,0,32,0,63,192,11,12,24,12,0,
255,63,128,4,0,10,0,49,128,0,0,255,224,4,0,0,
0,31,0,32,128,32,128,31,0,11,12,24,12,0,255,63,
128,4,0,10,0,49,128,0,0,255,224,0,0,63,128,0,
128,63,128,32,0,63,128,9,12,24,12,1,255,0,128,252,
128,4,128,8,128,16,128,40,128,68,128,130,128,0,128,0,
128,0,128,0,128,10,12,24,12,0,255,0,64,56,64,0,
64,254,64,16,192,40,64,68,64,130,64,0,64,0,64,0,
64,0,64,11,12,24,12,0,255,0,160,56,160,0,160,254,
160,16,160,41,160,68,160,130,160,0,160,0,160,0,160,0,
160,11,10,20,12,0,1,14,0,0,0,63,128,4,0,10,
0,17,0,96,192,4,0,4,0,255,224,11,12,24,12,0,
255,28,32,0,32,127,32,8,32,20,32,34,32,193,160,8,
32,255,224,0,32,0,32,0,32,11,12,24,12,0,255,14,
0,0,0,63,128,4,0,10,0,49,128,0,0,255,224,4,
0,63,128,0,128,0,128,11,12,24,12,0,255,4,0,63,
128,4,0,10,0,49,128,255,224,4,0,63,128,0,128,63,
128,32,0,63,128,11,12,24,12,0,255,4,0,63,128,4,
0,10,0,49,128,0,0,255,224,4,0,31,0,32,128,32,
128,31,0,10,12,24,12,0,255,28,64,0,64,127,64,8,
64,20,64,99,64,0,64,255,192,8,64,8,64,8,64,8,
64,11,12,24,12,0,255,28,32,0,32,127,32,8,32,20,
32,34,32,65,32,128,160,0,32,0,32,0,32,0,32,9,
12,24,12,1,255,56,128,0,128,254,128,16,128,40,128,68,
128,130,128,0,0,63,128,32,128,32,128,63,128,10,14,28,
12,1,253,0,128,248,128,8,128,8,128,248,192,16,128,32,
128,64,128,128,128,0,128,0,128,0,128,0,0,128,0,9,
12,24,12,1,255,0,128,248,128,128,128,128,128,251,128,128,
128,128,128,128,128,248,128,0,128,0,128,0,128,11,10,20,
12,0,0,63,192,32,0,32,0,63,192,32,0,32,0,63,
192,0,0,0,0,255,224,11,12,24,12,0,255,63,192,32,
0,63,192,32,0,63,192,0,0,255,224,0,0,32,0,32,
0,32,0,63,192,11,12,24,12,0,255,0,160,254,160,40,
160,40,160,40,224,40,160,40,160,254,160,0,160,0,160,0,
160,0,160,11,12,24,12,0,255,0,160,254,160,40,160,40,
224,40,160,254,160,0,160,0,160,16,160,16,0,16,0,31,
224,11,9,18,12,0,0,127,192,17,0,17,0,17,0,127,
192,0,0,4,0,4,0,255,224,11,9,18,12,0,0,127,
192,17,0,17,0,17,0,127,192,0,0,0,0,0,0,255,
224,9,12,24,12,1,255,252,128,72,128,72,128,72,128,72,
128,252,128,0,0,63,128,0,128,63,128,32,0,63,128,10,
12,24,12,1,255,56,128,0,128,254,128,0,128,124,128,130,
192,130,128,130,128,124,128,0,128,0,128,0,128,11,12,24,
12,0,255,14,0,63,128,0,0,31,0,32,128,31,0,4,
0,255,224,0,0,63,128,32,128,63,128,12,12,24,12,0,
255,28,64,0,64,127,64,0,64,62,64,65,112,62,64,0,
64,8,64,255,192,0,64,0,64,0,0,0,12,9,0,0,
0,0,12,10,0,0,0,0,12,10,2,0,0,0,12,10,
0,0,0,0,12,10,0,0,0,0,12,10,0,0,0,0,
12,10,0,0,0,0,12,10,0,0,0,0,12,10,0};

View File

@@ -1,73 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef _DRIVERS_H_
#define _DRIVERS_H_
#include "MarlinConfig.h"
#define A4988 0x001
#define DRV8825 0x002
#define LV8729 0x003
#define L6470 0x104
#define TB6560 0x005
#define TB6600 0x006
#define TMC2100 0x007
#define TMC2130 0x108
#define TMC2130_STANDALONE 0x008
#define TMC2208 0x109
#define TMC2208_STANDALONE 0x009
#define TMC26X 0x10A
#define TMC26X_STANDALONE 0x00A
#define TMC2660 0x10B
#define TMC2660_STANDALONE 0x00B
#define _AXIS_DRIVER_TYPE(A,T) ( defined(A##_DRIVER_TYPE) && (A##_DRIVER_TYPE == T) )
#define AXIS_DRIVER_TYPE_X(T) _AXIS_DRIVER_TYPE(X,T)
#define AXIS_DRIVER_TYPE_Y(T) _AXIS_DRIVER_TYPE(Y,T)
#define AXIS_DRIVER_TYPE_Z(T) _AXIS_DRIVER_TYPE(Z,T)
#define AXIS_DRIVER_TYPE_X2(T) (ENABLED(X_DUAL_STEPPER_DRIVERS) || ENABLED(DUAL_X_CARRIAGE)) && _AXIS_DRIVER_TYPE(X2,T)
#define AXIS_DRIVER_TYPE_Y2(T) (ENABLED(Y_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Y2,T))
#define AXIS_DRIVER_TYPE_Z2(T) (ENABLED(Z_DUAL_STEPPER_DRIVERS) && _AXIS_DRIVER_TYPE(Z2,T))
#define AXIS_DRIVER_TYPE_E0(T) (E_STEPPERS > 0 && _AXIS_DRIVER_TYPE(E0,T))
#define AXIS_DRIVER_TYPE_E1(T) (E_STEPPERS > 1 && _AXIS_DRIVER_TYPE(E1,T))
#define AXIS_DRIVER_TYPE_E2(T) (E_STEPPERS > 2 && _AXIS_DRIVER_TYPE(E2,T))
#define AXIS_DRIVER_TYPE_E3(T) (E_STEPPERS > 3 && _AXIS_DRIVER_TYPE(E3,T))
#define AXIS_DRIVER_TYPE_E4(T) (E_STEPPERS > 4 && _AXIS_DRIVER_TYPE(E4,T))
#define AXIS_DRIVER_TYPE(A,T) AXIS_DRIVER_TYPE_##A(T)
#define HAS_DRIVER(T) (AXIS_DRIVER_TYPE_X(T) || AXIS_DRIVER_TYPE_X2(T) || \
AXIS_DRIVER_TYPE_Y(T) || AXIS_DRIVER_TYPE_Y2(T) || \
AXIS_DRIVER_TYPE_Z(T) || AXIS_DRIVER_TYPE_Z2(T) || \
AXIS_DRIVER_TYPE_E0(T) || AXIS_DRIVER_TYPE_E1(T) || \
AXIS_DRIVER_TYPE_E2(T) || AXIS_DRIVER_TYPE_E3(T) || \
AXIS_DRIVER_TYPE_E4(T) )
// Test for supported TMC drivers that require advanced configuration
// Does not match standalone configurations
#define HAS_TRINAMIC (HAS_DRIVER(TMC2130) || HAS_DRIVER(TMC2208))
#define AXIS_IS_TMC(A) ( AXIS_DRIVER_TYPE_##A(TMC2130) || \
AXIS_DRIVER_TYPE_##A(TMC2208) )
#endif // _DRIVERS_H_

View File

@@ -23,9 +23,6 @@
#ifndef __DURATION_T__
#define __DURATION_T__
#include <stdio.h>
#include <inttypes.h>
struct duration_t {
/**
* @brief Duration is stored in seconds
@@ -144,26 +141,14 @@ struct duration_t {
* @param buffer The array pointed to must be able to accommodate 10 bytes
*
* Output examples:
* 123456789 (strlen)
* 99:59
* 11d 12:33
* 1234567890 (strlen)
* 1193046:59
*/
uint8_t toDigital(char *buffer, bool with_days=false) const {
uint16_t h = uint16_t(this->hour()),
m = uint16_t(this->minute() % 60UL);
if (with_days) {
uint16_t d = this->day();
sprintf_P(buffer, PSTR("%ud %02u:%02u"), d, h % 24, m);
return d >= 10 ? 9 : 8;
}
else if (h < 100) {
sprintf_P(buffer, PSTR("%02u:%02u"), h, m);
return 5;
}
else {
sprintf_P(buffer, PSTR("%u:%02u"), h, m);
return 6;
}
void toDigital(char *buffer) const {
int h = this->hour() % 24,
m = this->minute() % 60;
sprintf_P(buffer, PSTR("%02i:%02i"), h, m);
}
};

View File

@@ -1,144 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* emergency_parser.h - Intercept special commands directly in the serial stream
*/
#ifndef _EMERGENCY_PARSER_H_
#define _EMERGENCY_PARSER_H_
// External references
extern volatile bool wait_for_user, wait_for_heatup;
void quickstop_stepper();
class EmergencyParser {
public:
// Currently looking for: M108, M112, M410
enum State : char {
EP_RESET,
EP_N,
EP_M,
EP_M1,
EP_M10,
EP_M108,
EP_M11,
EP_M112,
EP_M4,
EP_M41,
EP_M410,
EP_IGNORE // to '\n'
};
static bool killed_by_M112;
static State state;
EmergencyParser() {}
__attribute__((always_inline)) inline
static void update(const uint8_t c) {
switch (state) {
case EP_RESET:
switch (c) {
case ' ': break;
case 'N': state = EP_N; break;
case 'M': state = EP_M; break;
default: state = EP_IGNORE;
}
break;
case EP_N:
switch (c) {
case '0': case '1': case '2':
case '3': case '4': case '5':
case '6': case '7': case '8':
case '9': case '-': case ' ': break;
case 'M': state = EP_M; break;
default: state = EP_IGNORE;
}
break;
case EP_M:
switch (c) {
case ' ': break;
case '1': state = EP_M1; break;
case '4': state = EP_M4; break;
default: state = EP_IGNORE;
}
break;
case EP_M1:
switch (c) {
case '0': state = EP_M10; break;
case '1': state = EP_M11; break;
default: state = EP_IGNORE;
}
break;
case EP_M10:
state = (c == '8') ? EP_M108 : EP_IGNORE;
break;
case EP_M11:
state = (c == '2') ? EP_M112 : EP_IGNORE;
break;
case EP_M4:
state = (c == '1') ? EP_M41 : EP_IGNORE;
break;
case EP_M41:
state = (c == '0') ? EP_M410 : EP_IGNORE;
break;
case EP_IGNORE:
if (c == '\n') state = EP_RESET;
break;
default:
if (c == '\n') {
switch (state) {
case EP_M108:
wait_for_user = wait_for_heatup = false;
break;
case EP_M112:
killed_by_M112 = true;
break;
case EP_M410:
quickstop_stepper();
break;
default:
break;
}
state = EP_RESET;
}
}
}
};
extern EmergencyParser emergency_parser;
#endif // _EMERGENCY_PARSER_H_

View File

@@ -1,239 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Endstop Interrupts
*
* Without endstop interrupts the endstop pins must be polled continually in
* the temperature-ISR via endstops.update(), most of the time finding no change.
* With this feature endstops.update() is called only when we know that at
* least one endstop has changed state, saving valuable CPU cycles.
*
* This feature only works when all used endstop pins can generate either an
* 'external interrupt' or a 'pin change interrupt'.
*
* Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'.
* (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino)
*/
#ifndef _ENDSTOP_INTERRUPTS_H_
#define _ENDSTOP_INTERRUPTS_H_
#include "macros.h"
// One ISR for all EXT-Interrupts
void endstop_ISR(void) { endstops.update(); }
/**
* Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)
*
* These macros for the Arduino MEGA do not include the two connected pins on Port J (D13, D14).
* So we extend them here because these are the normal pins for Y_MIN and Y_MAX on RAMPS.
* There are more PCI-enabled processor pins on Port J, but they are not connected to Arduino MEGA.
*/
#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA)
#undef digitalPinToPCICR
#define digitalPinToPCICR(p) ( WITHIN(p, 10, 15) || \
WITHIN(p, 50, 53) || \
WITHIN(p, 62, 69) ? &PCICR : (uint8_t*)0 )
#undef digitalPinToPCICRbit
#define digitalPinToPCICRbit(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \
WITHIN(p, 14, 15) ? 1 : \
WITHIN(p, 62, 69) ? 2 : \
0 )
#undef digitalPinToPCMSK
#define digitalPinToPCMSK(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? &PCMSK0 : \
WITHIN(p, 14, 15) ? &PCMSK1 : \
WITHIN(p, 62, 69) ? &PCMSK2 : \
(uint8_t *)0 )
#undef digitalPinToPCMSKbit
#define digitalPinToPCMSKbit(p) ( WITHIN(p, 10, 13) ? ((p) - 6) : \
(p) == 14 || (p) == 51 ? 2 : \
(p) == 15 || (p) == 52 ? 1 : \
(p) == 50 ? 3 : \
(p) == 53 ? 0 : \
WITHIN(p, 62, 69) ? ((p) - 62) : \
0 )
#endif
// Install Pin change interrupt for a pin. Can be called multiple times.
void pciSetup(const int8_t pin) {
SBI(*digitalPinToPCMSK(pin), digitalPinToPCMSKbit(pin)); // enable pin
SBI(PCIFR, digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group
}
// Handlers for pin change interrupts
#ifdef PCINT0_vect
ISR(PCINT0_vect) { endstop_ISR(); }
#endif
#ifdef PCINT1_vect
ISR(PCINT1_vect) { endstop_ISR(); }
#endif
#ifdef PCINT2_vect
ISR(PCINT2_vect) { endstop_ISR(); }
#endif
#ifdef PCINT3_vect
ISR(PCINT3_vect) { endstop_ISR(); }
#endif
void setup_endstop_interrupts( void ) {
#if HAS_X_MAX
#if digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT // if pin has an external interrupt
attachInterrupt(digitalPinToInterrupt(X_MAX_PIN), endstop_ISR, CHANGE); // assign it
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(X_MAX_PIN) != NULL, "X_MAX_PIN is not interrupt-capable"); // if pin has no pin change interrupt - error
pciSetup(X_MAX_PIN); // assign it
#endif
#endif
#if HAS_X_MIN
#if digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(X_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(X_MIN_PIN) != NULL, "X_MIN_PIN is not interrupt-capable");
pciSetup(X_MIN_PIN);
#endif
#endif
#if HAS_Y_MAX
#if digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Y_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Y_MAX_PIN) != NULL, "Y_MAX_PIN is not interrupt-capable");
pciSetup(Y_MAX_PIN);
#endif
#endif
#if HAS_Y_MIN
#if digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Y_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Y_MIN_PIN) != NULL, "Y_MIN_PIN is not interrupt-capable");
pciSetup(Y_MIN_PIN);
#endif
#endif
#if HAS_Z_MAX
#if digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Z_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z_MAX_PIN) != NULL, "Z_MAX_PIN is not interrupt-capable");
pciSetup(Z_MAX_PIN);
#endif
#endif
#if HAS_Z_MIN
#if digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Z_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z_MIN_PIN) != NULL, "Z_MIN_PIN is not interrupt-capable");
pciSetup(Z_MIN_PIN);
#endif
#endif
#if HAS_X2_MAX
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(X2_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(X2_MAX_PIN) != NULL, "X2_MAX_PIN is not interrupt-capable");
pciSetup(X2_MAX_PIN);
#endif
#endif
#if HAS_X2_MIN
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(X2_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(X2_MIN_PIN) != NULL, "X2_MIN_PIN is not interrupt-capable");
pciSetup(X2_MIN_PIN);
#endif
#endif
#if HAS_Y2_MAX
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Y2_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Y2_MAX_PIN) != NULL, "Y2_MAX_PIN is not interrupt-capable");
pciSetup(Y2_MAX_PIN);
#endif
#endif
#if HAS_Y2_MIN
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
attachInterrupt(digitalPinToInterrupt(Y2_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Y2_MIN_PIN) != NULL, "Y2_MIN_PIN is not interrupt-capable");
pciSetup(Y2_MIN_PIN);
#endif
#endif
#if HAS_Z2_MAX
#if digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Z2_MAX_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z2_MAX_PIN) != NULL, "Z2_MAX_PIN is not interrupt-capable");
pciSetup(Z2_MAX_PIN);
#endif
#endif
#if HAS_Z2_MIN
#if digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Z2_MIN_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z2_MIN_PIN) != NULL, "Z2_MIN_PIN is not interrupt-capable");
pciSetup(Z2_MIN_PIN);
#endif
#endif
#if HAS_Z_MIN_PROBE_PIN
#if digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT
attachInterrupt(digitalPinToInterrupt(Z_MIN_PROBE_PIN), endstop_ISR, CHANGE);
#else
// Not all used endstop/probe -pins can raise interrupts. Please deactivate ENDSTOP_INTERRUPTS or change the pin configuration!
static_assert(digitalPinToPCICR(Z_MIN_PROBE_PIN) != NULL, "Z_MIN_PROBE_PIN is not interrupt-capable");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
}
#endif // _ENDSTOP_INTERRUPTS_H_

View File

@@ -31,39 +31,35 @@
#include "stepper.h"
#include "ultralcd.h"
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
#include "endstop_interrupts.h"
#endif
// TEST_ENDSTOP: test the old and the current status of an endstop
#define TEST_ENDSTOP(ENDSTOP) (TEST(current_endstop_bits & old_endstop_bits, ENDSTOP))
Endstops endstops;
// public:
bool Endstops::enabled, Endstops::enabled_globally; // Initialized by settings.load()
volatile uint8_t Endstops::hit_state;
bool Endstops::enabled = true,
Endstops::enabled_globally =
#if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
(true)
#else
(false)
#endif
;
volatile char Endstops::endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value
Endstops::esbits_t Endstops::live_state = 0;
#if ENABLED(ENDSTOP_NOISE_FILTER)
Endstops::esbits_t Endstops::validated_live_state;
uint8_t Endstops::endstop_poll_count;
#if ENABLED(Z_DUAL_ENDSTOPS)
uint16_t
#else
byte
#endif
Endstops::current_endstop_bits = 0,
Endstops::old_endstop_bits = 0;
#if HAS_BED_PROBE
volatile bool Endstops::z_probe_enabled = false;
#endif
// Initialized by settings.load()
#if ENABLED(X_DUAL_ENDSTOPS)
float Endstops::x_endstop_adj;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
float Endstops::y_endstop_adj;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
float Endstops::z_endstop_adj;
#endif
/**
* Class and Instance Methods
*/
@@ -71,196 +67,72 @@ Endstops::esbits_t Endstops::live_state = 0;
void Endstops::init() {
#if HAS_X_MIN
SET_INPUT(X_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_XMIN)
SET_INPUT_PULLUP(X_MIN_PIN);
#else
SET_INPUT(X_MIN_PIN);
#endif
#endif
#if HAS_X2_MIN
#if ENABLED(ENDSTOPPULLUP_XMIN)
SET_INPUT_PULLUP(X2_MIN_PIN);
#else
SET_INPUT(X2_MIN_PIN);
WRITE(X_MIN_PIN,HIGH);
#endif
#endif
#if HAS_Y_MIN
SET_INPUT(Y_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_YMIN)
SET_INPUT_PULLUP(Y_MIN_PIN);
#else
SET_INPUT(Y_MIN_PIN);
#endif
#endif
#if HAS_Y2_MIN
#if ENABLED(ENDSTOPPULLUP_YMIN)
SET_INPUT_PULLUP(Y2_MIN_PIN);
#else
SET_INPUT(Y2_MIN_PIN);
WRITE(Y_MIN_PIN,HIGH);
#endif
#endif
#if HAS_Z_MIN
SET_INPUT(Z_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z_MIN_PIN);
#else
SET_INPUT(Z_MIN_PIN);
WRITE(Z_MIN_PIN,HIGH);
#endif
#endif
#if HAS_Z2_MIN
SET_INPUT(Z2_MIN_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMIN)
SET_INPUT_PULLUP(Z2_MIN_PIN);
#else
SET_INPUT(Z2_MIN_PIN);
WRITE(Z2_MIN_PIN,HIGH);
#endif
#endif
#if HAS_X_MAX
SET_INPUT(X_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_XMAX)
SET_INPUT_PULLUP(X_MAX_PIN);
#else
SET_INPUT(X_MAX_PIN);
#endif
#endif
#if HAS_X2_MAX
#if ENABLED(ENDSTOPPULLUP_XMAX)
SET_INPUT_PULLUP(X2_MAX_PIN);
#else
SET_INPUT(X2_MAX_PIN);
WRITE(X_MAX_PIN,HIGH);
#endif
#endif
#if HAS_Y_MAX
SET_INPUT(Y_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_YMAX)
SET_INPUT_PULLUP(Y_MAX_PIN);
#else
SET_INPUT(Y_MAX_PIN);
#endif
#endif
#if HAS_Y2_MAX
#if ENABLED(ENDSTOPPULLUP_YMAX)
SET_INPUT_PULLUP(Y2_MAX_PIN);
#else
SET_INPUT(Y2_MAX_PIN);
WRITE(Y_MAX_PIN,HIGH);
#endif
#endif
#if HAS_Z_MAX
SET_INPUT(Z_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z_MAX_PIN);
#else
SET_INPUT(Z_MAX_PIN);
WRITE(Z_MAX_PIN,HIGH);
#endif
#endif
#if HAS_Z2_MAX
SET_INPUT(Z2_MAX_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMAX)
SET_INPUT_PULLUP(Z2_MAX_PIN);
#else
SET_INPUT(Z2_MAX_PIN);
WRITE(Z2_MAX_PIN,HIGH);
#endif
#endif
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
#if HAS_Z_MIN_PROBE_PIN && ENABLED(Z_MIN_PROBE_ENDSTOP) // Check for Z_MIN_PROBE_ENDSTOP so we don't pull a pin high unless it's to be used.
SET_INPUT(Z_MIN_PROBE_PIN);
#if ENABLED(ENDSTOPPULLUP_ZMIN_PROBE)
SET_INPUT_PULLUP(Z_MIN_PROBE_PIN);
#else
SET_INPUT(Z_MIN_PROBE_PIN);
WRITE(Z_MIN_PROBE_PIN,HIGH);
#endif
#endif
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
setup_endstop_interrupts();
#endif
// Enable endstops
enable_globally(
#if ENABLED(ENDSTOPS_ALWAYS_ON_DEFAULT)
true
#else
false
#endif
);
} // Endstops::init
// Called at ~1KHz from Temperature ISR: Poll endstop state if required
void Endstops::poll() {
#if ENABLED(PINS_DEBUGGING)
run_monitor(); // report changes in endstop status
#endif
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE) && ENABLED(ENDSTOP_NOISE_FILTER)
if (endstop_poll_count) update();
#elif DISABLED(ENDSTOP_INTERRUPTS_FEATURE) || ENABLED(ENDSTOP_NOISE_FILTER)
update();
#endif
}
void Endstops::enable_globally(const bool onoff) {
enabled_globally = enabled = onoff;
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
update();
#endif
}
// Enable / disable endstop checking
void Endstops::enable(const bool onoff) {
enabled = onoff;
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
update();
#endif
}
// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
void Endstops::not_homing() {
enabled = enabled_globally;
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
update();
#endif
}
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
void Endstops::validate_homing_move() {
if (trigger_state()) hit_on_purpose();
else kill(PSTR(MSG_ERR_HOMING_FAILED));
}
#endif
// Enable / disable endstop z-probe checking
#if HAS_BED_PROBE
void Endstops::enable_z_probe(const bool onoff) {
z_probe_enabled = onoff;
#if ENABLED(ENDSTOP_INTERRUPTS_FEATURE)
update();
#endif
}
#endif
#if ENABLED(PINS_DEBUGGING)
void Endstops::run_monitor() {
if (!monitor_flag) return;
static uint8_t monitor_count = 16; // offset this check from the others
monitor_count += _BV(1); // 15 Hz
monitor_count &= 0x7F;
if (!monitor_count) monitor(); // report changes in endstop status
}
#endif
void Endstops::event_handler() {
static uint8_t prev_hit_state; // = 0
if (hit_state && hit_state != prev_hit_state) {
void Endstops::report_state() {
if (endstop_hit_bits) {
#if ENABLED(ULTRA_LCD)
char chrX = ' ', chrY = ' ', chrZ = ' ', chrP = ' ';
#define _SET_STOP_CHAR(A,C) (chr## A = C)
@@ -269,35 +141,35 @@ void Endstops::event_handler() {
#endif
#define _ENDSTOP_HIT_ECHO(A,C) do{ \
SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", planner.triggered_position_mm(_AXIS(A))); \
SERIAL_ECHOPAIR(" " STRINGIFY(A) ":", stepper.triggered_position_mm(A ##_AXIS)); \
_SET_STOP_CHAR(A,C); }while(0)
#define _ENDSTOP_HIT_TEST(A,C) \
if (TEST(hit_state, A ##_MIN) || TEST(hit_state, A ##_MAX)) \
if (TEST(endstop_hit_bits, A ##_MIN) || TEST(endstop_hit_bits, A ##_MAX)) \
_ENDSTOP_HIT_ECHO(A,C)
#define ENDSTOP_HIT_TEST_X() _ENDSTOP_HIT_TEST(X,'X')
#define ENDSTOP_HIT_TEST_Y() _ENDSTOP_HIT_TEST(Y,'Y')
#define ENDSTOP_HIT_TEST_Z() _ENDSTOP_HIT_TEST(Z,'Z')
SERIAL_ECHO_START();
SERIAL_ECHO_START;
SERIAL_ECHOPGM(MSG_ENDSTOPS_HIT);
ENDSTOP_HIT_TEST_X();
ENDSTOP_HIT_TEST_Y();
ENDSTOP_HIT_TEST_Z();
_ENDSTOP_HIT_TEST(X, 'X');
_ENDSTOP_HIT_TEST(Y, 'Y');
_ENDSTOP_HIT_TEST(Z, 'Z');
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
#define P_AXIS Z_AXIS
if (TEST(hit_state, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P');
if (TEST(endstop_hit_bits, Z_MIN_PROBE)) _ENDSTOP_HIT_ECHO(P, 'P');
#endif
SERIAL_EOL();
SERIAL_EOL;
#if ENABLED(ULTRA_LCD)
lcd_status_printf_P(0, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP);
char msg[3 * strlen(MSG_LCD_ENDSTOPS) + 8 + 1]; // Room for a UTF 8 string
sprintf_P(msg, PSTR(MSG_LCD_ENDSTOPS " %c %c %c %c"), chrX, chrY, chrZ, chrP);
lcd_setstatus(msg);
#endif
hit_on_purpose();
#if ENABLED(ABORT_ON_ENDSTOP_HIT_FEATURE_ENABLED) && ENABLED(SDSUPPORT)
if (planner.abort_on_endstop_hit) {
if (stepper.abort_on_endstop_hit) {
card.sdprinting = false;
card.closefile();
quickstop_stepper();
@@ -305,478 +177,202 @@ void Endstops::event_handler() {
}
#endif
}
prev_hit_state = hit_state;
} // Endstops::report_state
static void print_es_state(const bool is_hit, const char * const label=NULL) {
if (label) serialprintPGM(label);
SERIAL_PROTOCOLPGM(": ");
serialprintPGM(is_hit ? PSTR(MSG_ENDSTOP_HIT) : PSTR(MSG_ENDSTOP_OPEN));
SERIAL_EOL();
}
void _O2 Endstops::M119() {
#if ENABLED(BLTOUCH)
extern void _bltouch_set_SW_mode();
_bltouch_set_SW_mode();
#endif
void Endstops::M119() {
SERIAL_PROTOCOLLNPGM(MSG_M119_REPORT);
#define ES_REPORT(S) print_es_state(READ(S##_PIN) != S##_ENDSTOP_INVERTING, PSTR(MSG_##S))
#if HAS_X_MIN
ES_REPORT(X_MIN);
#endif
#if HAS_X2_MIN
ES_REPORT(X2_MIN);
SERIAL_PROTOCOLPGM(MSG_X_MIN);
SERIAL_PROTOCOLLN(((READ(X_MIN_PIN)^X_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if HAS_X_MAX
ES_REPORT(X_MAX);
#endif
#if HAS_X2_MAX
ES_REPORT(X2_MAX);
SERIAL_PROTOCOLPGM(MSG_X_MAX);
SERIAL_PROTOCOLLN(((READ(X_MAX_PIN)^X_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if HAS_Y_MIN
ES_REPORT(Y_MIN);
#endif
#if HAS_Y2_MIN
ES_REPORT(Y2_MIN);
SERIAL_PROTOCOLPGM(MSG_Y_MIN);
SERIAL_PROTOCOLLN(((READ(Y_MIN_PIN)^Y_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if HAS_Y_MAX
ES_REPORT(Y_MAX);
#endif
#if HAS_Y2_MAX
ES_REPORT(Y2_MAX);
SERIAL_PROTOCOLPGM(MSG_Y_MAX);
SERIAL_PROTOCOLLN(((READ(Y_MAX_PIN)^Y_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if HAS_Z_MIN
ES_REPORT(Z_MIN);
#endif
#if HAS_Z2_MIN
ES_REPORT(Z2_MIN);
SERIAL_PROTOCOLPGM(MSG_Z_MIN);
SERIAL_PROTOCOLLN(((READ(Z_MIN_PIN)^Z_MIN_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if HAS_Z_MAX
ES_REPORT(Z_MAX);
SERIAL_PROTOCOLPGM(MSG_Z_MAX);
SERIAL_PROTOCOLLN(((READ(Z_MAX_PIN)^Z_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if HAS_Z2_MAX
ES_REPORT(Z2_MAX);
SERIAL_PROTOCOLPGM(MSG_Z2_MAX);
SERIAL_PROTOCOLLN(((READ(Z2_MAX_PIN)^Z2_MAX_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
print_es_state(READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING, PSTR(MSG_Z_PROBE));
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#if NUM_RUNOUT_SENSORS == 1
print_es_state(READ(FIL_RUNOUT_PIN) != FIL_RUNOUT_INVERTING, PSTR(MSG_FILAMENT_RUNOUT_SENSOR));
#else
for (uint8_t i = 1; i <= NUM_RUNOUT_SENSORS; i++) {
pin_t pin;
switch (i) {
default: continue;
case 1: pin = FIL_RUNOUT_PIN; break;
case 2: pin = FIL_RUNOUT2_PIN; break;
#if NUM_RUNOUT_SENSORS > 2
case 3: pin = FIL_RUNOUT3_PIN; break;
#if NUM_RUNOUT_SENSORS > 3
case 4: pin = FIL_RUNOUT4_PIN; break;
#if NUM_RUNOUT_SENSORS > 4
case 5: pin = FIL_RUNOUT5_PIN; break;
#endif
#endif
#endif
}
SERIAL_PROTOCOLPGM(MSG_FILAMENT_RUNOUT_SENSOR);
if (i > 1) { SERIAL_CHAR(' '); SERIAL_CHAR('0' + i); }
print_es_state(digitalRead(pin) != FIL_RUNOUT_INVERTING);
}
#endif
#endif
#if ENABLED(BLTOUCH)
extern void _bltouch_reset_SW_mode();
_bltouch_reset_SW_mode();
#if HAS_Z_MIN_PROBE_PIN
SERIAL_PROTOCOLPGM(MSG_Z_PROBE);
SERIAL_PROTOCOLLN(((READ(Z_MIN_PROBE_PIN)^Z_MIN_PROBE_ENDSTOP_INVERTING) ? MSG_ENDSTOP_HIT : MSG_ENDSTOP_OPEN));
#endif
} // Endstops::M119
// The following routines are called from an ISR context. It could be the temperature ISR, the
// endstop ISR or the Stepper ISR.
#if ENABLED(Z_DUAL_ENDSTOPS)
#define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
// Pass the result of the endstop test
void Endstops::test_dual_z_endstops(EndstopEnum es1, EndstopEnum es2) {
byte z_test = TEST_ENDSTOP(es1) | (TEST_ENDSTOP(es2) << 1); // bit 0 for Z, bit 1 for Z2
if (stepper.current_block->steps[Z_AXIS] > 0) {
stepper.endstop_triggered(Z_AXIS);
SBI(endstop_hit_bits, Z_MIN);
if (!stepper.performing_homing || (z_test == 0x3)) //if not performing home or if both endstops were trigged during homing...
stepper.kill_current_block();
}
}
// Check endstops - Could be called from Temperature ISR!
#endif
// Check endstops - Called from ISR!
void Endstops::update() {
#if DISABLED(ENDSTOP_NOISE_FILTER)
if (!abort_enabled()) return;
#endif
#define _ENDSTOP_PIN(AXIS, MINMAX) AXIS ##_## MINMAX ##_PIN
#define _ENDSTOP_INVERTING(AXIS, MINMAX) AXIS ##_## MINMAX ##_ENDSTOP_INVERTING
#define _ENDSTOP_HIT(AXIS) SBI(endstop_hit_bits, _ENDSTOP(AXIS, MIN))
#define _ENDSTOP(AXIS, MINMAX) AXIS ##_## MINMAX
#define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT_TO(live_state, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
#define COPY_LIVE_STATE(SRC_BIT, DST_BIT) SET_BIT_TO(live_state, DST_BIT, TEST(live_state, SRC_BIT))
// UPDATE_ENDSTOP_BIT: set the current endstop bits for an endstop to its status
#define UPDATE_ENDSTOP_BIT(AXIS, MINMAX) SET_BIT(current_endstop_bits, _ENDSTOP(AXIS, MINMAX), (READ(_ENDSTOP_PIN(AXIS, MINMAX)) != _ENDSTOP_INVERTING(AXIS, MINMAX)))
// COPY_BIT: copy the value of COPY_BIT to BIT in bits
#define COPY_BIT(bits, COPY_BIT, BIT) SET_BIT(bits, BIT, TEST(bits, COPY_BIT))
#if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ)
// If G38 command is active check Z_MIN_PROBE for ALL movement
if (G38_move) UPDATE_ENDSTOP_BIT(Z, MIN_PROBE);
#endif
#define UPDATE_ENDSTOP(AXIS,MINMAX) do { \
UPDATE_ENDSTOP_BIT(AXIS, MINMAX); \
if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX)) && stepper.current_block->steps[_AXIS(AXIS)] > 0) { \
_ENDSTOP_HIT(AXIS); \
stepper.endstop_triggered(_AXIS(AXIS)); \
} \
} while(0)
// With Dual X, endstops are only checked in the homing direction for the active extruder
#if ENABLED(DUAL_X_CARRIAGE)
#define E0_ACTIVE stepper.movement_extruder() == 0
#define X_MIN_TEST ((X_HOME_DIR < 0 && E0_ACTIVE) || (X2_HOME_DIR < 0 && !E0_ACTIVE))
#define X_MAX_TEST ((X_HOME_DIR > 0 && E0_ACTIVE) || (X2_HOME_DIR > 0 && !E0_ACTIVE))
#if ENABLED(COREXY) || ENABLED(COREXZ)
// Head direction in -X axis for CoreXY and CoreXZ bots.
// If DeltaA == -DeltaB, the movement is only in Y or Z axis
if ((stepper.current_block->steps[CORE_AXIS_1] != stepper.current_block->steps[CORE_AXIS_2]) || (stepper.motor_direction(CORE_AXIS_1) == stepper.motor_direction(CORE_AXIS_2))) {
if (stepper.motor_direction(X_HEAD))
#else
#define X_MIN_TEST true
#define X_MAX_TEST true
if (stepper.motor_direction(X_AXIS)) // stepping along -X axis (regular Cartesian bot)
#endif
// Use HEAD for core axes, AXIS for others
#if CORE_IS_XY || CORE_IS_XZ
#define X_AXIS_HEAD X_HEAD
#else
#define X_AXIS_HEAD X_AXIS
#endif
#if CORE_IS_XY || CORE_IS_YZ
#define Y_AXIS_HEAD Y_HEAD
#else
#define Y_AXIS_HEAD Y_AXIS
#endif
#if CORE_IS_XZ || CORE_IS_YZ
#define Z_AXIS_HEAD Z_HEAD
#else
#define Z_AXIS_HEAD Z_AXIS
#endif
/**
* Check and update endstops
*/
#if HAS_X_MIN
#if ENABLED(X_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(X, MIN);
#if HAS_X2_MIN
UPDATE_ENDSTOP_BIT(X2, MIN);
#else
COPY_LIVE_STATE(X_MIN, X2_MIN);
#endif
#else
UPDATE_ENDSTOP_BIT(X, MIN);
#endif
#endif
#if HAS_X_MAX
#if ENABLED(X_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(X, MAX);
#if HAS_X2_MAX
UPDATE_ENDSTOP_BIT(X2, MAX);
#else
COPY_LIVE_STATE(X_MAX, X2_MAX);
#endif
#else
UPDATE_ENDSTOP_BIT(X, MAX);
#endif
#endif
#if HAS_Y_MIN
#if ENABLED(Y_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Y, MIN);
#if HAS_Y2_MIN
UPDATE_ENDSTOP_BIT(Y2, MIN);
#else
COPY_LIVE_STATE(Y_MIN, Y2_MIN);
#endif
#else
UPDATE_ENDSTOP_BIT(Y, MIN);
#endif
#endif
#if HAS_Y_MAX
#if ENABLED(Y_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Y, MAX);
#if HAS_Y2_MAX
UPDATE_ENDSTOP_BIT(Y2, MAX);
#else
COPY_LIVE_STATE(Y_MAX, Y2_MAX);
#endif
#else
UPDATE_ENDSTOP_BIT(Y, MAX);
#endif
#endif
#if HAS_Z_MIN
#if ENABLED(Z_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MIN);
#if HAS_Z2_MIN
UPDATE_ENDSTOP_BIT(Z2, MIN);
#else
COPY_LIVE_STATE(Z_MIN, Z2_MIN);
#endif
#elif ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
UPDATE_ENDSTOP_BIT(Z, MIN);
#elif Z_HOME_DIR < 0
UPDATE_ENDSTOP_BIT(Z, MIN);
#endif
#endif
// When closing the gap check the enabled probe
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
UPDATE_ENDSTOP_BIT(Z, MIN_PROBE);
#endif
#if HAS_Z_MAX
// Check both Z dual endstops
#if ENABLED(Z_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MAX);
#if HAS_Z2_MAX
UPDATE_ENDSTOP_BIT(Z2, MAX);
#else
COPY_LIVE_STATE(Z_MAX, Z2_MAX);
#endif
#elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
// If this pin isn't the bed probe it's the Z endstop
UPDATE_ENDSTOP_BIT(Z, MAX);
#endif
#endif
#if ENABLED(ENDSTOP_NOISE_FILTER)
/**
* Filtering out noise on endstops requires a delayed decision. Let's assume, due to noise,
* that 50% of endstop signal samples are good and 50% are bad (assuming normal distribution
* of random noise). Then the first sample has a 50% chance to be good or bad. The 2nd sample
* also has a 50% chance to be good or bad. The chances of 2 samples both being bad becomes
* 50% of 50%, or 25%. That was the previous implementation of Marlin endstop handling. It
* reduces chances of bad readings in half, at the cost of 1 extra sample period, but chances
* still exist. The only way to reduce them further is to increase the number of samples.
* To reduce the chance to 1% (1/128th) requires 7 samples (adding 7ms of delay).
*/
static esbits_t old_live_state;
if (old_live_state != live_state) {
endstop_poll_count = 7;
old_live_state = live_state;
}
else if (endstop_poll_count && !--endstop_poll_count)
validated_live_state = live_state;
if (!abort_enabled()) return;
#endif
// Test the current status of an endstop
#define TEST_ENDSTOP(ENDSTOP) (TEST(state(), ENDSTOP))
// Record endstop was hit
#define _ENDSTOP_HIT(AXIS, MINMAX) SBI(hit_state, _ENDSTOP(AXIS, MINMAX))
// Call the endstop triggered routine for single endstops
#define PROCESS_ENDSTOP(AXIS,MINMAX) do { \
if (TEST_ENDSTOP(_ENDSTOP(AXIS, MINMAX))) { \
_ENDSTOP_HIT(AXIS, MINMAX); \
planner.endstop_triggered(_AXIS(AXIS)); \
} \
}while(0)
// Call the endstop triggered routine for dual endstops
#define PROCESS_DUAL_ENDSTOP(AXIS1, AXIS2, MINMAX) do { \
const byte dual_hit = TEST_ENDSTOP(_ENDSTOP(AXIS1, MINMAX)) | (TEST_ENDSTOP(_ENDSTOP(AXIS2, MINMAX)) << 1); \
if (dual_hit) { \
_ENDSTOP_HIT(AXIS1, MINMAX); \
/* if not performing home or if both endstops were trigged during homing... */ \
if (!stepper.homing_dual_axis || dual_hit == 0b11) \
planner.endstop_triggered(_AXIS(AXIS1)); \
} \
}while(0)
#if ENABLED(G38_PROBE_TARGET) && PIN_EXISTS(Z_MIN_PROBE) && !(CORE_IS_XY || CORE_IS_XZ)
// If G38 command is active check Z_MIN_PROBE for ALL movement
if (G38_move) {
if (TEST_ENDSTOP(_ENDSTOP(Z, MIN_PROBE))) {
if (stepper.axis_is_moving(X_AXIS)) { _ENDSTOP_HIT(X, MIN); planner.endstop_triggered(X_AXIS); }
else if (stepper.axis_is_moving(Y_AXIS)) { _ENDSTOP_HIT(Y, MIN); planner.endstop_triggered(Y_AXIS); }
else if (stepper.axis_is_moving(Z_AXIS)) { _ENDSTOP_HIT(Z, MIN); planner.endstop_triggered(Z_AXIS); }
G38_endstop_hit = true;
{ // -direction
#if ENABLED(DUAL_X_CARRIAGE)
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((stepper.current_block->active_extruder == 0 && X_HOME_DIR == -1) || (stepper.current_block->active_extruder != 0 && X2_HOME_DIR == -1))
#endif
{
#if HAS_X_MIN
UPDATE_ENDSTOP(X, MIN);
#endif
}
}
else { // +direction
#if ENABLED(DUAL_X_CARRIAGE)
// with 2 x-carriages, endstops are only checked in the homing direction for the active extruder
if ((stepper.current_block->active_extruder == 0 && X_HOME_DIR == 1) || (stepper.current_block->active_extruder != 0 && X2_HOME_DIR == 1))
#endif
{
#if HAS_X_MAX
UPDATE_ENDSTOP(X, MAX);
#endif
}
}
#if ENABLED(COREXY) || ENABLED(COREXZ)
}
#endif
// Now, we must signal, after validation, if an endstop limit is pressed or not
if (stepper.axis_is_moving(X_AXIS)) {
if (stepper.motor_direction(X_AXIS_HEAD)) { // -direction
#if HAS_X_MIN
#if ENABLED(X_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(X, X2, MIN);
#else
if (X_MIN_TEST) PROCESS_ENDSTOP(X, MIN);
#if ENABLED(COREXY) || ENABLED(COREYZ)
// Head direction in -Y axis for CoreXY / CoreYZ bots.
// If DeltaA == DeltaB, the movement is only in X or Y axis
if ((stepper.current_block->steps[CORE_AXIS_1] != stepper.current_block->steps[CORE_AXIS_2]) || (stepper.motor_direction(CORE_AXIS_1) != stepper.motor_direction(CORE_AXIS_2))) {
if (stepper.motor_direction(Y_HEAD))
#else
if (stepper.motor_direction(Y_AXIS)) // -direction
#endif
{ // -direction
#if HAS_Y_MIN
UPDATE_ENDSTOP(Y, MIN);
#endif
#endif
}
else { // +direction
#if HAS_X_MAX
#if ENABLED(X_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(X, X2, MAX);
#else
if (X_MAX_TEST) PROCESS_ENDSTOP(X, MAX);
}
else { // +direction
#if HAS_Y_MAX
UPDATE_ENDSTOP(Y, MAX);
#endif
#endif
}
#if ENABLED(COREXY) || ENABLED(COREYZ)
}
}
#endif
if (stepper.axis_is_moving(Y_AXIS)) {
if (stepper.motor_direction(Y_AXIS_HEAD)) { // -direction
#if HAS_Y_MIN
#if ENABLED(Y_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Y, Y2, MIN);
#else
PROCESS_ENDSTOP(Y, MIN);
#endif
#endif
}
else { // +direction
#if HAS_Y_MAX
#if ENABLED(Y_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Y, Y2, MAX);
#else
PROCESS_ENDSTOP(Y, MAX);
#endif
#endif
}
}
#if ENABLED(COREXZ) || ENABLED(COREYZ)
// Head direction in -Z axis for CoreXZ or CoreYZ bots.
// If DeltaA == DeltaB, the movement is only in X or Y axis
if ((stepper.current_block->steps[CORE_AXIS_1] != stepper.current_block->steps[CORE_AXIS_2]) || (stepper.motor_direction(CORE_AXIS_1) != stepper.motor_direction(CORE_AXIS_2))) {
if (stepper.motor_direction(Z_HEAD))
#else
if (stepper.motor_direction(Z_AXIS))
#endif
{ // z -direction
#if HAS_Z_MIN
if (stepper.axis_is_moving(Z_AXIS)) {
if (stepper.motor_direction(Z_AXIS_HEAD)) { // Z -direction. Gantry down, bed up.
#if HAS_Z_MIN
#if ENABLED(Z_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Z, Z2, MIN);
#else
#if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
if (z_probe_enabled) PROCESS_ENDSTOP(Z, MIN);
#elif ENABLED(Z_MIN_PROBE_ENDSTOP)
if (!z_probe_enabled) PROCESS_ENDSTOP(Z, MIN);
#else
PROCESS_ENDSTOP(Z, MIN);
#endif
#endif
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
// When closing the gap check the enabled probe
#if ENABLED(Z_MIN_PROBE_ENDSTOP)
if (z_probe_enabled) PROCESS_ENDSTOP(Z, MIN_PROBE);
#endif
}
else { // Z +direction. Gantry up, bed down.
#if HAS_Z_MAX
#if ENABLED(Z_DUAL_ENDSTOPS)
PROCESS_DUAL_ENDSTOP(Z, Z2, MAX);
#elif DISABLED(Z_MIN_PROBE_ENDSTOP) || Z_MAX_PIN != Z_MIN_PROBE_PIN
// If this pin is not hijacked for the bed probe
// then it belongs to the Z endstop
PROCESS_ENDSTOP(Z, MAX);
UPDATE_ENDSTOP_BIT(Z, MIN);
#if HAS_Z2_MIN
UPDATE_ENDSTOP_BIT(Z2, MIN);
#else
COPY_BIT(current_endstop_bits, Z_MIN, Z2_MIN);
#endif
test_dual_z_endstops(Z_MIN, Z2_MIN);
#else // !Z_DUAL_ENDSTOPS
#if HAS_BED_PROBE && ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
if (z_probe_enabled) UPDATE_ENDSTOP(Z, MIN);
#else
UPDATE_ENDSTOP(Z, MIN);
#endif
#endif // !Z_DUAL_ENDSTOPS
#endif // HAS_Z_MIN
#if HAS_BED_PROBE && ENABLED(Z_MIN_PROBE_ENDSTOP) && DISABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN)
if (z_probe_enabled) {
UPDATE_ENDSTOP(Z, MIN_PROBE);
if (TEST_ENDSTOP(Z_MIN_PROBE)) SBI(endstop_hit_bits, Z_MIN_PROBE);
}
#endif
#endif
}
else { // z +direction
#if HAS_Z_MAX
#if ENABLED(Z_DUAL_ENDSTOPS)
UPDATE_ENDSTOP_BIT(Z, MAX);
#if HAS_Z2_MAX
UPDATE_ENDSTOP_BIT(Z2, MAX);
#else
COPY_BIT(current_endstop_bits, Z_MAX, Z2_MAX);
#endif
test_dual_z_endstops(Z_MAX, Z2_MAX);
#else // !Z_DUAL_ENDSTOPS
UPDATE_ENDSTOP(Z, MAX);
#endif // !Z_DUAL_ENDSTOPS
#endif // Z_MAX_PIN
}
#if ENABLED(COREXZ)
}
}
#endif
old_endstop_bits = current_endstop_bits;
} // Endstops::update()
#if ENABLED(PINS_DEBUGGING)
bool Endstops::monitor_flag = false;
/**
* monitors endstops & Z probe for changes
*
* If a change is detected then the LED is toggled and
* a message is sent out the serial port
*
* Yes, we could miss a rapid back & forth change but
* that won't matter because this is all manual.
*
*/
void Endstops::monitor() {
static uint16_t old_live_state_local = 0;
static uint8_t local_LED_status = 0;
uint16_t live_state_local = 0;
#if HAS_X_MIN
if (READ(X_MIN_PIN)) SBI(live_state_local, X_MIN);
#endif
#if HAS_X_MAX
if (READ(X_MAX_PIN)) SBI(live_state_local, X_MAX);
#endif
#if HAS_Y_MIN
if (READ(Y_MIN_PIN)) SBI(live_state_local, Y_MIN);
#endif
#if HAS_Y_MAX
if (READ(Y_MAX_PIN)) SBI(live_state_local, Y_MAX);
#endif
#if HAS_Z_MIN
if (READ(Z_MIN_PIN)) SBI(live_state_local, Z_MIN);
#endif
#if HAS_Z_MAX
if (READ(Z_MAX_PIN)) SBI(live_state_local, Z_MAX);
#endif
#if HAS_Z_MIN_PROBE_PIN
if (READ(Z_MIN_PROBE_PIN)) SBI(live_state_local, Z_MIN_PROBE);
#endif
#if HAS_X2_MIN
if (READ(X2_MIN_PIN)) SBI(live_state_local, X2_MIN);
#endif
#if HAS_X2_MAX
if (READ(X2_MAX_PIN)) SBI(live_state_local, X2_MAX);
#endif
#if HAS_Y2_MIN
if (READ(Y2_MIN_PIN)) SBI(live_state_local, Y2_MIN);
#endif
#if HAS_Y2_MAX
if (READ(Y2_MAX_PIN)) SBI(live_state_local, Y2_MAX);
#endif
#if HAS_Z2_MIN
if (READ(Z2_MIN_PIN)) SBI(live_state_local, Z2_MIN);
#endif
#if HAS_Z2_MAX
if (READ(Z2_MAX_PIN)) SBI(live_state_local, Z2_MAX);
#endif
uint16_t endstop_change = live_state_local ^ old_live_state_local;
if (endstop_change) {
#if HAS_X_MIN
if (TEST(endstop_change, X_MIN)) SERIAL_PROTOCOLPAIR(" X_MIN:", TEST(live_state_local, X_MIN));
#endif
#if HAS_X_MAX
if (TEST(endstop_change, X_MAX)) SERIAL_PROTOCOLPAIR(" X_MAX:", TEST(live_state_local, X_MAX));
#endif
#if HAS_Y_MIN
if (TEST(endstop_change, Y_MIN)) SERIAL_PROTOCOLPAIR(" Y_MIN:", TEST(live_state_local, Y_MIN));
#endif
#if HAS_Y_MAX
if (TEST(endstop_change, Y_MAX)) SERIAL_PROTOCOLPAIR(" Y_MAX:", TEST(live_state_local, Y_MAX));
#endif
#if HAS_Z_MIN
if (TEST(endstop_change, Z_MIN)) SERIAL_PROTOCOLPAIR(" Z_MIN:", TEST(live_state_local, Z_MIN));
#endif
#if HAS_Z_MAX
if (TEST(endstop_change, Z_MAX)) SERIAL_PROTOCOLPAIR(" Z_MAX:", TEST(live_state_local, Z_MAX));
#endif
#if HAS_Z_MIN_PROBE_PIN
if (TEST(endstop_change, Z_MIN_PROBE)) SERIAL_PROTOCOLPAIR(" PROBE:", TEST(live_state_local, Z_MIN_PROBE));
#endif
#if HAS_X2_MIN
if (TEST(endstop_change, X2_MIN)) SERIAL_PROTOCOLPAIR(" X2_MIN:", TEST(live_state_local, X2_MIN));
#endif
#if HAS_X2_MAX
if (TEST(endstop_change, X2_MAX)) SERIAL_PROTOCOLPAIR(" X2_MAX:", TEST(live_state_local, X2_MAX));
#endif
#if HAS_Y2_MIN
if (TEST(endstop_change, Y2_MIN)) SERIAL_PROTOCOLPAIR(" Y2_MIN:", TEST(live_state_local, Y2_MIN));
#endif
#if HAS_Y2_MAX
if (TEST(endstop_change, Y2_MAX)) SERIAL_PROTOCOLPAIR(" Y2_MAX:", TEST(live_state_local, Y2_MAX));
#endif
#if HAS_Z2_MIN
if (TEST(endstop_change, Z2_MIN)) SERIAL_PROTOCOLPAIR(" Z2_MIN:", TEST(live_state_local, Z2_MIN));
#endif
#if HAS_Z2_MAX
if (TEST(endstop_change, Z2_MAX)) SERIAL_PROTOCOLPAIR(" Z2_MAX:", TEST(live_state_local, Z2_MAX));
#endif
SERIAL_PROTOCOLPGM("\n\n");
analogWrite(LED_PIN, local_LED_status);
local_LED_status ^= 255;
old_live_state_local = live_state_local;
}
}
#endif // PINS_DEBUGGING

View File

@@ -21,115 +21,44 @@
*/
/**
* endstops.h - manages endstops
* endstops.h - manages endstops
*/
#ifndef __ENDSTOPS_H__
#define __ENDSTOPS_H__
#ifndef ENDSTOPS_H
#define ENDSTOPS_H
#include "MarlinConfig.h"
#define VALIDATE_HOMING_ENDSTOPS
enum EndstopEnum : char {
X_MIN,
Y_MIN,
Z_MIN,
Z_MIN_PROBE,
X_MAX,
Y_MAX,
Z_MAX,
X2_MIN,
X2_MAX,
Y2_MIN,
Y2_MAX,
Z2_MIN,
Z2_MAX
};
#include "enum.h"
class Endstops {
public:
static bool enabled, enabled_globally;
static volatile char endstop_hit_bits; // use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT value
#if ENABLED(X_DUAL_ENDSTOPS) || ENABLED(Y_DUAL_ENDSTOPS) || ENABLED(Z_DUAL_ENDSTOPS)
typedef uint16_t esbits_t;
#if ENABLED(X_DUAL_ENDSTOPS)
static float x_endstop_adj;
#endif
#if ENABLED(Y_DUAL_ENDSTOPS)
static float y_endstop_adj;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
static float z_endstop_adj;
#endif
#if ENABLED(Z_DUAL_ENDSTOPS)
static uint16_t
#else
typedef uint8_t esbits_t;
static byte
#endif
current_endstop_bits, old_endstop_bits;
private:
static esbits_t live_state;
static volatile uint8_t hit_state; // Use X_MIN, Y_MIN, Z_MIN and Z_MIN_PROBE as BIT index
#if ENABLED(ENDSTOP_NOISE_FILTER)
static esbits_t validated_live_state;
static uint8_t endstop_poll_count; // Countdown from threshold for polling
#endif
public:
Endstops() {};
/**
* Initialize the endstop pins
*/
static void init();
void init();
/**
* Are endstops or the probe set to abort the move?
*/
FORCE_INLINE static bool abort_enabled() {
return (enabled
#if HAS_BED_PROBE
|| z_probe_enabled
#endif
);
}
/**
* Periodic call to poll endstops if required. Called from temperature ISR
*/
static void poll();
/**
* Update endstops bits from the pins. Apply filtering to get a verified state.
* If abort_enabled() and moving towards a triggered switch, abort the current move.
* Called from ISR contexts.
* Update the endstops bits from the pins
*/
static void update();
/**
* Get Endstop hit state.
* Print an error message reporting the position when the endstops were last hit.
*/
FORCE_INLINE static uint8_t trigger_state() { return hit_state; }
/**
* Get current endstops state
*/
FORCE_INLINE static esbits_t state() {
return
#if ENABLED(ENDSTOP_NOISE_FILTER)
validated_live_state
#else
live_state
#endif
;
}
/**
* Report endstop hits to serial. Called from loop().
*/
static void event_handler();
static void report_state(); //call from somewhere to create an serial error message with the locations the endstops where hit, in case they were triggered
/**
* Report endstop positions in response to M119
@@ -137,38 +66,30 @@ class Endstops {
static void M119();
// Enable / disable endstop checking globally
static void enable_globally(const bool onoff=true);
static void enable_globally(bool onoff=true) { enabled_globally = enabled = onoff; }
// Enable / disable endstop checking
static void enable(const bool onoff=true);
static void enable(bool onoff=true) { enabled = onoff; }
// Disable / Enable endstops based on ENSTOPS_ONLY_FOR_HOMING and global enable
static void not_homing();
#if ENABLED(VALIDATE_HOMING_ENDSTOPS)
// If the last move failed to trigger an endstop, call kill
static void validate_homing_move();
#else
FORCE_INLINE static void validate_homing_move() { hit_on_purpose(); }
#endif
static void not_homing() { enabled = enabled_globally; }
// Clear endstops (i.e., they were hit intentionally) to suppress the report
FORCE_INLINE static void hit_on_purpose() { hit_state = 0; }
static void hit_on_purpose() { endstop_hit_bits = 0; }
// Enable / disable endstop z-probe checking
#if HAS_BED_PROBE
static volatile bool z_probe_enabled;
static void enable_z_probe(const bool onoff=true);
static void enable_z_probe(bool onoff=true) { z_probe_enabled = onoff; }
#endif
// Debugging of endstops
#if ENABLED(PINS_DEBUGGING)
static bool monitor_flag;
static void monitor();
static void run_monitor();
private:
#if ENABLED(Z_DUAL_ENDSTOPS)
static void test_dual_z_endstops(EndstopEnum es1, EndstopEnum es2);
#endif
};
extern Endstops endstops;
#endif // __ENDSTOPS_H__
#endif // ENDSTOPS_H

View File

@@ -23,46 +23,30 @@
#ifndef __ENUM_H__
#define __ENUM_H__
#include "MarlinConfig.h"
/**
* Axis indices as enumerated constants
*
* - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space
* - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians
* - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics
* Special axis:
* - A_AXIS and B_AXIS are used by COREXY printers
* - X_HEAD and Y_HEAD is used for systems that don't have a 1:1 relationship
* between X_AXIS and X Head movement, like CoreXY bots
*/
enum AxisEnum : unsigned char {
X_AXIS = 0,
A_AXIS = 0,
Y_AXIS = 1,
B_AXIS = 1,
Z_AXIS = 2,
C_AXIS = 2,
E_CART = 3,
#if ENABLED(HANGPRINTER) // Hangprinter order: A_AXIS, B_AXIS, C_AXIS, D_AXIS, E_AXIS
D_AXIS = 3,
E_AXIS = 4,
#else
E_AXIS = 3,
#endif
X_HEAD, Y_HEAD, Z_HEAD,
ALL_AXES = 0xFE,
NO_AXIS = 0xFF
enum AxisEnum {
NO_AXIS = -1,
X_AXIS = 0,
A_AXIS = 0,
Y_AXIS = 1,
B_AXIS = 1,
Z_AXIS = 2,
C_AXIS = 2,
E_AXIS = 3,
X_HEAD = 4,
Y_HEAD = 5,
Z_HEAD = 6
};
#define LOOP_S_LE_N(VAR, S, N) for (uint8_t VAR=S; VAR<=N; VAR++)
#define LOOP_S_L_N(VAR, S, N) for (uint8_t VAR=S; VAR<N; VAR++)
#define LOOP_LE_N(VAR, N) LOOP_S_LE_N(VAR, 0, N)
#define LOOP_L_N(VAR, N) LOOP_S_L_N(VAR, 0, N)
#define LOOP_NA(VAR) LOOP_L_N(VAR, NUM_AXIS)
#define LOOP_XYZ(VAR) LOOP_S_LE_N(VAR, X_AXIS, Z_AXIS)
#define LOOP_XYZE(VAR) LOOP_S_LE_N(VAR, X_AXIS, E_CART)
#define LOOP_XYZE_N(VAR) LOOP_S_L_N(VAR, X_AXIS, XYZE_N)
#define LOOP_MOV_AXIS(VAR) LOOP_S_L_N(VAR, A_AXIS, MOV_AXIS)
#define LOOP_NUM_AXIS(VAR) LOOP_S_L_N(VAR, A_AXIS, NUM_AXIS)
#define LOOP_NUM_AXIS_N(VAR) LOOP_S_L_N(VAR, A_AXIS, NUM_AXIS_N)
#define LOOP_XYZ(VAR) for (uint8_t VAR=X_AXIS; VAR<=Z_AXIS; VAR++)
#define LOOP_XYZE(VAR) for (uint8_t VAR=X_AXIS; VAR<=E_AXIS; VAR++)
typedef enum {
LINEARUNIT_MM,
@@ -79,48 +63,84 @@ typedef enum {
* Debug flags
* Not yet widely applied
*/
enum DebugFlags : unsigned char {
enum DebugFlags {
DEBUG_NONE = 0,
DEBUG_ECHO = _BV(0), ///< Echo commands in order as they are processed
DEBUG_INFO = _BV(1), ///< Print messages for code that has debug output
DEBUG_ERRORS = _BV(2), ///< Not implemented
DEBUG_DRYRUN = _BV(3), ///< Ignore temperature setting and E movement commands
DEBUG_COMMUNICATION = _BV(4), ///< Not implemented
DEBUG_LEVELING = _BV(5), ///< Print detailed output for homing and leveling
DEBUG_MESH_ADJUST = _BV(6), ///< UBL bed leveling
DEBUG_ALL = 0xFF
DEBUG_LEVELING = _BV(5) ///< Print detailed output for homing and leveling
};
#if ENABLED(ADVANCED_PAUSE_FEATURE)
enum AdvancedPauseMenuResponse : char {
ADVANCED_PAUSE_RESPONSE_WAIT_FOR,
ADVANCED_PAUSE_RESPONSE_EXTRUDE_MORE,
ADVANCED_PAUSE_RESPONSE_RESUME_PRINT
enum EndstopEnum {
X_MIN,
Y_MIN,
Z_MIN,
Z_MIN_PROBE,
X_MAX,
Y_MAX,
Z_MAX,
Z2_MIN,
Z2_MAX
};
/**
* Temperature
* Stages in the ISR loop
*/
enum TempState {
PrepareTemp_0,
MeasureTemp_0,
PrepareTemp_BED,
MeasureTemp_BED,
PrepareTemp_1,
MeasureTemp_1,
PrepareTemp_2,
MeasureTemp_2,
PrepareTemp_3,
MeasureTemp_3,
Prepare_FILWIDTH,
Measure_FILWIDTH,
StartupDelay // Startup, delay initial temp reading a tiny bit so the hardware can settle
};
#if ENABLED(EMERGENCY_PARSER)
enum e_parser_state {
state_RESET,
state_N,
state_M,
state_M1,
state_M10,
state_M108,
state_M11,
state_M112,
state_M4,
state_M41,
state_M410,
state_IGNORE // to '\n'
};
#endif
#if ENABLED(FILAMENT_CHANGE_FEATURE)
enum FilamentChangeMenuResponse {
FILAMENT_CHANGE_RESPONSE_WAIT_FOR,
FILAMENT_CHANGE_RESPONSE_EXTRUDE_MORE,
FILAMENT_CHANGE_RESPONSE_RESUME_PRINT
};
#if ENABLED(ULTIPANEL)
enum AdvancedPauseMessage : char {
ADVANCED_PAUSE_MESSAGE_INIT,
ADVANCED_PAUSE_MESSAGE_UNLOAD,
ADVANCED_PAUSE_MESSAGE_INSERT,
ADVANCED_PAUSE_MESSAGE_LOAD,
ADVANCED_PAUSE_MESSAGE_PURGE,
#if ENABLED(ADVANCED_PAUSE_CONTINUOUS_PURGE)
ADVANCED_PAUSE_MESSAGE_CONTINUOUS_PURGE,
#endif
ADVANCED_PAUSE_MESSAGE_OPTION,
ADVANCED_PAUSE_MESSAGE_RESUME,
ADVANCED_PAUSE_MESSAGE_STATUS,
ADVANCED_PAUSE_MESSAGE_CLICK_TO_HEAT_NOZZLE,
ADVANCED_PAUSE_MESSAGE_WAIT_FOR_NOZZLES_TO_HEAT
enum FilamentChangeMessage {
FILAMENT_CHANGE_MESSAGE_INIT,
FILAMENT_CHANGE_MESSAGE_UNLOAD,
FILAMENT_CHANGE_MESSAGE_INSERT,
FILAMENT_CHANGE_MESSAGE_LOAD,
FILAMENT_CHANGE_MESSAGE_EXTRUDE,
FILAMENT_CHANGE_MESSAGE_OPTION,
FILAMENT_CHANGE_MESSAGE_RESUME,
FILAMENT_CHANGE_MESSAGE_STATUS
};
#endif
enum AdvancedPauseMode : char {
ADVANCED_PAUSE_MODE_PAUSE_PRINT,
ADVANCED_PAUSE_MODE_LOAD_FILAMENT,
ADVANCED_PAUSE_MODE_UNLOAD_FILAMENT
};
#endif
/**
@@ -128,7 +148,7 @@ enum DebugFlags : unsigned char {
* Marlin sends messages if blocked or busy
*/
#if ENABLED(HOST_KEEPALIVE_FEATURE)
enum MarlinBusyState : char {
enum MarlinBusyState {
NOT_BUSY, // Not in a handler
IN_HANDLER, // Processing a GCode
IN_PROCESS, // Known to be blocking command input (as in G29)
@@ -137,15 +157,32 @@ enum DebugFlags : unsigned char {
};
#endif
#if ENABLED(MESH_BED_LEVELING)
enum MeshLevelingState {
MeshReport,
MeshStart,
MeshNext,
MeshSet,
MeshSetZOffset,
MeshReset
};
enum MBLStatus {
MBL_STATUS_NONE = 0,
MBL_STATUS_HAS_MESH_BIT = 0,
MBL_STATUS_ACTIVE_BIT = 1
};
#endif
/**
* SD Card
*/
enum LsAction : char { LS_SerialPrint, LS_Count, LS_GetFilename };
enum LsAction { LS_SerialPrint, LS_Count, LS_GetFilename };
/**
* Ultra LCD
*/
enum LCDViewAction : char {
enum LCDViewAction {
LCDVIEW_NONE,
LCDVIEW_REDRAW_NOW,
LCDVIEW_CALL_REDRAW_NEXT,
@@ -153,23 +190,4 @@ enum LCDViewAction : char {
LCDVIEW_CALL_NO_REDRAW
};
/**
* Dual X Carriage modes. A Dual Nozzle can also do duplication.
*/
#if ENABLED(DUAL_X_CARRIAGE) || ENABLED(DUAL_NOZZLE_DUPLICATION_MODE)
enum DualXMode : char {
DXC_FULL_CONTROL_MODE, // DUAL_X_CARRIAGE only
DXC_AUTO_PARK_MODE, // DUAL_X_CARRIAGE only
DXC_DUPLICATION_MODE
};
#endif
/**
* Workspace planes only apply to G2/G3 moves
* (and "canned cycles" - not a current feature)
*/
#if ENABLED(CNC_WORKSPACE_PLANES)
enum WorkspacePlane : char { PLANE_XY, PLANE_ZX, PLANE_YZ };
#endif
#endif // __ENUM_H__

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,15 +0,0 @@
This is an example configuration for the CL-260 Ultimaker 2 clone.
Change Z_MAX_POS to 300 for the CL-260MAX.
(The printer is available on AliExpress; be aware that this is not a beginner's
printer -- it needs tweaking and some parts replaced before being decent.)
The printer comes with a quite old Marlin, the sources are available here:
http://www.thingiverse.com/thing:1635830/ and I recommend replacing them.
The setting "works" for my printer and the extruder using my calibration value.
You might want to tweak some settings, e.g enable EEPROM, increase default Z speed, adjust homing speeds,...
Have fun!
--
tobi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
# Example Configuration for BQ [Hephestos 2](http://www.bq.com/uk/hephestos-2)
Based on the original configuration file shipped with the heavily modified Marlin fork by BQ.
The forked firmware and configuration files can be found at the [BQ Github repository](https://github.com/bq/Marlin).
NOTE: The look and feel of the LCD menu will change dramatically when using the original Marlin firmware.
## Changelog
* 2018/05/30 - Configuration updated to the latest Marlin version (43a55a9af).
ABL Bilinear 5x5 is active by default.
* 2017/07/06 - Configuration updated to the latest Marlin version and added support for the
official BQ heated bed upgrade kit.
* 2016/12/13 - Configuration updated to the latest Marlin version.
* 2016/07/13 - Configuration updated to the latest Marlin version.
* 2016/06/21 - Disabled heated bed related options, activated software endstops and SD printing now
disables the heater when finishes printing.
* 2016/03/21 - Activated 4-point auto leveling by default and updated miscellaneous z-probe values.
* 2016/03/01 - The first release of Marlin's configuration file for the
BQ Hephestos 2 3D printer.
## Support
This configuration should work easily with the stock Hephestos 2, nevertheless if you encounter any
issues you may contact me on [Github](https://github.com/jbrazio), [Twitter](https://twitter.com/jbrazio) or by mail.

View File

@@ -1,100 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Custom Boot Screen bitmap
*
* Place this file in the root with your configuration files
* and enable SHOW_CUSTOM_BOOTSCREEN in Configuration.h.
*
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
*/
#define CUSTOM_BOOTSCREEN_BMPWIDTH 64
const unsigned char custom_start_bmp[] PROGMEM = {
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000011,B11110000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11111000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11111000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00001111,B11111100,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00001111,B11111100,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11111000,B00000000,B00000000,B00000000,
B00000000,B00000000,B11111000,B00000111,B11111000,B00000111,B11000000,B00000000,
B00000000,B00000001,B11111100,B00000011,B11110000,B00001111,B11100000,B00000000,
B00000000,B00000011,B11111110,B00000000,B11000000,B00011111,B11110000,B00000000,
B00000000,B00000011,B11111110,B00000000,B00000000,B00011111,B11110000,B00000000,
B00000000,B00000011,B11111110,B00000000,B00000000,B00011111,B11110000,B00000000,
B00000000,B00000011,B11111110,B00000000,B00000000,B00011111,B11110000,B00000000,
B00000000,B00000011,B11111100,B00000000,B00000000,B00001111,B11100000,B00000000,
B00000000,B00000001,B11111000,B00000000,B00000000,B00001111,B11100000,B00000000,
B00000000,B00000000,B01110000,B00000000,B00000000,B00000011,B10000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01100000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111100,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111100,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111100,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000111,B11111100,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111100,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000011,B11111100,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000001,B11111000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00001111,B10000000,B00000000,B00000000,B01110000,B00000000,B00000000,B00000000,
B00011111,B11000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,
B00111111,B11000000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,
B00111111,B11100000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,
B00111111,B11100000,B00000000,B00000000,B01111000,B00000000,B00000000,B00000000,
B00111111,B11100000,B00000000,B00000000,B01111011,B11000000,B00001111,B00000000,
B00111111,B11000000,B00000000,B00000000,B01111111,B11110000,B00111111,B11000000,
B00011111,B10000000,B00000000,B00000000,B01111111,B11111000,B01111111,B11100000,
B00001111,B00000000,B00000000,B00000000,B01111110,B11111100,B11111001,B11110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B11100000,B11110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00011101,B11100000,B01110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00011101,B11100000,B01110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00011101,B11100000,B01110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00011101,B11100000,B01110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00011101,B11100000,B01110000,
B00000000,B00000000,B00000000,B00000000,B01111000,B00111100,B11100000,B11110000,
B00000000,B00000000,B00000000,B00000000,B01111100,B01111100,B11111001,B11110000,
B00000000,B00000000,B00000000,B00000000,B00011111,B11111000,B11111111,B11110000,
B00000000,B00000000,B00000000,B00000000,B00001111,B11110000,B01111111,B11110000,
B00000000,B00000000,B00000000,B00000000,B00000111,B11100000,B00011111,B01110000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01110000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01110000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01110000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01110000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B01110000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -21,80 +21,83 @@
*/
/**
* Custom Boot Screen bitmap
* Custom Bitmap for splashscreen
*
* Place this file in the root with your configuration files
* and enable SHOW_CUSTOM_BOOTSCREEN in Configuration.h.
* You may use one of the following tools to generate the C++ bitmap array from
* a black and white image:
*
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
* - http://www.marlinfw.org/tools/u8glib/converter.html
* - http://www.digole.com/tools/PicturetoC_Hex_converter.php
*/
#include <avr/pgmspace.h>
#define CUSTOM_BOOTSCREEN_BMPWIDTH 64
#define CUSTOM_BOOTSCREEN_TIMEOUT 2500
#define CUSTOM_BOOTSCREEN_BMPWIDTH 63
#define CUSTOM_BOOTSCREEN_BMPHEIGHT 64
const unsigned char custom_start_bmp[] PROGMEM = {
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00111111,B11111100,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000011,B11111111,B11111111,B11000000,B00000000,B00000000,
B00000000,B00000000,B00011111,B11111111,B11111111,B11110000,B00000000,B00000000,
B00000000,B00000000,B01111111,B11111111,B11111111,B11111100,B00000000,B00000000,
B00000000,B00000000,B11111111,B11111111,B11111111,B11111111,B00000000,B00000000,
B00000000,B00000011,B11111111,B11111111,B11111111,B11111111,B10000000,B00000000,
B00000000,B00000111,B11111111,B11111111,B11111111,B11111111,B11000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00001111,B00000111,B10000111,B11111111,B11111111,B11100000,B00000000,
B00000000,B00011111,B10001111,B11000111,B11111111,B11111111,B11110001,B00000000,
B00000001,B00011111,B10001111,B11000111,B11111111,B11111111,B11110001,B10000000,
B00000011,B00011111,B10001111,B11000111,B11111111,B11111111,B11110001,B10000000,
B00000111,B00011111,B10001111,B11000111,B11111111,B11111111,B11100001,B11000000,
B00000111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11100000,
B00001111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11100000,
B00001111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11110000,
B00011111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11110000,
B00011111,B00011111,B10001111,B11000111,B11111111,B11111111,B11100001,B11110000,
B00111111,B00011111,B10001111,B11000111,B11111111,B11111111,B11110001,B11111000,
B00111111,B00011111,B10001111,B11000111,B11111111,B11111111,B11110001,B11111000,
B00111111,B00011111,B10001111,B11000111,B11111111,B11111111,B11110001,B11111000,
B00111111,B00011111,B10001111,B11000111,B11111111,B11111111,B11100001,B11111000,
B01111111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11111100,
B01111111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11111100,
B01111111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11111100,
B01111111,B00011111,B10001111,B11000111,B11000000,B00000000,B00000001,B11111100,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,
B01111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111111,B11111100,
B01111111,B00000000,B00000000,B00000111,B11000111,B11100011,B11110001,B11111100,
B01111111,B00000000,B00000000,B00000111,B11000111,B11100011,B11110001,B11111100,
B01111111,B00000000,B00000000,B00000111,B11000111,B11100011,B11110001,B11111100,
B00111111,B00001111,B11111111,B11111111,B11000111,B11100011,B11110001,B11111000,
B00111111,B00011111,B11111111,B11111111,B11000111,B11100011,B11110001,B11111000,
B00111111,B00011111,B11111111,B11111111,B11000111,B11100011,B11110001,B11111000,
B00111111,B00011111,B11111111,B11111111,B11000111,B11100011,B11110001,B11111000,
B00011111,B00011111,B11111111,B11111111,B11000111,B11100011,B11110001,B11110000,
B00011111,B00001111,B11111111,B11111111,B11000111,B11100011,B11110001,B11110000,
B00011111,B00000000,B00000000,B00000111,B11000111,B11100011,B11110001,B11100000,
B00001111,B00000000,B00000000,B00000111,B11000111,B11100011,B11110001,B11100000,
B00001111,B00000000,B00000000,B00000111,B11000111,B11100011,B11110001,B11000000,
B00000111,B00001111,B11111111,B11111111,B11000111,B11100011,B11110001,B11000000,
B00000011,B00011111,B11111111,B11111111,B11000111,B11100011,B11110001,B10000000,
B00000011,B00011111,B11111111,B11111111,B11000111,B11100011,B11110001,B00000000,
B00000001,B00011111,B11111111,B11111111,B11000111,B11100011,B11110000,B00000000,
B00000000,B00011111,B11111111,B11111111,B11000111,B11100011,B11110000,B00000000,
B00000000,B00001111,B11111111,B11111111,B11000011,B11000001,B11100000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000111,B11000000,B00000000,B00000000,B00000000,
B00000000,B00000111,B11111111,B11111111,B11111111,B11111111,B11000000,B00000000,
B00000000,B00000011,B11111111,B11111111,B11111111,B11111111,B10000000,B00000000,
B00000000,B00000001,B11111111,B11111111,B11111111,B11111110,B00000000,B00000000,
B00000000,B00000000,B01111111,B11111111,B11111111,B11111100,B00000000,B00000000,
B00000000,B00000000,B00011111,B11111111,B11111111,B11110000,B00000000,B00000000,
B00000000,B00000000,B00000111,B11111111,B11111111,B10000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B01111111,B11111000,B00000000,B00000000,B00000000,
B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000,B00000000
const unsigned char custom_start_bmp[512] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x3f, 0xfc, 0x00, 0x00, 0x00,
0x00, 0x00, 0x03, 0xff, 0xff, 0xc0, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x0f, 0x07, 0x87, 0xff, 0xff, 0xe0, 0x00,
0x00, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xf1, 0x00,
0x01, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xf1, 0x80,
0x03, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xf1, 0x80,
0x07, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xe1, 0xc0,
0x07, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xe0,
0x0f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xe0,
0x0f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xf0,
0x1f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xf0,
0x1f, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xe1, 0xf0,
0x3f, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xf1, 0xf8,
0x3f, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xf1, 0xf8,
0x3f, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xf1, 0xf8,
0x3f, 0x1f, 0x8f, 0xc7, 0xff, 0xff, 0xe1, 0xf8,
0x7f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xfc,
0x7f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xfc,
0x7f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xfc,
0x7f, 0x1f, 0x8f, 0xc7, 0xc0, 0x00, 0x01, 0xfc,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc,
0x7f, 0x00, 0x00, 0x07, 0xc7, 0xe3, 0xf1, 0xfc,
0x7f, 0x00, 0x00, 0x07, 0xc7, 0xe3, 0xf1, 0xfc,
0x7f, 0x00, 0x00, 0x07, 0xc7, 0xe3, 0xf1, 0xfc,
0x3f, 0x0f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xf8,
0x3f, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xf8,
0x3f, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xf8,
0x3f, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xf8,
0x1f, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xf0,
0x1f, 0x0f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xf0,
0x1f, 0x00, 0x00, 0x07, 0xc7, 0xe3, 0xf1, 0xe0,
0x0f, 0x00, 0x00, 0x07, 0xc7, 0xe3, 0xf1, 0xe0,
0x0f, 0x00, 0x00, 0x07, 0xc7, 0xe3, 0xf1, 0xc0,
0x07, 0x0f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0xc0,
0x03, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0x80,
0x03, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf1, 0x00,
0x01, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf0, 0x00,
0x00, 0x1f, 0xff, 0xff, 0xc7, 0xe3, 0xf0, 0x00,
0x00, 0x0f, 0xff, 0xff, 0xc3, 0xc1, 0xe0, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x07, 0xc0, 0x00, 0x00, 0x00,
0x00, 0x07, 0xff, 0xff, 0xff, 0xff, 0xc0, 0x00,
0x00, 0x03, 0xff, 0xff, 0xff, 0xff, 0x80, 0x00,
0x00, 0x01, 0xff, 0xff, 0xff, 0xfe, 0x00, 0x00,
0x00, 0x00, 0x7f, 0xff, 0xff, 0xfc, 0x00, 0x00,
0x00, 0x00, 0x1f, 0xff, 0xff, 0xf0, 0x00, 0x00,
0x00, 0x00, 0x07, 0xff, 0xff, 0x80, 0x00, 0x00,
0x00, 0x00, 0x00, 0x7f, 0xf8, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

File diff suppressed because it is too large Load Diff

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