Merge branch 'bugfix-2.1.x' into LulzbotTestBase

This commit is contained in:
InsanityAutomation
2022-06-08 17:38:26 -04:00
355 changed files with 6703 additions and 3292 deletions
+19 -20
View File
@@ -14,13 +14,13 @@ body:
## Before Reporting a Bug
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
- Test with the [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see whether the issue still exists.
- Test with the [`bugfix-2.1.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.1.x.zip) to see whether the issue still exists.
## Instructions
Please follow the instructions below. Failure to do so may result in your issue being closed. See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.0.x/.github/contributing.md) for additional guidelines.
Please follow the instructions below. Failure to do so may result in your issue being closed. See [Contributing to Marlin](https://github.com/MarlinFirmware/Marlin/blob/bugfix-2.1.x/.github/contributing.md) for additional guidelines.
1. Provide a good title starting with [BUG].
2. Fill out all sections of this bug report form.
@@ -28,10 +28,10 @@ body:
- type: dropdown
attributes:
label: Did you test the latest `bugfix-2.0.x` code?
label: Did you test the latest `bugfix-2.1.x` code?
description: >-
Always try the latest code to make sure the issue you are reporting is not already fixed. To download
the latest code just [click this link](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip).
the latest code just [click this link](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.1.x.zip).
options:
- Yes, and the problem still exists.
- No, but I will test it now!
@@ -50,6 +50,8 @@ body:
Describe the bug in this section. Tell us what you were trying to do and what
happened that you did not expect. Provide a clear and concise description of the
problem and include as many details as possible.
When pasting formatted text don't forget to put ` ``` ` (on its own line) before and after to make it readable.
placeholder: |
Marlin doesn't work.
validations:
@@ -147,23 +149,20 @@ body:
- Same as my slicer
- Other (explain below)
- type: markdown
- type: checkboxes
attributes:
value: >-
## Other things to include
Please also be sure to include these items to help with troubleshooting:
* **A ZIP file** containing your `Configuration.h` and `Configuration_adv.h`.
(Please don't paste lengthy configuration text here.)
* **Log output** from the host. (`M111 S247` for maximum logging.)
* **Images or videos** demonstrating the problem, if it helps to make it clear.
* **A G-Code file** that exposes the problem, if not affecting _all_ G-code.
If you've made any other modifications to the firmware, please describe them in detail in the space provided.
When pasting formatted text into the box below don't forget to put ` ``` ` (on its own line) before and after to make it readable.
label: Other things to include
options:
- label: A ZIP file containing your `Configuration.h` and `Configuration_adv.h`.
required: true
- label: Log output from the host. (`M111 S247` for maximum logging.)
- label: Images or videos demonstrating the problem, if it helps to make it clear.
- label: A G-Code file that exposes the problem, if not affecting _all_ G-code.
- type: textarea
attributes:
label: Additional information & file uploads
description: >-
If you've made any other modifications to the firmware, please describe them in detail.
When pasting formatted text don't forget to put ` ``` ` (on its own line) before and after to make it readable.
+1 -1
View File
@@ -17,7 +17,7 @@ body:
- Read and understand Marlin's [Code of Conduct](https://github.com/MarlinFirmware/Marlin/blob/master/.github/code_of_conduct.md). You are expected to comply with it, including treating everyone with respect.
- Check the latest [`bugfix-2.0.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.0.x.zip) to see if the feature already exists.
- Check the latest [`bugfix-2.1.x` branch](https://github.com/MarlinFirmware/Marlin/archive/bugfix-2.1.x.zip) to see if the feature already exists.
- Before you proceed with your request, please consider if it is necessary to make it into a firmware feature, or if it may be better suited for a slicer or host feature.
+1 -1
View File
@@ -116,7 +116,7 @@ Unsure where to begin contributing to Marlin? You can start by looking through t
### Pull Requests
Pull Requests should always be targeted to working branches (e.g., `bugfix-2.0.x` and/or `bugfix-1.1.x`) and never to release branches (e.g., `2.0.x` and/or `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
Pull Requests should always be targeted to working branches (e.g., `bugfix-2.1.x` and/or `bugfix-1.1.x`) and never to release branches (e.g., `2.0.x` and/or `1.1.x`). If this is your first Pull Request, please read our [Guide to Pull Requests](https://marlinfw.org/docs/development/getting_started_pull_requests.html) and Github's [Pull Request](https://help.github.com/articles/creating-a-pull-request/) documentation.
* Fill in [the required template](pull_request_template.md).
* Don't include issue numbers in the PR title.
+16 -6
View File
@@ -1,23 +1,33 @@
### Requirements
<!--
* Filling out this template is required. Pull Requests without a clear description may be closed at the maintainers' discretion.
Submitting a Pull Request
- Please fill out all sections of this form. You can delete the helpful comments.
- Pull Requests without clear information will take longer and may even be rejected.
- We get a high volume of submissions so please be patient during review.
-->
### Description
<!--
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.
Clearly describe the submitted changes with lots of details. Include images where helpful. Initial reviewers may not be familiar with the subject, so be as thorough as possible. You can use MarkDown syntax to improve readability with bullet lists, code blocks, and so on. PREVIEW and fix up formatting before submitting.
-->
### Requirements
<!-- Does this PR require a specific board, LCD, etc.? -->
### Benefits
<!-- What does this fix or improve? -->
<!-- What does this PR fix or improve? -->
### Configurations
<!-- Attach any Configuration.h, Configuration_adv.h, or platformio.ini files needed to compile/test your Pull Request. -->
<!-- Attach Configurations ZIP and any other files needed to test this PR. -->
### Related Issues
<!-- Whether this fixes a bug or fulfills a feature request, please list any related Issues here. -->
<!-- Does this PR fix a bug or fulfill a Feature Request? Link related Issues here. -->
+59
View File
@@ -0,0 +1,59 @@
#
# bump-date.yml
# Bump the distribution date once per day
#
name: Bump Distribution Date
on:
schedule:
- cron: '0 */6 * * *'
jobs:
bump_date:
name: Bump Distribution Date
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- name: Check out bugfix-2.1.x
uses: actions/checkout@v2
with:
ref: bugfix-2.1.x
- name: Bump Date (bugfix-2.0.x)
run: |
# Inline Bump Script
if [[ ! "$( git log -1 --pretty=%B )" =~ ^\[cron\] ]]; then
DIST=$( date +"%Y-%m-%d" )
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/src/inc/Version.h" && \
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/Version.h" && \
git config user.name "${GITHUB_ACTOR}" && \
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
git add . && \
git commit -m "[cron] Bump distribution date ($DIST)" && \
git push
fi
exit 0
- name: Check out bugfix-2.1.x
uses: actions/checkout@v2
with:
ref: bugfix-2.1.x
- name: Bump Date (bugfix-2.1.x)
run: |
# Inline Bump Script
if [[ ! "$( git log -1 --pretty=%B )" =~ ^\[cron\] ]]; then
DIST=$( date +"%Y-%m-%d" )
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/src/inc/Version.h" && \
eval "sed -E -i 's/(#define +STRING_DISTRIBUTION_DATE) .*$/\1 \"$DIST\"/g' Marlin/Version.h" && \
git config user.name "${GITHUB_ACTOR}" && \
git config user.email "${GITHUB_ACTOR}@users.noreply.github.com" && \
git add . && \
git commit -m "[cron] Bump distribution date ($DIST)" && \
git push
fi
exit 0
+34
View File
@@ -0,0 +1,34 @@
#
# check-pr.yml
# Close PRs directed at release branches
#
name: PR Bad Target
on:
pull_request_target:
types: [opened]
branches:
- 1.0.x
- 1.1.x
- 2.0.x
- 2.1.x
jobs:
bad_target:
name: PR Bad Target
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
with:
comment: >
Thanks for your contribution! Unfortunately we can't accept PRs directed at release branches. We make patches to the bugfix branches and only later do we push them out as releases.
Please redo this PR starting with the `bugfix-2.1.x` branch and be careful to target `bugfix-2.1.x` when resubmitting the PR. Patches may also target `bugfix-2.0.x` if they are specifically for 2.0.9.x.
It may help to set your fork's default branch to `bugfix-2.0.x`.
See [this page](http://marlinfw.org/docs/development/getting_started_pull_requests.html) for full instructions.
+39
View File
@@ -0,0 +1,39 @@
#
# clean-closed.yml
# Remove obsolete labels when an Issue or PR is closed
#
name: Clean Closed
on:
pull_request:
types: [closed]
issues:
types: [closed]
jobs:
remove_label:
runs-on: ubuntu-latest
strategy:
matrix:
label:
- "S: Don't Merge"
- "S: Hold for 2.1"
- "S: Please Merge"
- "S: Please Test"
- "help wanted"
- "Needs: Discussion"
- "Needs: Documentation"
- "Needs: More Data"
- "Needs: Patch"
- "Needs: Testing"
- "Needs: Work"
steps:
- uses: actions/checkout@v2
- name: Remove Labels
uses: actions-ecosystem/action-remove-labels@v1
with:
github_token: ${{ github.token }}
labels: ${{ matrix.label }}
+28
View File
@@ -0,0 +1,28 @@
#
# close-stale.yml
# Close open issues after a period of inactivity
#
name: Close Stale Issues
on:
schedule:
- cron: "22 1 * * *"
jobs:
stale:
name: Close Stale Issues
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has had no activity in the last 60 days. Please add a reply if you want to keep this issue active, otherwise it will be automatically closed within 10 days.'
days-before-stale: 60
days-before-close: 10
stale-issue-label: 'stale-closing-soon'
exempt-all-assignees: true
exempt-issue-labels: 'Bug: Confirmed !,T: Feature Request,Needs: Discussion,Needs: Documentation,Needs: Patch,Needs: Work,Needs: Testing,help wanted,no-locking'
+32
View File
@@ -0,0 +1,32 @@
#
# lock-closed.yml
# Lock closed issues after a period of inactivity
#
name: Lock Closed Issues
on:
schedule:
- cron: '0 1/13 * * *'
jobs:
lock:
name: Lock Closed Issues
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
with:
github-token: ${{ github.token }}
process-only: 'issues'
issue-lock-inactive-days: '60'
issue-exclude-created-before: ''
issue-exclude-labels: 'no-locking'
issue-lock-labels: ''
issue-lock-comment: >
This issue has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
issue-lock-reason: ''
+2
View File
@@ -9,6 +9,7 @@ on:
pull_request:
branches:
- bugfix-2.0.x
- bugfix-2.1.x
paths-ignore:
- config/**
- data/**
@@ -17,6 +18,7 @@ on:
push:
branches:
- bugfix-2.0.x
- bugfix-2.1.x
paths-ignore:
- config/**
- data/**
+22
View File
@@ -0,0 +1,22 @@
#
# unlock-reopened.yml
# Unlock an issue whenever it is re-opened
#
name: "Unlock reopened issue"
on:
issues:
types: [reopened]
jobs:
unlock:
name: Unlock Reopened
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-latest
steps:
- uses: OSDKDev/unlock-issues@v1.1
with:
repo-token: "${{ secrets.GITHUB_TOKEN }}"
+16 -16
View File
@@ -714,7 +714,7 @@
#if ENABLED(PIDTEMP)
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
// Set/get with G-code: M301 E[extruder number, 0-2]
#if ENABLED(PID_PARAMS_PER_HOTEND)
// Specify up to one value per hotend here, according to your setup.
@@ -765,15 +765,15 @@
//#define MPC_FAN_0_ACTIVE_HOTEND
#endif
#define FILAMENT_HEAT_CAPACITY_PERMM 5.6e-3f // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA).
//#define FILAMENT_HEAT_CAPACITY_PERMM 3.6e-3f // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG).
#define FILAMENT_HEAT_CAPACITY_PERMM { 5.6e-3f } // 0.0056 J/K/mm for 1.75mm PLA (0.0149 J/K/mm for 2.85mm PLA).
//#define FILAMENT_HEAT_CAPACITY_PERMM { 3.6e-3f } // 0.0036 J/K/mm for 1.75mm PETG (0.0094 J/K/mm for 2.85mm PETG).
// Advanced options
#define MPC_SMOOTHING_FACTOR 0.5f // (0.0...1.0) Noisy temperature sensors may need a lower value for stabilization.
#define MPC_MIN_AMBIENT_CHANGE 1.0f // (K/s) Modeled ambient temperature rate of change, when correcting model inaccuracies.
#define MPC_STEADYSTATE 0.5f // (K/s) Temperature change rate for steady state logic to be enforced.
#define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center just above the surface.
#define MPC_TUNING_POS { X_CENTER, Y_CENTER, 1.0f } // (mm) M306 Autotuning position, ideally bed center at first layer height.
#define MPC_TUNING_END_Z 10.0f // (mm) M306 Autotuning final Z position.
#endif
@@ -2040,18 +2040,18 @@
#endif
// Add a menu item to move between bed corners for manual bed adjustment
//#define LEVEL_BED_CORNERS
//#define LCD_BED_TRAMMING
#if ENABLED(LEVEL_BED_CORNERS)
#define LEVEL_CORNERS_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
#define LEVEL_CORNERS_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
#define LEVEL_CORNERS_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
//#define LEVEL_CENTER_TOO // Move to the center after the last corner
//#define LEVEL_CORNERS_USE_PROBE
#if ENABLED(LEVEL_CORNERS_USE_PROBE)
#define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
#define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
//#define LEVEL_CORNERS_AUDIO_FEEDBACK
#if ENABLED(LCD_BED_TRAMMING)
#define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
#define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
//#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
//#define BED_TRAMMING_USE_PROBE
#if ENABLED(BED_TRAMMING_USE_PROBE)
#define BED_TRAMMING_PROBE_TOLERANCE 0.1 // (mm)
#define BED_TRAMMING_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
//#define BED_TRAMMING_AUDIO_FEEDBACK
#endif
/**
@@ -2071,7 +2071,7 @@
* | 1 2 | | 1 4 | | 1 2 | | 2 |
* LF --------- RF LF --------- RF LF --------- RF LF --------- RF
*/
#define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, RB, LB }
#define BED_TRAMMING_LEVELING_ORDER { LF, RF, RB, LB }
#endif
/**
+14 -1
View File
@@ -3689,7 +3689,10 @@
#if ENABLED(SPINDLE_LASER_USE_PWM)
#define SPINDLE_LASER_PWM_INVERT false // Set to "true" if the speed/power goes up when you want it to go slower
#define SPINDLE_LASER_FREQUENCY 2500 // (Hz) Spindle/laser frequency (only on supported HALs: AVR, ESP32, and LPC)
#endif
// ESP32: If SPINDLE_LASER_PWM_PIN is onboard then <=78125Hz. For I2S expander
// the frequency determines the PWM resolution. 2500Hz = 0-100, 977Hz = 0-255, ...
// (250000 / SPINDLE_LASER_FREQUENCY) = max value.
#endif
//#define AIR_EVACUATION // Cutter Vacuum / Laser Blower motor control with G-codes M10-M11
#if ENABLED(AIR_EVACUATION)
@@ -3765,6 +3768,16 @@
#define LASER_TEST_PULSE_MIN 1 // Used with Laser Control Menu
#define LASER_TEST_PULSE_MAX 999 // Caution: Menu may not show more than 3 characters
/**
* Laser Safety Timeout
*
* The laser should be turned off when there is no movement for a period of time.
* Consider material flammability, cut rate, and G-code order when setting this
* value. Too low and it could turn off during a very slow move; too high and
* the material could ignite.
*/
#define LASER_SAFETY_TIMEOUT_MS 1000 // (ms)
/**
* Enable inline laser power to be handled in the planner / stepper routines.
* Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I)
+2 -2
View File
@@ -109,7 +109,7 @@ LIQUID_TWI2 ?= 0
# This defines if Wire is needed
WIRE ?= 0
# This defines if Tone is needed (i.e SPEAKER is defined in Configuration.h)
# This defines if Tone is needed (i.e., SPEAKER is defined in Configuration.h)
# Disabling this (and SPEAKER) saves approximately 350 bytes of memory.
TONE ?= 1
@@ -512,7 +512,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1324)
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# Malyan M180 Mainboard Version 2 (no display function, direct gcode only)
# Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
+2 -2
View File
@@ -28,7 +28,7 @@
/**
* Marlin release version identifier
*/
//#define SHORT_BUILD_VERSION "bugfix-2.0.x"
//#define SHORT_BUILD_VERSION "bugfix-2.1.x"
/**
* Verbose version identifier which should contain a reference to the location
@@ -41,7 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2022-05-17"
//#define STRING_DISTRIBUTION_DATE "2022-06-08"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
+1 -1
View File
@@ -74,7 +74,7 @@
#define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin
void PRINT_ARRAY_NAME(uint8_t x) {
char *name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name);
PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name);
LOOP_L_N(y, MAX_NAME_LENGTH) {
char temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0)
+12 -24
View File
@@ -199,8 +199,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
for (i = 0; i <PageSize >> 2; i++)
pageContents[i] = (((uint32_t*)data)[i]) | (~(pageContents[i] ^ ((uint32_t*)data)[i]));
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM PageWrite ", page);
DEBUG_ECHO_MSG("EEPROM PageWrite ", page);
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
@@ -245,8 +244,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ", page);
DEBUG_ECHO_MSG("EEPROM Unlock failure for page ", page);
return false;
}
@@ -270,8 +268,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Write failure for page ", page);
DEBUG_ECHO_MSG("EEPROM Write failure for page ", page);
return false;
}
@@ -286,8 +283,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
if (memcmp(getFlashStorage(page),data,PageSize)) {
#ifdef EE_EMU_DEBUG
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Verify Write failure for page ", page);
DEBUG_ECHO_MSG("EEPROM Verify Write failure for page ", page);
ee_Dump( page, (uint32_t *)addrflash);
ee_Dump(-page, data);
@@ -325,8 +321,7 @@ static bool ee_PageErase(uint16_t page) {
uint16_t i;
uint32_t addrflash = uint32_t(getFlashStorage(page));
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM PageErase ", page);
DEBUG_ECHO_MSG("EEPROM PageErase ", page);
DEBUG_ECHOLNPGM(" in FLASH address ", (uint32_t)addrflash);
DEBUG_ECHOLNPGM(" base address ", (uint32_t)getFlashStorage(0));
DEBUG_FLUSH();
@@ -370,8 +365,7 @@ static bool ee_PageErase(uint16_t page) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Unlock failure for page ",page);
DEBUG_ECHO_MSG("EEPROM Unlock failure for page ",page);
return false;
}
@@ -394,8 +388,7 @@ static bool ee_PageErase(uint16_t page) {
// Reenable interrupts
__enable_irq();
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Erase failure for page ",page);
DEBUG_ECHO_MSG("EEPROM Erase failure for page ",page);
return false;
}
@@ -410,8 +403,7 @@ static bool ee_PageErase(uint16_t page) {
uint32_t * aligned_src = (uint32_t *) addrflash;
for (i = 0; i < PageSize >> 2; i++) {
if (*aligned_src++ != 0xFFFFFFFF) {
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Verify Erase failure for page ",page);
DEBUG_ECHO_MSG("EEPROM Verify Erase failure for page ",page);
ee_Dump(page, (uint32_t *)addrflash);
return false;
}
@@ -921,8 +913,7 @@ static void ee_Init() {
// If all groups seem to be used, default to first group
if (curGroup >= GroupCount) curGroup = 0;
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Current Group: ",curGroup);
DEBUG_ECHO_MSG("EEPROM Current Group: ",curGroup);
DEBUG_FLUSH();
// Now, validate that all the other group pages are empty
@@ -931,8 +922,7 @@ static void ee_Init() {
for (int page = 0; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(grp * PagesPerGroup + page)) {
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on group ", grp);
DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on group ", grp);
DEBUG_FLUSH();
ee_PageErase(grp * PagesPerGroup + page);
}
@@ -948,15 +938,13 @@ static void ee_Init() {
}
}
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Active page: ", curPage);
DEBUG_ECHO_MSG("EEPROM Active page: ", curPage);
DEBUG_FLUSH();
// Make sure the pages following the first clean one are also clean
for (int page = curPage + 1; page < PagesPerGroup; page++) {
if (!ee_IsPageClean(curGroup * PagesPerGroup + page)) {
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("EEPROM Page ", page, " not clean on active group ", curGroup);
DEBUG_ECHO_MSG("EEPROM Page ", page, " not clean on active group ", curGroup);
DEBUG_FLUSH();
ee_Dump(curGroup * PagesPerGroup + page, getFlashStorage(curGroup * PagesPerGroup + page));
ee_PageErase(curGroup * PagesPerGroup + page);
+38 -12
View File
@@ -65,6 +65,7 @@ portMUX_TYPE MarlinHAL::spinlock = portMUX_INITIALIZER_UNLOCKED;
// ------------------------
uint16_t MarlinHAL::adc_result;
pwm_pin_t MarlinHAL::pwm_pin_data[MAX_EXPANDER_BITS];
// ------------------------
// Private Variables
@@ -330,21 +331,46 @@ int8_t get_pwm_channel(const pin_t pin, const uint32_t freq, const uint16_t res)
}
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=_BV(PWM_RESOLUTION)-1*/, const bool invert/*=false*/) {
const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION);
if (cid >= 0) {
uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1);
ledcWrite(cid, duty);
}
#if ENABLED(I2S_STEPPER_STREAM)
if (pin > 127) {
const uint8_t pinlo = pin & 0x7F;
pwm_pin_t &pindata = pwm_pin_data[pinlo];
const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, pindata.pwm_cycle_ticks);
if (duty == 0 || duty == pindata.pwm_cycle_ticks) { // max or min (i.e., on/off)
pindata.pwm_duty_ticks = 0; // turn off PWM for this pin
duty ? SBI32(i2s_port_data, pinlo) : CBI32(i2s_port_data, pinlo); // set pin level
}
else
pindata.pwm_duty_ticks = duty; // PWM duty count = # of 4µs ticks per full PWM cycle
}
else
#endif
{
const int8_t cid = get_pwm_channel(pin, PWM_FREQUENCY, PWM_RESOLUTION);
if (cid >= 0) {
const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, _BV(PWM_RESOLUTION)-1);
ledcWrite(cid, duty);
}
}
}
int8_t MarlinHAL::set_pwm_frequency(const pin_t pin, const uint32_t f_desired) {
const int8_t cid = channel_for_pin(pin);
if (cid >= 0) {
if (f_desired == ledcReadFreq(cid)) return cid; // no freq change
ledcDetachPin(chan_pin[cid]);
chan_pin[cid] = 0; // remove old freq channel
}
return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one
#if ENABLED(I2S_STEPPER_STREAM)
if (pin > 127) {
pwm_pin_data[pin & 0x7F].pwm_cycle_ticks = 1000000UL / f_desired / 4; // # of 4µs ticks per full PWM cycle
return 0;
}
else
#endif
{
const int8_t cid = channel_for_pin(pin);
if (cid >= 0) {
if (f_desired == ledcReadFreq(cid)) return cid; // no freq change
ledcDetachPin(chan_pin[cid]);
chan_pin[cid] = 0; // remove old freq channel
}
return get_pwm_channel(pin, f_desired, PWM_RESOLUTION); // try for new one
}
}
// use hardware PWM if avail, if not then ISR
+11
View File
@@ -68,6 +68,9 @@
#define PWM_RESOLUTION 10u // Default PWM bit resolution
#define CHANNEL_MAX_NUM 15u // max PWM channel # to allocate (7 to only use low speed, 15 to use low & high)
#define MAX_PWM_IOPIN 33u // hardware pwm pins < 34
#ifndef MAX_EXPANDER_BITS
#define MAX_EXPANDER_BITS 32 // I2S expander bit width (max 32)
#endif
// ------------------------
// Types
@@ -76,6 +79,12 @@
typedef double isr_float_t; // FPU ops are used for single-precision, so use double for ISRs.
typedef int16_t pin_t;
typedef struct pwm_pin {
uint32_t pwm_cycle_ticks = 1000000UL / (PWM_FREQUENCY) / 4; // # ticks per pwm cycle
uint32_t pwm_tick_count = 0; // current tick count
uint32_t pwm_duty_ticks = 0; // # of ticks for current duty cycle
} pwm_pin_t;
class Servo;
typedef Servo hal_servo_t;
@@ -197,6 +206,8 @@ public:
// Free SRAM
static int freeMemory();
static pwm_pin_t pwm_pin_data[MAX_EXPANDER_BITS];
//
// ADC Methods
//
+20
View File
@@ -337,6 +337,26 @@ uint8_t i2s_state(uint8_t pin) {
}
void i2s_push_sample() {
// Every 4µs (when space in DMA buffer) toggle each expander PWM output using
// the current duty cycle/frequency so they sync with any steps (once
// through the DMA/FIFO buffers). PWM signal inversion handled by other functions
LOOP_L_N(p, MAX_EXPANDER_BITS) {
if (hal.pwm_pin_data[p].pwm_duty_ticks > 0) { // pin has active pwm?
if (hal.pwm_pin_data[p].pwm_tick_count == 0) {
if (TEST32(i2s_port_data, p)) { // hi->lo
CBI32(i2s_port_data, p);
hal.pwm_pin_data[p].pwm_tick_count = hal.pwm_pin_data[p].pwm_cycle_ticks - hal.pwm_pin_data[p].pwm_duty_ticks;
}
else { // lo->hi
SBI32(i2s_port_data, p);
hal.pwm_pin_data[p].pwm_tick_count = hal.pwm_pin_data[p].pwm_duty_ticks;
}
}
else
hal.pwm_pin_data[p].pwm_tick_count--;
}
}
dma.current[dma.rw_pos++] = i2s_port_data;
}
@@ -20,3 +20,10 @@
*
*/
#pragma once
//
// Board-specific options need to be defined before HAL.h
//
#if MB(MKS_TINYBEE)
#define MAX_EXPANDER_BITS 24 // TinyBee has 3 x HC595
#endif
+4
View File
@@ -48,3 +48,7 @@
#if USING_PULLDOWNS
#error "PULLDOWN pin mode is not available on ESP32 boards."
#endif
#if BOTH(I2S_STEPPER_STREAM, LIN_ADVANCE)
#error "I2S stream is currently incompatible with LIN_ADVANCE."
#endif
+7 -14
View File
@@ -23,24 +23,17 @@
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfigPre.h"
#include "../../inc/MarlinConfig.h"
#if EITHER(MKS_MINI_12864, FYSETC_MINI_12864_2_1)
#include <U8glib-HAL.h>
#include "Arduino.h"
#include "../shared/HAL_SPI.h"
#include "HAL.h"
#include "SPI.h"
static SPISettings spiConfig;
#define MDOGLCD_MOSI 23
#define MDOGLCD_SCK 18
#define MLCD_RESET_PIN 0
#define MLCD_PINS_DC 4
#define MDOGLCD_CS 21
#define MDOGLCD_A0 4
#ifndef LCD_SPI_SPEED
#ifdef SD_SPI_SPEED
@@ -61,24 +54,24 @@ uint8_t u8g_eps_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_pt
case U8G_COM_MSG_STOP: break;
case U8G_COM_MSG_INIT:
OUT_WRITE(MDOGLCD_CS, HIGH);
OUT_WRITE(MDOGLCD_A0, HIGH);
OUT_WRITE(MLCD_RESET_PIN, HIGH);
OUT_WRITE(DOGLCD_CS, HIGH);
OUT_WRITE(DOGLCD_A0, HIGH);
OUT_WRITE(LCD_RESET_PIN, HIGH);
u8g_Delay(5);
spiBegin();
spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
WRITE(MDOGLCD_A0, arg_val ? HIGH : LOW);
WRITE(DOGLCD_A0, arg_val ? HIGH : LOW);
break;
case U8G_COM_MSG_CHIP_SELECT: /* arg_val == 0 means HIGH level of U8G_PI_CS */
WRITE(MDOGLCD_CS, arg_val ? LOW : HIGH);
WRITE(DOGLCD_CS, arg_val ? LOW : HIGH);
break;
case U8G_COM_MSG_RESET:
WRITE(MLCD_RESET_PIN, arg_val);
WRITE(LCD_RESET_PIN, arg_val);
break;
case U8G_COM_MSG_WRITE_BYTE:
+1 -1
View File
@@ -598,7 +598,7 @@ void MarlinHAL::dma_init() {
void MarlinHAL::init() {
TERN_(DMA_IS_REQUIRED, dma_init());
#if ENABLED(SDSUPPORT)
#if SD_CONNECTION_IS(ONBOARD) && PIN_EXISTS(SD_DETECT)
#if HAS_SD_DETECT && SD_CONNECTION_IS(ONBOARD)
SET_INPUT_PULLUP(SD_DETECT_PIN);
#endif
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
+4 -4
View File
@@ -57,7 +57,7 @@ public:
auto sd2card = diskIODriver();
// single block
if (blkLen == 1) {
watchdog_refresh();
hal.watchdog_refresh();
sd2card->writeBlock(blkAddr, pBuf);
return true;
}
@@ -65,7 +65,7 @@ public:
// multi block optimization
sd2card->writeStart(blkAddr, blkLen);
while (blkLen--) {
watchdog_refresh();
hal.watchdog_refresh();
sd2card->writeData(pBuf);
pBuf += BLOCK_SIZE;
}
@@ -77,7 +77,7 @@ public:
auto sd2card = diskIODriver();
// single block
if (blkLen == 1) {
watchdog_refresh();
hal.watchdog_refresh();
sd2card->readBlock(blkAddr, pBuf);
return true;
}
@@ -85,7 +85,7 @@ public:
// multi block optimization
sd2card->readStart(blkAddr);
while (blkLen--) {
watchdog_refresh();
hal.watchdog_refresh();
sd2card->readData(pBuf);
pBuf += BLOCK_SIZE;
}
+173 -225
View File
@@ -35,42 +35,15 @@
// use local drivers
#if defined(STM32F103xE) || defined(STM32F103xG)
#include <stm32f1xx_hal_rcc_ex.h>
#include <stm32f1xx_hal_sd.h>
#include <stm32f1xx.h>
#elif defined(STM32F4xx)
#include <stm32f4xx_hal_rcc.h>
#include <stm32f4xx_hal_dma.h>
#include <stm32f4xx_hal_gpio.h>
#include <stm32f4xx_hal_sd.h>
#include <stm32f4xx.h>
#elif defined(STM32F7xx)
#include <stm32f7xx_hal_rcc.h>
#include <stm32f7xx_hal_dma.h>
#include <stm32f7xx_hal_gpio.h>
#include <stm32f7xx_hal_sd.h>
#include <stm32f7xx.h>
#elif defined(STM32H7xx)
#include <stm32h7xx.h>
#else
#error "SDIO only supported with STM32F103xE, STM32F103xG, STM32F4xx, or STM32F7xx."
#endif
SD_HandleTypeDef hsd; // create SDIO structure
// F4 supports one DMA for RX and another for TX, but Marlin will never
// do read and write at same time, so we use the same DMA for both.
DMA_HandleTypeDef hdma_sdio;
/*
SDIO_INIT_CLK_DIV is 118
SDIO clock frequency is 48MHz / (TRANSFER_CLOCK_DIV + 2)
SDIO init clock frequency should not exceed 400kHz = 48MHz / (118 + 2)
Default TRANSFER_CLOCK_DIV is 2 (118 / 40)
Default SDIO clock frequency is 48MHz / (2 + 2) = 12 MHz
This might be too fast for stable SDIO operations
MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency
Additional testing is required as there are clearly some 4bit initialization problems
*/
#ifndef USBD_OK
#define USBD_OK 0
#error "SDIO only supported with STM32F103xE, STM32F103xG, STM32F4xx, STM32F7xx, or STM32H7xx."
#endif
// Target Clock, configurable. Default is 18MHz, from STM32F1
@@ -78,223 +51,209 @@ DMA_HandleTypeDef hdma_sdio;
#define SDIO_CLOCK 18000000 // 18 MHz
#endif
// SDIO retries, configurable. Default is 3, from STM32F1
#ifndef SDIO_READ_RETRIES
#define SDIO_READ_RETRIES 3
#endif
#define SD_TIMEOUT 1000 // ms
// SDIO Max Clock (naming from STM Manual, don't change)
#define SDIOCLK 48000000
static uint32_t clock_to_divider(uint32_t clk) {
// limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals
// Also limited to no more than 48Mhz (SDIOCLK).
const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
clk = min(clk, (uint32_t)(pclk2 * 8 / 3));
clk = min(clk, (uint32_t)SDIOCLK);
// Round up divider, so we don't run the card over the speed supported,
// and subtract by 2, because STM32 will add 2, as written in the manual:
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
return pclk2 / clk + (pclk2 % clk != 0) - 2;
#if defined(STM32F1xx)
DMA_HandleTypeDef hdma_sdio;
extern "C" void DMA2_Channel4_5_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_sdio);
}
#elif defined(STM32F4xx)
DMA_HandleTypeDef hdma_sdio_rx;
DMA_HandleTypeDef hdma_sdio_tx;
extern "C" void DMA2_Stream3_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_sdio_rx);
}
extern "C" void DMA2_Stream6_IRQHandler(void) {
HAL_DMA_IRQHandler(&hdma_sdio_tx);
}
#elif defined(STM32H7xx)
#define __HAL_RCC_SDIO_FORCE_RESET __HAL_RCC_SDMMC1_FORCE_RESET
#define __HAL_RCC_SDIO_RELEASE_RESET __HAL_RCC_SDMMC1_RELEASE_RESET
#define __HAL_RCC_SDIO_CLK_ENABLE __HAL_RCC_SDMMC1_CLK_ENABLE
#define SDIO SDMMC1
#define SDIO_IRQn SDMMC1_IRQn
#define SDIO_IRQHandler SDMMC1_IRQHandler
#define SDIO_CLOCK_EDGE_RISING SDMMC_CLOCK_EDGE_RISING
#define SDIO_CLOCK_POWER_SAVE_DISABLE SDMMC_CLOCK_POWER_SAVE_DISABLE
#define SDIO_BUS_WIDE_1B SDMMC_BUS_WIDE_1B
#define SDIO_BUS_WIDE_4B SDMMC_BUS_WIDE_4B
#define SDIO_HARDWARE_FLOW_CONTROL_DISABLE SDMMC_HARDWARE_FLOW_CONTROL_DISABLE
#endif
uint8_t waitingRxCplt = 0;
uint8_t waitingTxCplt = 0;
SD_HandleTypeDef hsd;
extern "C" void SDIO_IRQHandler(void) {
HAL_SD_IRQHandler(&hsd);
}
void go_to_transfer_speed() {
/* Default SDIO peripheral configuration for SD card initialization */
hsd.Init.ClockEdge = hsd.Init.ClockEdge;
hsd.Init.ClockBypass = hsd.Init.ClockBypass;
hsd.Init.ClockPowerSave = hsd.Init.ClockPowerSave;
hsd.Init.BusWide = hsd.Init.BusWide;
hsd.Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
/* Initialize SDIO peripheral interface with default configuration */
SDIO_Init(hsd.Instance, hsd.Init);
void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsdio) {
waitingTxCplt = 0;
}
void SD_LowLevel_Init(void) {
uint32_t tempreg;
__HAL_RCC_GPIOC_CLK_ENABLE(); //enable GPIO clocks
__HAL_RCC_GPIOD_CLK_ENABLE(); //enable GPIO clocks
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = 1; //GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
#if DISABLED(STM32F1xx)
GPIO_InitStruct.Alternate = GPIO_AF12_SDIO;
#endif
GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_12; // D0 & SCK
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsdio) {
waitingRxCplt = 0;
}
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
pinmap_pinout(PC_12, PinMap_SD);
pinmap_pinout(PD_2, PinMap_SD);
pinmap_pinout(PC_8, PinMap_SD);
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // define D1-D3 only if have a four bit wide SDIO bus
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11; // D1-D3
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
// D1-D3
pinmap_pinout(PC_9, PinMap_SD);
pinmap_pinout(PC_10, PinMap_SD);
pinmap_pinout(PC_11, PinMap_SD);
#endif
// Configure PD.02 CMD line
GPIO_InitStruct.Pin = GPIO_PIN_2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
// Setup DMA
#if defined(STM32F1xx)
hdma_sdio.Init.Mode = DMA_NORMAL;
hdma_sdio.Instance = DMA2_Channel4;
HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
#elif defined(STM32F4xx)
hdma_sdio.Init.Mode = DMA_PFCTRL;
hdma_sdio.Instance = DMA2_Stream3;
hdma_sdio.Init.Channel = DMA_CHANNEL_4;
hdma_sdio.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
#endif
__HAL_RCC_SDIO_CLK_ENABLE();
HAL_NVIC_EnableIRQ(SDIO_IRQn);
hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
__HAL_LINKDMA(&hsd, hdmarx, hdma_sdio);
__HAL_LINKDMA(&hsd, hdmatx, hdma_sdio);
// DMA Config
#if defined(STM32F1xx)
__HAL_RCC_SDIO_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
#else
__HAL_RCC_SDIO_FORCE_RESET();
delay(2);
__HAL_RCC_SDIO_RELEASE_RESET();
delay(2);
__HAL_RCC_SDIO_CLK_ENABLE();
HAL_NVIC_EnableIRQ(DMA2_Channel4_5_IRQn);
hdma_sdio.Instance = DMA2_Channel4;
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio.Init.Mode = DMA_NORMAL;
hdma_sdio.Init.Priority = DMA_PRIORITY_LOW;
HAL_DMA_Init(&hdma_sdio);
__HAL_RCC_DMA2_FORCE_RESET();
delay(2);
__HAL_RCC_DMA2_RELEASE_RESET();
delay(2);
__HAL_LINKDMA(hsd, hdmarx ,hdma_sdio);
__HAL_LINKDMA(hsd, hdmatx, hdma_sdio);
#elif defined(STM32F4xx)
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_NVIC_EnableIRQ(DMA2_Stream3_IRQn);
HAL_NVIC_EnableIRQ(DMA2_Stream6_IRQn);
hdma_sdio_rx.Instance = DMA2_Stream3;
hdma_sdio_rx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdio_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_rx.Init.Mode = DMA_PFCTRL;
hdma_sdio_rx.Init.Priority = DMA_PRIORITY_LOW;
hdma_sdio_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_rx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_rx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&hdma_sdio_rx);
__HAL_LINKDMA(hsd,hdmarx,hdma_sdio_rx);
hdma_sdio_tx.Instance = DMA2_Stream6;
hdma_sdio_tx.Init.Channel = DMA_CHANNEL_4;
hdma_sdio_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sdio_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdio_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdio_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdio_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdio_tx.Init.Mode = DMA_PFCTRL;
hdma_sdio_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_sdio_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_sdio_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_sdio_tx.Init.MemBurst = DMA_MBURST_INC4;
hdma_sdio_tx.Init.PeriphBurst = DMA_PBURST_INC4;
HAL_DMA_Init(&hdma_sdio_tx);
__HAL_LINKDMA(hsd,hdmatx,hdma_sdio_tx);
#endif
//Initialize the SDIO (with initial <400Khz Clock)
tempreg = 0; //Reset value
tempreg |= SDIO_CLKCR_CLKEN; // Clock enabled
tempreg |= SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
// Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable
SDIO->CLKCR = tempreg;
// Power up the SDIO
SDIO_PowerState_ON(SDIO);
hsd.Instance = SDIO;
}
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
UNUSED(hsd); // Prevent unused argument(s) compilation warning
__HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock
void HAL_SD_MspDeInit(SD_HandleTypeDef *hsd) {
#if !defined(STM32F1xx)
__HAL_RCC_SDIO_FORCE_RESET();
delay(10);
__HAL_RCC_SDIO_RELEASE_RESET();
delay(10);
#endif
}
static uint32_t clock_to_divider(uint32_t clk) {
#if defined(STM32H7xx)
// SDMMC_CK frequency = sdmmc_ker_ck / [2 * CLKDIV].
uint32_t sdmmc_clk = HAL_RCCEx_GetPeriphCLKFreq(RCC_PERIPHCLK_SDMMC);
return sdmmc_clk / (2U * SDIO_CLOCK) + (sdmmc_clk % (2U * SDIO_CLOCK) != 0);
#else
// limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals
// Also limited to no more than 48Mhz (SDIOCLK).
const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
clk = min(clk, (uint32_t)(pclk2 * 8 / 3));
clk = min(clk, (uint32_t)SDIOCLK);
// Round up divider, so we don't run the card over the speed supported,
// and subtract by 2, because STM32 will add 2, as written in the manual:
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
return pclk2 / clk + (pclk2 % clk != 0) - 2;
#endif
}
bool SDIO_Init() {
uint8_t retryCnt = SDIO_READ_RETRIES;
HAL_StatusTypeDef sd_state = HAL_OK;
if (hsd.Instance == SDIO)
HAL_SD_DeInit(&hsd);
bool status;
/* HAL SD initialization */
hsd.Instance = SDIO;
hsd.State = HAL_SD_STATE_RESET;
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
sd_state = HAL_SD_Init(&hsd);
SD_LowLevel_Init();
uint8_t retry_Cnt = retryCnt;
for (;;) {
hal.watchdog_refresh();
status = (bool) HAL_SD_Init(&hsd);
if (!status) break;
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
}
go_to_transfer_speed();
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3) // go to 4 bit wide mode if pins are defined
retry_Cnt = retryCnt;
for (;;) {
hal.watchdog_refresh();
if (!HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B)) break; // some cards are only 1 bit wide so a pass here is not required
if (!--retry_Cnt) break;
}
if (!retry_Cnt) { // wide bus failed, go back to one bit wide mode
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
SD_LowLevel_Init();
retry_Cnt = retryCnt;
for (;;) {
hal.watchdog_refresh();
status = (bool) HAL_SD_Init(&hsd);
if (!status) break;
if (!--retry_Cnt) return false; // return failing status if retries are exhausted
}
go_to_transfer_speed();
#if PINS_EXIST(SDIO_D1, SDIO_D2, SDIO_D3)
if (sd_state == HAL_OK) {
sd_state = HAL_SD_ConfigWideBusOperation(&hsd, SDIO_BUS_WIDE_4B);
}
#endif
return true;
}
static bool SDIO_ReadWriteBlock_DMA(uint32_t block, const uint8_t *src, uint8_t *dst) {
if (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) return false;
hal.watchdog_refresh();
HAL_StatusTypeDef ret;
if (src) {
hdma_sdio.Init.Direction = DMA_MEMORY_TO_PERIPH;
HAL_DMA_Init(&hdma_sdio);
ret = HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1);
}
else {
hdma_sdio.Init.Direction = DMA_PERIPH_TO_MEMORY;
HAL_DMA_Init(&hdma_sdio);
ret = HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1);
}
if (ret != HAL_OK) {
HAL_DMA_Abort_IT(&hdma_sdio);
HAL_DMA_DeInit(&hdma_sdio);
return false;
}
millis_t timeout = millis() + 500;
// Wait the transfer
while (hsd.State != HAL_SD_STATE_READY) {
if (ELAPSED(millis(), timeout)) {
HAL_DMA_Abort_IT(&hdma_sdio);
HAL_DMA_DeInit(&hdma_sdio);
return false;
}
}
while (__HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TC_FLAG_INDEX(&hdma_sdio)) != 0
|| __HAL_DMA_GET_FLAG(&hdma_sdio, __HAL_DMA_GET_TE_FLAG_INDEX(&hdma_sdio)) != 0) { /* nada */ }
HAL_DMA_Abort_IT(&hdma_sdio);
HAL_DMA_DeInit(&hdma_sdio);
timeout = millis() + 500;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) if (ELAPSED(millis(), timeout)) return false;
return true;
return (sd_state == HAL_OK) ? true : false;
}
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
uint8_t retries = SDIO_READ_RETRIES;
while (retries--) if (SDIO_ReadWriteBlock_DMA(block, nullptr, dst)) return true;
return false;
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER) {
if (HAL_GetTick() >= timeout) return false;
}
waitingRxCplt = 1;
if (HAL_SD_ReadBlocks_DMA(&hsd, (uint8_t *)dst, block, 1) != HAL_OK)
return false;
timeout = HAL_GetTick() + SD_TIMEOUT;
while (waitingRxCplt)
if (HAL_GetTick() >= timeout) return false;
return true;
}
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
uint8_t retries = SDIO_READ_RETRIES;
while (retries--) if (SDIO_ReadWriteBlock_DMA(block, src, nullptr)) return true;
return false;
uint32_t timeout = HAL_GetTick() + SD_TIMEOUT;
while (HAL_SD_GetCardState(&hsd) != HAL_SD_CARD_TRANSFER)
if (HAL_GetTick() >= timeout) return false;
waitingTxCplt = 1;
if (HAL_SD_WriteBlocks_DMA(&hsd, (uint8_t *)src, block, 1) != HAL_OK)
return false;
timeout = HAL_GetTick() + SD_TIMEOUT;
while (waitingTxCplt)
if (HAL_GetTick() >= timeout) return false;
return true;
}
bool SDIO_IsReady() {
@@ -305,16 +264,5 @@ uint32_t SDIO_GetCardSize() {
return (uint32_t)(hsd.SdCard.BlockNbr) * (hsd.SdCard.BlockSize);
}
#if defined(STM32F1xx)
#define DMA_IRQ_HANDLER DMA2_Channel4_5_IRQHandler
#elif defined(STM32F4xx)
#define DMA_IRQ_HANDLER DMA2_Stream3_IRQHandler
#else
#error "Unknown STM32 architecture."
#endif
extern "C" void SDIO_IRQHandler(void) { HAL_SD_IRQHandler(&hsd); }
extern "C" void DMA_IRQ_HANDLER(void) { HAL_DMA_IRQHandler(&hdma_sdio); }
#endif // SDIO_SUPPORT
#endif // HAL_STM32
+1 -1
View File
@@ -30,7 +30,7 @@ SPIClass TFT_SPI::SPIx(1);
void TFT_SPI::Init() {
#if PIN_EXISTS(TFT_RESET)
OUT_WRITE(TFT_RST_PIN, HIGH);
OUT_WRITE(TFT_RESET_PIN, HIGH);
delay(100);
#endif
@@ -221,7 +221,7 @@ bool resume_from_fault() {
// So we'll just need to refresh the watchdog for a while and then stop for the system to reboot
uint32_t last = start;
while (PENDING(last, end)) {
watchdog_refresh();
hal.watchdog_refresh();
while (millis() == last) { /* nada */ }
last = millis();
MinSerial::TX('.');
+36 -35
View File
@@ -423,37 +423,38 @@ inline void manage_inactivity(const bool no_stepper_sleep=false) {
kill();
}
const bool has_blocks = planner.has_blocks_queued(); // Any moves in the planner?
if (has_blocks) gcode.reset_stepper_timeout(ms); // Reset timeout for M18/M84, M85 max 'kill', and laser.
// M18 / M84 : Handle steppers inactive time timeout
if (gcode.stepper_inactive_time) {
#if HAS_DISABLE_INACTIVE_AXIS
if (gcode.stepper_inactive_time) {
static bool already_shutdown_steppers; // = false
static bool already_shutdown_steppers; // = false
// Any moves in the planner? Resets both the M18/M84
// activity timeout and the M85 max 'kill' timeout
if (planner.has_blocks_queued())
gcode.reset_stepper_timeout(ms);
else if (!do_reset_timeout && gcode.stepper_inactive_timeout()) {
if (!already_shutdown_steppers) {
already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this
if (!has_blocks && !do_reset_timeout && gcode.stepper_inactive_timeout()) {
if (!already_shutdown_steppers) {
already_shutdown_steppers = true; // L6470 SPI will consume 99% of free time without this
// Individual axes will be disabled if configured
TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS));
TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS));
TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS));
TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS));
TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS));
TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS));
TERN_(DISABLE_INACTIVE_U, stepper.disable_axis(U_AXIS));
TERN_(DISABLE_INACTIVE_V, stepper.disable_axis(V_AXIS));
TERN_(DISABLE_INACTIVE_W, stepper.disable_axis(W_AXIS));
TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers());
// Individual axes will be disabled if configured
TERN_(DISABLE_INACTIVE_X, stepper.disable_axis(X_AXIS));
TERN_(DISABLE_INACTIVE_Y, stepper.disable_axis(Y_AXIS));
TERN_(DISABLE_INACTIVE_Z, stepper.disable_axis(Z_AXIS));
TERN_(DISABLE_INACTIVE_I, stepper.disable_axis(I_AXIS));
TERN_(DISABLE_INACTIVE_J, stepper.disable_axis(J_AXIS));
TERN_(DISABLE_INACTIVE_K, stepper.disable_axis(K_AXIS));
TERN_(DISABLE_INACTIVE_U, stepper.disable_axis(U_AXIS));
TERN_(DISABLE_INACTIVE_V, stepper.disable_axis(V_AXIS));
TERN_(DISABLE_INACTIVE_W, stepper.disable_axis(W_AXIS));
TERN_(DISABLE_INACTIVE_E, stepper.disable_e_steppers());
TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled());
TERN_(AUTO_BED_LEVELING_UBL, bedlevel.steppers_were_disabled());
}
}
else
already_shutdown_steppers = false;
}
else
already_shutdown_steppers = false;
}
#endif
#if ENABLED(PHOTO_GCODE) && PIN_EXISTS(CHDK)
// Check if CHDK should be set to LOW (after M240 set it HIGH)
@@ -1241,6 +1242,17 @@ void setup() {
SETUP_RUN(tmc_serial_begin());
#endif
#if HAS_TMC_SPI
#if DISABLED(TMC_USE_SW_SPI)
SETUP_RUN(SPI.begin());
#endif
SETUP_RUN(tmc_init_cs_pins());
#endif
#if HAS_L64XX
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#endif
#if ENABLED(PSU_CONTROL)
SETUP_LOG("PSU_CONTROL");
powerManager.init();
@@ -1250,21 +1262,10 @@ void setup() {
SETUP_RUN(recovery.setup());
#endif
#if HAS_L64XX
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#endif
#if HAS_STEPPER_RESET
SETUP_RUN(disableStepperDrivers());
#endif
#if HAS_TMC_SPI
#if DISABLED(TMC_USE_SW_SPI)
SETUP_RUN(SPI.begin());
#endif
SETUP_RUN(tmc_init_cs_pins());
#endif
SETUP_RUN(hal.init_board());
SETUP_RUN(esp_wifi_init());
+22 -20
View File
@@ -161,7 +161,7 @@
#define BOARD_PICA_REVB 1324 // PICA Shield (original version)
#define BOARD_PICA 1325 // PICA Shield (rev C or later)
#define BOARD_INTAMSYS40 1326 // Intamsys 4.0 (Funmat HT)
#define BOARD_MALYAN_M180 1327 // Malyan M180 Mainboard Version 2 (no display function, direct gcode only)
#define BOARD_MALYAN_M180 1327 // Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
#define BOARD_GT2560_V4_A20 1328 // Geeetech GT2560 Rev B for A20(M/T/D)
#define BOARD_PROTONEER_CNC_SHIELD_V3 1329 // Mega controller & Protoneer CNC Shield V3.00
#define BOARD_WEEDO_62A 1330 // WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
@@ -228,33 +228,33 @@
#define BOARD_RAMPS_14_RE_ARM_EFF 2002 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS_14_RE_ARM_EEF 2003 // Re-ARM with RAMPS 1.4 (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS_14_RE_ARM_SF 2004 // Re-ARM with RAMPS 1.4 (Power outputs: Spindle, Controller Fan)
#define BOARD_MKS_SBASE 2005 // MKS-Sbase (Power outputs: Hotend0, Hotend1, Bed, Fan)
#define BOARD_MKS_SBASE 2005 // MKS-Sbase
#define BOARD_AZSMZ_MINI 2006 // AZSMZ Mini
#define BOARD_BIQU_BQ111_A4 2007 // BIQU BQ111-A4 (Power outputs: Hotend, Fan, Bed)
#define BOARD_SELENA_COMPACT 2008 // Selena Compact (Power outputs: Hotend0, Hotend1, Bed0, Bed1, Fan0, Fan1)
#define BOARD_BIQU_B300_V1_0 2009 // BIQU B300_V1.0 (Power outputs: Hotend0, Fan, Bed, SPI Driver)
#define BOARD_MKS_SGEN_L 2010 // MKS-SGen-L (Power outputs: Hotend0, Hotend1, Bed, Fan)
#define BOARD_BIQU_BQ111_A4 2007 // BIQU BQ111-A4
#define BOARD_SELENA_COMPACT 2008 // Selena Compact
#define BOARD_BIQU_B300_V1_0 2009 // BIQU B300_V1.0
#define BOARD_MKS_SGEN_L 2010 // MKS-SGen-L
#define BOARD_GMARSH_X6_REV1 2011 // GMARSH X6, revision 1 prototype
#define BOARD_BTT_SKR_V1_1 2012 // BigTreeTech SKR v1.1 (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_BTT_SKR_V1_3 2013 // BigTreeTech SKR v1.3 (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_BTT_SKR_V1_4 2014 // BigTreeTech SKR v1.4 (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_BTT_SKR_V1_1 2012 // BigTreeTech SKR v1.1
#define BOARD_BTT_SKR_V1_3 2013 // BigTreeTech SKR v1.3
#define BOARD_BTT_SKR_V1_4 2014 // BigTreeTech SKR v1.4
//
// LPC1769 ARM Cortex M3
//
#define BOARD_MKS_SGEN 2500 // MKS-SGen (Power outputs: Hotend0, Hotend1, Bed, Fan)
#define BOARD_AZTEEG_X5_GT 2501 // Azteeg X5 GT (Power outputs: Hotend0, Hotend1, Bed, Fan)
#define BOARD_AZTEEG_X5_MINI 2502 // Azteeg X5 Mini (Power outputs: Hotend0, Bed, Fan)
#define BOARD_AZTEEG_X5_MINI_WIFI 2503 // Azteeg X5 Mini Wifi (Power outputs: Hotend0, Bed, Fan)
#define BOARD_MKS_SGEN 2500 // MKS-SGen
#define BOARD_AZTEEG_X5_GT 2501 // Azteeg X5 GT
#define BOARD_AZTEEG_X5_MINI 2502 // Azteeg X5 Mini
#define BOARD_AZTEEG_X5_MINI_WIFI 2503 // Azteeg X5 Mini Wifi
#define BOARD_COHESION3D_REMIX 2504 // Cohesion3D ReMix
#define BOARD_COHESION3D_MINI 2505 // Cohesion3D Mini
#define BOARD_SMOOTHIEBOARD 2506 // Smoothieboard
#define BOARD_TH3D_EZBOARD 2507 // TH3D EZBoard v1.0
#define BOARD_BTT_SKR_V1_4_TURBO 2508 // BigTreeTech SKR v1.4 TURBO (Power outputs: Hotend0, Hotend1, Fan, Bed)
#define BOARD_MKS_SGEN_L_V2 2509 // MKS SGEN_L V2 (Power outputs: Hotend0, Hotend1, Bed, Fan)
#define BOARD_BTT_SKR_E3_TURBO 2510 // BigTreeTech SKR E3 Turbo (Power outputs: Hotend0, Hotend1, Bed, Fan0, Fan1)
#define BOARD_FLY_CDY 2511 // FLYmaker FLY CDY (Power outputs: Hotend0, Hotend1, Hotend2, Bed, Fan0, Fan1, Fan2)
#define BOARD_BTT_SKR_V1_4_TURBO 2508 // BigTreeTech SKR v1.4 TURBO
#define BOARD_MKS_SGEN_L_V2 2509 // MKS SGEN_L V2
#define BOARD_BTT_SKR_E3_TURBO 2510 // BigTreeTech SKR E3 Turbo
#define BOARD_FLY_CDY 2511 // FLYmaker FLY CDY
//
// SAM3X8E ARM Cortex M3
@@ -280,8 +280,8 @@
#define BOARD_RAMPS4DUE_EFF 3017 // RAMPS4DUE (Power outputs: Hotend, Fan0, Fan1)
#define BOARD_RAMPS4DUE_EEF 3018 // RAMPS4DUE (Power outputs: Hotend0, Hotend1, Fan)
#define BOARD_RAMPS4DUE_SF 3019 // RAMPS4DUE (Power outputs: Spindle, Controller Fan)
#define BOARD_RURAMPS4D_11 3020 // RuRAMPS4Duo v1.1 (Power outputs: Hotend0, Hotend1, Hotend2, Fan0, Fan1, Bed)
#define BOARD_RURAMPS4D_13 3021 // RuRAMPS4Duo v1.3 (Power outputs: Hotend0, Hotend1, Hotend2, Fan0, Fan1, Bed)
#define BOARD_RURAMPS4D_11 3020 // RuRAMPS4Duo v1.1
#define BOARD_RURAMPS4D_13 3021 // RuRAMPS4Duo v1.3
#define BOARD_ULTRATRONICS_PRO 3022 // ReprapWorld Ultratronics Pro V1.0
#define BOARD_ARCHIM1 3023 // UltiMachine Archim1 (with DRV8825 drivers)
#define BOARD_ARCHIM2 3024 // UltiMachine Archim2 (with TMC2130 drivers)
@@ -293,7 +293,7 @@
// SAM3X8C ARM Cortex M3
//
#define BOARD_PRINTRBOARD_G2 3100 // PRINTRBOARD G2
#define BOARD_PRINTRBOARD_G2 3100 // Printrboard G2
#define BOARD_ADSK 3101 // Arduino DUE Shield Kit (ADSK)
//
@@ -429,6 +429,8 @@
#define BOARD_T41U5XBB 5002 // T41U5XBB Teensy 4.1 breakout board
#define BOARD_NUCLEO_F767ZI 5003 // ST NUCLEO-F767ZI Dev Board
#define BOARD_BTT_SKR_SE_BX 5004 // BigTreeTech SKR SE BX (STM32H743II)
#define BOARD_BTT_SKR_V3_0 5005 // BigTreeTech SKR V3.0 (STM32H743VG)
#define BOARD_BTT_SKR_V3_0_EZ 5006 // BigTreeTech SKR V3.0 EZ (STM32H743VG)
//
// Espressif ESP32 WiFi
+19 -10
View File
@@ -712,13 +712,22 @@
#define RREPEAT2_S(S,N,OP,V...) EVAL1024(_RREPEAT2(S,SUB##S(N),OP,V))
#define RREPEAT2(N,OP,V...) RREPEAT2_S(0,N,OP,V)
// See https://github.com/swansontec/map-macro
#define MAP_OUT
#define MAP_END(...)
#define MAP_GET_END() 0, MAP_END
#define MAP_NEXT0(test, next, ...) next MAP_OUT
#define MAP_NEXT1(test, next) MAP_NEXT0 (test, next, 0)
#define MAP_NEXT(test, next) MAP_NEXT1 (MAP_GET_END test, next)
#define MAP0(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP1) (f, peek, __VA_ARGS__)
#define MAP1(f, x, peek, ...) f(x) MAP_NEXT (peek, MAP0) (f, peek, __VA_ARGS__)
#define MAP(f, ...) EVAL512 (MAP1 (f, __VA_ARGS__, (), 0))
// Call OP(A) with each item as an argument
#define _MAP(_MAP_OP,A,V...) \
_MAP_OP(A) \
IF_ELSE(HAS_ARGS(V)) \
( DEFER2(__MAP)()(_MAP_OP,V) ) \
( /* Do nothing */ )
#define __MAP() _MAP
#define MAP(OP,V...) EVAL(_MAP(OP,V))
// Emit a list of OP(A) with the given items
#define _MAPLIST(_MAP_OP,A,V...) \
_MAP_OP(A) \
IF_ELSE(HAS_ARGS(V)) \
( , DEFER2(__MAPLIST)()(_MAP_OP,V) ) \
( /* Do nothing */ )
#define __MAPLIST() _MAPLIST
#define MAPLIST(OP,V...) EVAL(_MAPLIST(OP,V))
+1
View File
@@ -45,6 +45,7 @@ typedef const char Language_Str[];
// Set unused languages equal to each other so the
// compiler can optimize away the conditionals.
#define LCD_LANGUAGE_1 LCD_LANGUAGE
#ifndef LCD_LANGUAGE_2
#define LCD_LANGUAGE_2 LCD_LANGUAGE
#endif
+9 -6
View File
@@ -30,12 +30,15 @@
uint8_t marlin_debug_flags = MARLIN_DEBUG_NONE;
// Commonly-used strings in serial output
PGMSTR(NUL_STR, ""); PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T");
PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
LOGICAL_AXIS_CODE(PGMSTR(SP_E_STR, " E"), PGMSTR(SP_X_STR, " X"), PGMSTR(SP_Y_STR, " Y"), PGMSTR(SP_Z_STR, " Z"), PGMSTR(SP_I_STR, " " STR_I), PGMSTR(SP_J_STR, " " STR_J), PGMSTR(SP_K_STR, " " STR_K), PGMSTR(SP_U_STR, " " STR_U), PGMSTR(SP_V_STR, " " STR_V), PGMSTR(SP_W_STR, " " STR_W));
LOGICAL_AXIS_CODE(PGMSTR(SP_E_LBL, " E:"), PGMSTR(SP_X_LBL, " X:"), PGMSTR(SP_Y_LBL, " Y:"), PGMSTR(SP_Z_LBL, " Z:"), PGMSTR(SP_I_LBL, " " STR_I ":"), PGMSTR(SP_J_LBL, " " STR_J ":"), PGMSTR(SP_K_LBL, " " STR_K ":"), PGMSTR(SP_U_LBL, " " STR_U ":"), PGMSTR(SP_V_LBL, " " STR_V ":"), PGMSTR(SP_W_LBL, " " STR_W ":"));
LOGICAL_AXIS_CODE(PGMSTR(E_STR, "E"), PGMSTR(X_STR, "X"), PGMSTR(Y_STR, "Y"), PGMSTR(Z_STR, "Z"), PGMSTR(I_STR, STR_I), PGMSTR(J_STR, STR_J), PGMSTR(K_STR, STR_K), PGMSTR(U_STR, STR_U), PGMSTR(V_STR, STR_V), PGMSTR(W_STR, STR_W));
LOGICAL_AXIS_CODE(PGMSTR(E_LBL, "E:"), PGMSTR(X_LBL, "X:"), PGMSTR(Y_LBL, "Y:"), PGMSTR(Z_LBL, "Z:"), PGMSTR(I_LBL, STR_I ":"), PGMSTR(J_LBL, STR_J ":"), PGMSTR(K_LBL, STR_K ":"), PGMSTR(U_LBL, STR_U ":"), PGMSTR(V_LBL, STR_V ":"), PGMSTR(W_LBL, STR_W ":"));
PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
PGMSTR(SP_P_STR, " P"); PGMSTR(SP_T_STR, " T"); PGMSTR(NUL_STR, "");
#define _N_STR(N) PGMSTR(N##_STR, STR_##N);
#define _N_LBL(N) PGMSTR(N##_LBL, STR_##N ":");
#define _SP_N_STR(N) PGMSTR(SP_##N##_STR, " " STR_##N);
#define _SP_N_LBL(N) PGMSTR(SP_##N##_LBL, " " STR_##N ":");
MAP(_N_STR, LOGICAL_AXIS_NAMES); MAP(_SP_N_STR, LOGICAL_AXIS_NAMES);
MAP(_N_LBL, LOGICAL_AXIS_NAMES); MAP(_SP_N_LBL, LOGICAL_AXIS_NAMES);
// Hook Meatpack if it's enabled on the first leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_1)
+29 -11
View File
@@ -28,17 +28,6 @@
#include "../feature/meatpack.h"
#endif
// Commonly-used strings in serial output
extern const char NUL_STR[], SP_P_STR[], SP_T_STR[],
SP_A_STR[], SP_B_STR[], SP_C_STR[],
LOGICAL_AXIS_LIST(SP_E_STR[], SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_I_STR[], SP_J_STR[], SP_K_STR[], SP_U_STR[], SP_V_STR[], SP_W_STR[]),
LOGICAL_AXIS_LIST(SP_E_LBL[], SP_X_LBL[], SP_Y_LBL[], SP_Z_LBL[], SP_I_LBL[], SP_J_LBL[], SP_K_LBL[], SP_U_LBL[], SP_V_LBL[], SP_W_LBL[]),
LOGICAL_AXIS_LIST(E_STR[], X_STR[], Y_STR[], Z_STR[], I_STR[], J_STR[], K_STR[], U_STR[], V_STR[], W_STR[]),
LOGICAL_AXIS_LIST(E_LBL[], X_LBL[], Y_LBL[], Z_LBL[], I_LBL[], J_LBL[], K_LBL[], U_LBL[], V_LBL[], W_LBL[]);
PGM_P const SP_AXIS_LBL[] PROGMEM = LOGICAL_AXIS_ARRAY(SP_E_LBL, SP_X_LBL, SP_Y_LBL, SP_Z_LBL, SP_I_LBL, SP_J_LBL, SP_K_LBL, SP_U_LBL, SP_V_LBL, SP_W_LBL);
PGM_P const SP_AXIS_STR[] PROGMEM = LOGICAL_AXIS_ARRAY(SP_E_STR, SP_X_STR, SP_Y_STR, SP_Z_STR, SP_I_STR, SP_J_STR, SP_K_STR, SP_U_STR, SP_V_STR, SP_W_STR);
//
// Debugging flags for use by M111
//
@@ -354,3 +343,32 @@ inline void print_pos(const xyz_pos_t &xyz, FSTR_P const prefix=nullptr, FSTR_P
#define SERIAL_POS(SUFFIX,VAR) do { print_pos(VAR, F(" " STRINGIFY(VAR) "="), F(" : " SUFFIX "\n")); }while(0)
#define SERIAL_XYZ(PREFIX,V...) do { print_pos(V, F(PREFIX)); }while(0)
//
// Commonly-used strings in serial output
//
#define _N_STR(N) N##_STR
#define _N_LBL(N) N##_LBL
#define _N_STR_A(N) _N_STR(N)[]
#define _N_LBL_A(N) _N_LBL(N)[]
#define _SP_N_STR(N) SP_##N##_STR
#define _SP_N_LBL(N) SP_##N##_LBL
#define _SP_N_STR_A(N) _SP_N_STR(N)[]
#define _SP_N_LBL_A(N) _SP_N_LBL(N)[]
extern const char SP_A_STR[], SP_B_STR[], SP_C_STR[], SP_P_STR[], SP_T_STR[], NUL_STR[],
MAPLIST(_N_STR_A, LOGICAL_AXIS_NAMES), MAPLIST(_SP_N_STR_A, LOGICAL_AXIS_NAMES),
MAPLIST(_N_LBL_A, LOGICAL_AXIS_NAMES), MAPLIST(_SP_N_LBL_A, LOGICAL_AXIS_NAMES);
PGM_P const SP_AXIS_LBL[] PROGMEM = { MAPLIST(_SP_N_LBL, LOGICAL_AXIS_NAMES) };
PGM_P const SP_AXIS_STR[] PROGMEM = { MAPLIST(_SP_N_STR, LOGICAL_AXIS_NAMES) };
#undef _N_STR
#undef _N_LBL
#undef _N_STR_A
#undef _N_LBL_A
#undef _SP_N_STR
#undef _SP_N_LBL
#undef _SP_N_STR_A
#undef _SP_N_LBL_A
+10 -3
View File
@@ -39,20 +39,28 @@ struct IF<true, L, R> { typedef L type; };
#define NUM_AXIS_GANG(V...) GANG_N(NUM_AXES, V)
#define NUM_AXIS_CODE(V...) CODE_N(NUM_AXES, V)
#define NUM_AXIS_LIST(V...) LIST_N(NUM_AXES, V)
#define NUM_AXIS_LIST_1(V) LIST_N_1(NUM_AXES, V)
#define NUM_AXIS_ARRAY(V...) { NUM_AXIS_LIST(V) }
#define NUM_AXIS_ARRAY_1(V) { NUM_AXIS_LIST_1(V) }
#define NUM_AXIS_ARGS(T...) NUM_AXIS_LIST(T x, T y, T z, T i, T j, T k, T u, T v, T w)
#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
#define NUM_AXIS_DEFS(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
#define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W)
#define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES)
#define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E)
#define LOGICAL_AXIS_CODE(E,V...) NUM_AXIS_CODE(V) CODE_ITEM_E(E)
#define LOGICAL_AXIS_LIST(E,V...) NUM_AXIS_LIST(V) LIST_ITEM_E(E)
#define LOGICAL_AXIS_LIST_1(V) NUM_AXIS_LIST_1(V) LIST_ITEM_E(V)
#define LOGICAL_AXIS_ARRAY(E,V...) { LOGICAL_AXIS_LIST(E,V) }
#define LOGICAL_AXIS_ARRAY_1(V) { LOGICAL_AXIS_LIST_1(V) }
#define LOGICAL_AXIS_ARGS(T...) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k, T u, T v, T w)
#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w)
#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V)
#define LOGICAL_AXES_STRING LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
#define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K, U, V, W)
#define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES)
#define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)
#define XYZ_GANG(V...) GANG_N(PRIMARY_LINEAR_AXES, V)
#define XYZ_CODE(V...) CODE_N(PRIMARY_LINEAR_AXES, V)
@@ -173,7 +181,6 @@ enum AxisEnum : uint8_t {
};
typedef IF<(NUM_AXIS_ENUMS > 8), uint16_t, uint8_t>::type axis_bits_t;
typedef IF<(NUM_AXES > 8), uint16_t, uint8_t>::type linear_axis_bits_t;
//
// Loop over axes
+5 -4
View File
@@ -132,11 +132,10 @@ void safe_delay(millis_t ms) {
#else
#if ENABLED(AUTO_BED_LEVELING_UBL)
SERIAL_ECHOPGM("UBL Adjustment Z");
const float rz = bedlevel.get_z_correction(current_position);
#elif ENABLED(AUTO_BED_LEVELING_BILINEAR)
SERIAL_ECHOPGM("ABL Adjustment Z");
const float rz = bedlevel.get_z_correction(current_position);
#endif
const float rz = bedlevel.get_z_correction(current_position);
SERIAL_ECHO(ftostr43sign(rz, '+'));
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (planner.z_fade_height) {
@@ -156,11 +155,13 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM("Mesh Bed Leveling");
if (planner.leveling_active) {
SERIAL_ECHOLNPGM(" (enabled)");
SERIAL_ECHOPGM("MBL Adjustment Z", ftostr43sign(bedlevel.get_z(current_position), '+'));
const float z_offset = bedlevel.get_z_offset(),
z_correction = bedlevel.get_z_correction(current_position);
SERIAL_ECHOPGM("MBL Adjustment Z", ftostr43sign(z_offset + z_correction, '+'));
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
if (planner.z_fade_height) {
SERIAL_ECHOPGM(" (", ftostr43sign(
bedlevel.get_z(current_position, planner.fade_scaling_factor_for_z(current_position.z)), '+'
z_offset + z_correction * planner.fade_scaling_factor_for_z(current_position.z), '+'
));
SERIAL_CHAR(')');
}
-1
View File
@@ -29,7 +29,6 @@
#if HAS_MOTOR_CURRENT_DAC
#include "stepper_dac.h"
#include "../../MarlinCore.h" // for SP_X_LBL...
bool dac_present = false;
constexpr xyze_uint8_t dac_order = DAC_STEPPER_ORDER;
+1 -1
View File
@@ -26,7 +26,7 @@
* Algorithm & Implementation: Scott Mudge - mail@scottmudge.com
* Date: Dec. 2020
*
* Character Frequencies from ~30 MB of comment-stripped gcode:
* Character Frequencies from ~30 MB of comment-stripped G-code:
* '1' -> 4451136 '4' -> 1353273 '\n' -> 1087683 '-' -> 90242
* '0' -> 4253577 '9' -> 1352147 'G' -> 1075806 'Z' -> 34109
* ' ' -> 3053297 '3' -> 1262929 'X' -> 975742 'M' -> 11879
+2 -2
View File
@@ -29,7 +29,7 @@
* Specifically optimized for 3D printing G-Code, this is a zero-cost data compression method
* which packs ~180-190% more data into the same amount of bytes going to the CNC controller.
* As a majority of G-Code can be represented by a restricted alphabet, I performed histogram
* analysis on a wide variety of 3D printing gcode samples, and found ~93% of all gcode could
* analysis on a wide variety of 3D printing G-code samples, and found ~93% of all G-code could
* be represented by the same 15-character alphabet.
*
* This allowed me to design a system of packing 2 8-bit characters into a single byte, assuming
@@ -38,7 +38,7 @@
*
* Combined with some logic to allow commingling of full-width characters outside of this 15-
* character alphabet (at the cost of an extra 8-bits per full-width character), and by stripping
* out unnecessary comments, the end result is gcode which is roughly half the original size.
* out unnecessary comments, the end result is G-code which is roughly half the original size.
*
* Why did I do this? I noticed micro-stuttering and other data-bottleneck issues while printing
* objects with high curvature, especially at high speeds. There is also the issue of the limited
@@ -51,7 +51,7 @@ When done, the MMU sends
- MMU => 'ok\n'
We don't wait for a response here but immediately continue with the next gcode which should
We don't wait for a response here but immediately continue with the next G-code which should
be one or more extruder moves to feed the filament into the hotend.
+2 -3
View File
@@ -939,7 +939,7 @@ bool MMU2::load_filament_to_nozzle(const uint8_t index) {
* Load filament to nozzle of multimaterial printer
*
* This function is used only after T? (user select filament) and M600 (change filament).
* It is not used after T0 .. T4 command (select filament), in such case, gcode is responsible for loading
* It is not used after T0 .. T4 command (select filament), in such case, G-code is responsible for loading
* filament to nozzle.
*/
void MMU2::load_to_nozzle() {
@@ -1031,8 +1031,7 @@ void MMU2::execute_extruder_sequence(const E_Step * sequence, int steps) {
const float es = pgm_read_float(&(step->extrude));
const feedRate_t fr_mm_m = pgm_read_float(&(step->feedRate));
DEBUG_ECHO_START();
DEBUG_ECHOLNPGM("E step ", es, "/", fr_mm_m);
DEBUG_ECHO_MSG("E step ", es, "/", fr_mm_m);
current_position.e += es;
line_to_current_position(MMM_TO_MMS(fr_mm_m));
+2 -2
View File
@@ -39,7 +39,8 @@
#endif
SpindleLaser cutter;
uint8_t SpindleLaser::power;
uint8_t SpindleLaser::power,
SpindleLaser::last_power_applied; // = 0 // Basic power state tracking
#if ENABLED(LASER_FEATURE)
cutter_test_pulse_t SpindleLaser::testPulse = 50; // Test fire Pulse time ms value.
#endif
@@ -113,7 +114,6 @@ void SpindleLaser::init() {
* @param opwr Power value. Range 0 to MAX. When 0 disable spindle/laser.
*/
void SpindleLaser::apply_power(const uint8_t opwr) {
static uint8_t last_power_applied = 0;
if (opwr == last_power_applied) return;
last_power_applied = opwr;
power = opwr;
+2 -3
View File
@@ -41,8 +41,6 @@
#define PCT_TO_PWM(X) ((X) * 255 / 100)
#define PCT_TO_SERVO(X) ((X) * 180 / 100)
// #define _MAP(N,S1,S2,D1,D2) ((N)*_MAX((D2)-(D1),0)/_MAX((S2)-(S1),1)+(D1))
class SpindleLaser {
public:
static const inline uint8_t pct_to_ocr(const_float_t pct) { return uint8_t(PCT_TO_PWM(pct)); }
@@ -91,7 +89,8 @@ public:
#endif
static bool isReady; // Ready to apply power setting from the UI to OCR
static uint8_t power;
static uint8_t power,
last_power_applied; // Basic power state tracking
#if ENABLED(MARLIN_DEV_MODE)
static cutter_frequency_t frequency; // Set PWM frequency; range: 2K-50K
+6
View File
@@ -321,6 +321,9 @@ void GcodeSuite::G28() {
stepperW.rms_current(W_CURRENT_HOME);
if (DEBUGGING(LEVELING)) debug_current(F(STR_W), tmc_save_current_W, W_CURRENT_HOME);
#endif
#if SENSORLESS_STALLGUARD_DELAY
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
#endif
#endif
#if ENABLED(IMPROVE_HOMING_RELIABILITY)
@@ -576,6 +579,9 @@ void GcodeSuite::G28() {
#if HAS_CURRENT_HOME(W)
stepperW.rms_current(tmc_save_current_W);
#endif
#if SENSORLESS_STALLGUARD_DELAY
safe_delay(SENSORLESS_STALLGUARD_DELAY); // Short delay needed to settle
#endif
#endif // HAS_HOMING_CURRENT
ui.refresh();
+40 -7
View File
@@ -71,9 +71,9 @@ float lcd_probe_pt(const xy_pos_t &xy);
void ac_home() {
endstops.enable(true);
TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(true));
TERN_(SENSORLESS_HOMING, endstops.set_homing_current(true));
home_delta();
TERN_(HAS_DELTA_SENSORLESS_PROBING, probe.set_homing_current(false));
TERN_(SENSORLESS_HOMING, endstops.set_homing_current(false));
endstops.not_homing();
}
@@ -390,6 +390,8 @@ static float auto_tune_a(const float dcr) {
* X Don't activate stallguard on X.
* Y Don't activate stallguard on Y.
* Z Don't activate stallguard on Z.
*
* S Save offset_sensorless_adj
*/
void GcodeSuite::G33() {
@@ -411,7 +413,8 @@ void GcodeSuite::G33() {
dcr -= probe_at_offset ? _MAX(total_offset, PROBING_MARGIN) : total_offset;
#endif
NOMORE(dcr, DELTA_PRINTABLE_RADIUS);
if (parser.seenval('R')) dcr -= _MAX(parser.value_float(),0);
if (parser.seenval('R')) dcr -= _MAX(parser.value_float(), 0.0f);
TERN_(HAS_DELTA_SENSORLESS_PROBING, dcr *= sensorless_radius_factor);
const float calibration_precision = parser.floatval('C', 0.0f);
if (calibration_precision < 0) {
@@ -434,9 +437,8 @@ void GcodeSuite::G33() {
const bool stow_after_each = parser.seen_test('E');
#if HAS_DELTA_SENSORLESS_PROBING
probe.test_sensitivity.x = !parser.seen_test('X');
TERN_(HAS_Y_AXIS, probe.test_sensitivity.y = !parser.seen_test('Y'));
TERN_(HAS_Z_AXIS, probe.test_sensitivity.z = !parser.seen_test('Z'));
probe.test_sensitivity = { !parser.seen_test('X'), !parser.seen_test('Y'), !parser.seen_test('Z') };
const bool do_save_offset_adj = parser.seen_test('S');
#endif
const bool _0p_calibration = probe_points == 0,
@@ -475,6 +477,25 @@ void GcodeSuite::G33() {
if (!_0p_calibration) ac_home();
#if HAS_DELTA_SENSORLESS_PROBING
if (verbose_level > 0 && do_save_offset_adj) {
offset_sensorless_adj.reset();
auto caltower = [&](Probe::sense_bool_t s){
float z_at_pt[NPP + 1];
LOOP_CAL_ALL(rad) z_at_pt[rad] = 0.0f;
probe.test_sensitivity = s;
if (probe_calibration_points(z_at_pt, 1, dcr, false, false, probe_at_offset))
probe.set_offset_sensorless_adj(z_at_pt[CEN]);
};
caltower({ true, false, false }); // A
caltower({ false, true, false }); // B
caltower({ false, false, true }); // C
probe.test_sensitivity = { true, true, true }; // reset to all
}
#endif
do { // start iterations
float z_at_pt[NPP + 1] = { 0.0f };
@@ -598,8 +619,17 @@ void GcodeSuite::G33() {
// print report
if (verbose_level == 3 || verbose_level == 0)
if (verbose_level == 3 || verbose_level == 0) {
print_calibration_results(z_at_pt, _tower_results, _opposite_results);
#if HAS_DELTA_SENSORLESS_PROBING
if (verbose_level == 0 && probe_points == 1) {
if (do_save_offset_adj)
probe.set_offset_sensorless_adj(z_at_pt[CEN]);
else
probe.refresh_largest_sensorless_adj();
}
#endif
}
if (verbose_level != 0) { // !dry run
if ((zero_std_dev >= test_precision && iterations > force_iterations) || zero_std_dev <= calibration_precision) { // end iterations
@@ -660,6 +690,9 @@ void GcodeSuite::G33() {
ac_cleanup(TERN_(HAS_MULTI_HOTEND, old_tool_index));
TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE));
#if HAS_DELTA_SENSORLESS_PROBING
probe.test_sensitivity = { true, true, true };
#endif
}
#endif // DELTA_AUTO_CALIBRATION
+2 -11
View File
@@ -47,19 +47,10 @@ void GcodeSuite::M425() {
bool noArgs = true;
auto axis_can_calibrate = [](const uint8_t a) {
#define _CAN_CASE(N) case N##_AXIS: return AXIS_CAN_CALIBRATE(N);
switch (a) {
default: return false;
NUM_AXIS_CODE(
case X_AXIS: return AXIS_CAN_CALIBRATE(X),
case Y_AXIS: return AXIS_CAN_CALIBRATE(Y),
case Z_AXIS: return AXIS_CAN_CALIBRATE(Z),
case I_AXIS: return AXIS_CAN_CALIBRATE(I),
case J_AXIS: return AXIS_CAN_CALIBRATE(J),
case K_AXIS: return AXIS_CAN_CALIBRATE(K),
case U_AXIS: return AXIS_CAN_CALIBRATE(U),
case V_AXIS: return AXIS_CAN_CALIBRATE(V),
case W_AXIS: return AXIS_CAN_CALIBRATE(W)
);
MAIN_AXIS_MAP(_CAN_CASE)
}
};
+15 -6
View File
@@ -108,12 +108,21 @@
#endif // !NO_VOLUMETRICS
/**
* M201: Set max acceleration in units/s^2 for print moves (M201 X1000 Y1000)
* M201: Set max acceleration in units/s^2 for print moves.
*
* With multiple extruders use T to specify which one.
* X<accel> : Max Acceleration for X
* Y<accel> : Max Acceleration for Y
* Z<accel> : Max Acceleration for Z
* ... : etc
* E<accel> : Max Acceleration for Extruder
* T<index> : Extruder index to set
*
* With XY_FREQUENCY_LIMIT:
* F<Hz> : Frequency limit for XY...IJKUVW
* S<percent> : Speed factor percentage.
*/
void GcodeSuite::M201() {
if (!parser.seen("T" LOGICAL_AXES_STRING))
if (!parser.seen("T" STR_AXES_LOGICAL TERN_(XY_FREQUENCY_LIMIT, "FS")))
return M201_report();
const int8_t target_extruder = get_target_extruder_from_command();
@@ -121,7 +130,7 @@ void GcodeSuite::M201() {
#ifdef XY_FREQUENCY_LIMIT
if (parser.seenval('F')) planner.set_frequency_limit(parser.value_byte());
if (parser.seenval('G')) planner.xy_freq_min_speed_factor = constrain(parser.value_float(), 1, 100) / 100;
if (parser.seenval('S')) planner.xy_freq_min_speed_factor = constrain(parser.value_float(), 1, 100) / 100;
#endif
LOOP_LOGICAL_AXES(i) {
@@ -167,7 +176,7 @@ void GcodeSuite::M201_report(const bool forReplay/*=true*/) {
* With multiple extruders use T to specify which one.
*/
void GcodeSuite::M203() {
if (!parser.seen("T" LOGICAL_AXES_STRING))
if (!parser.seen("T" STR_AXES_LOGICAL))
return M203_report();
const int8_t target_extruder = get_target_extruder_from_command();
@@ -200,7 +209,7 @@ void GcodeSuite::M203_report(const bool forReplay/*=true*/) {
);
#if ENABLED(DISTINCT_E_FACTORS)
LOOP_L_N(i, E_STEPPERS) {
SERIAL_ECHO_START();
if (!forReplay) SERIAL_ECHO_START();
SERIAL_ECHOLNPGM_P(
PSTR(" M203 T"), i
, SP_E_STR, VOLUMETRIC_UNIT(planner.settings.max_feedrate_mm_s[E_AXIS_N(i)])
+1 -1
View File
@@ -43,7 +43,7 @@ void GcodeSuite::M92() {
if (target_extruder < 0) return;
// No arguments? Show M92 report.
if (!parser.seen(LOGICAL_AXES_STRING TERN_(MAGIC_NUMBERS_GCODE, "HL")))
if (!parser.seen(STR_AXES_LOGICAL TERN_(MAGIC_NUMBERS_GCODE, "HL")))
return M92_report(true, target_extruder);
LOOP_LOGICAL_AXES(i) {
+12 -2
View File
@@ -23,6 +23,7 @@
#include "../gcode.h"
#include "../../MarlinCore.h" // for stepper_inactive_time, disable_e_steppers
#include "../../lcd/marlinui.h"
#include "../../module/motion.h" // for e_axis_mask
#include "../../module/stepper.h"
#if ENABLED(AUTO_BED_LEVELING_UBL)
@@ -43,7 +44,7 @@ inline stepper_flags_t selected_axis_bits() {
selected.bits = _BV(INDEX_OF_AXIS(E_AXIS, e));
}
else
selected.bits = selected.e_bits();
selected.bits = e_axis_mask;
}
#endif
selected.bits |= NUM_AXIS_GANG(
@@ -210,7 +211,16 @@ void try_to_disable(const stepper_flags_t to_disable) {
void GcodeSuite::M18_M84() {
if (parser.seenval('S')) {
reset_stepper_timeout();
stepper_inactive_time = parser.value_millis_from_seconds();
#if HAS_DISABLE_INACTIVE_AXIS
const millis_t ms = parser.value_millis_from_seconds();
#if LASER_SAFETY_TIMEOUT_MS > 0
if (ms && ms <= LASER_SAFETY_TIMEOUT_MS) {
SERIAL_ECHO_MSG("M18 timeout must be > ", MS_TO_SEC(LASER_SAFETY_TIMEOUT_MS + 999), " s for laser safety.");
return;
}
#endif
stepper_inactive_time = ms;
#endif
}
else {
if (parser.seen_axis()) {
+4
View File
@@ -66,6 +66,10 @@
* PWM duty cycle goes from 0 (off) to 255 (always on).
*/
void GcodeSuite::M3_M4(const bool is_M4) {
#if LASER_SAFETY_TIMEOUT_MS > 0
reset_stepper_timeout(); // Reset timeout to allow subsequent G-code to power the laser (imm.)
#endif
#if EITHER(SPINDLE_LASER_USE_PWM, SPINDLE_SERVO)
auto get_s_power = [] {
if (parser.seenval('S')) {
+8 -1
View File
@@ -29,7 +29,14 @@ void GcodeSuite::M85() {
if (parser.seen('S')) {
reset_stepper_timeout();
max_inactive_time = parser.value_millis_from_seconds();
const millis_t ms = parser.value_millis_from_seconds();
#if LASER_SAFETY_TIMEOUT_MS > 0
if (ms && ms <= LASER_SAFETY_TIMEOUT_MS) {
SERIAL_ECHO_MSG("M85 timeout must be > ", MS_TO_SEC(LASER_SAFETY_TIMEOUT_MS + 999), " s for laser safety.");
return;
}
#endif
max_inactive_time = ms;
}
}
+3 -2
View File
@@ -45,9 +45,10 @@
* X, Y, Z : Specify axes to move during cleaning. Default: ALL.
*/
void GcodeSuite::G12() {
// Don't allow nozzle cleaning without homing first
if (homing_needed_error(linear_bits & ~TERN0(NOZZLE_CLEAN_NO_Z, Z_AXIS) & ~TERN0(NOZZLE_CLEAN_NO_Y, Y_AXIS)))
return;
constexpr main_axes_bits_t clean_axis_mask = main_axes_mask & ~TERN0(NOZZLE_CLEAN_NO_Z, Z_AXIS) & ~TERN0(NOZZLE_CLEAN_NO_Y, Y_AXIS);
if (homing_needed_error(clean_axis_mask)) return;
#ifdef WIPE_SEQUENCE_COMMANDS
if (!parser.seen_any()) {
@@ -48,7 +48,7 @@
void GcodeSuite::M907() {
#if HAS_MOTOR_CURRENT_SPI
if (!parser.seen("BS" LOGICAL_AXES_STRING))
if (!parser.seen("BS" STR_AXES_LOGICAL))
return M907_report();
if (parser.seenval('S')) LOOP_L_N(i, MOTOR_CURRENT_COUNT) stepper.set_digipot_current(i, parser.value_int());
+5 -5
View File
@@ -50,14 +50,14 @@ void GcodeSuite::G60() {
{
const xyze_pos_t &pos = stored_position[slot];
DEBUG_ECHOPGM(STR_SAVED_POS " S", slot, " :");
DEBUG_ECHOLNPAIR_F_P(
DEBUG_ECHOLNPGM_P(
LIST_N(DOUBLE(NUM_AXES),
SP_Y_STR, pos.x, SP_Y_STR, pos.y, SP_Z_STR, pos.z,
SP_I_STR, pos.i, SP_J_STR, pos.j, SP_K_STR, pos.k,
SP_U_STR, pos.u, SP_V_STR, pos.v, SP_W_STR, pos.w
SP_X_LBL, pos.x, SP_Y_LBL, pos.y, SP_Z_LBL, pos.z,
SP_I_LBL, pos.i, SP_J_LBL, pos.j, SP_K_LBL, pos.k,
SP_U_LBL, pos.u, SP_V_LBL, pos.v, SP_W_LBL, pos.w
)
#if HAS_EXTRUDERS
, SP_E_STR, pos.e
, SP_E_LBL, pos.e
#endif
);
}
+1 -1
View File
@@ -68,7 +68,7 @@ void GcodeSuite::G61() {
SYNC_E(stored_position[slot].e);
}
else {
if (parser.seen(NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W))) {
if (parser.seen(STR_AXES_MAIN)) {
DEBUG_ECHOPGM(STR_RESTORING_POS " S", slot);
LOOP_NUM_AXES(i) {
destination[i] = parser.seenval(AXIS_CHAR(i))
+6 -3
View File
@@ -21,7 +21,7 @@
*/
/**
* gcode.cpp - Temporary container for all gcode handlers
* gcode.cpp - Temporary container for all G-code handlers
* Most will migrate to classes, by feature.
*/
@@ -73,8 +73,11 @@ GcodeSuite gcode;
// Inactivity shutdown
millis_t GcodeSuite::previous_move_ms = 0,
GcodeSuite::max_inactive_time = 0,
GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME);
GcodeSuite::max_inactive_time = 0;
#if HAS_DISABLE_INACTIVE_AXIS
millis_t GcodeSuite::stepper_inactive_time = SEC_TO_MS(DEFAULT_STEPPER_DEACTIVE_TIME);
#endif
// Relative motion mode for each logical axis
static constexpr xyze_bool_t ar_init = AXIS_RELATIVE_MODES;
+12 -6
View File
@@ -110,7 +110,7 @@
* M33 - Get the longname version of a path. (Requires LONG_FILENAME_HOST_SUPPORT)
* M34 - Set SD Card sorting options. (Requires SDCARD_SORT_ALPHA)
*
* M42 - Change pin status via gcode: M42 P<pin> S<value>. LED pin assumed if P is omitted. (Requires DIRECT_PIN_CONTROL)
* M42 - Change pin status via G-code: M42 P<pin> S<value>. LED pin assumed if P is omitted. (Requires DIRECT_PIN_CONTROL)
* M43 - Display pin status, watch pins for changes, watch endstops & toggle LED, Z servo probe test, toggle pins (Requires PINS_DEBUGGING)
* M48 - Measure Z Probe repeatability: M48 P<points> X<pos> Y<pos> V<level> E<engage> L<legs> S<chizoid>. (Requires Z_MIN_PROBE_REPEATABILITY_TEST)
*
@@ -396,14 +396,20 @@ public:
static bool select_coordinate_system(const int8_t _new);
#endif
static millis_t previous_move_ms, max_inactive_time, stepper_inactive_time;
FORCE_INLINE static void reset_stepper_timeout(const millis_t ms=millis()) { previous_move_ms = ms; }
static millis_t previous_move_ms, max_inactive_time;
FORCE_INLINE static bool stepper_max_timed_out(const millis_t ms=millis()) {
return max_inactive_time && ELAPSED(ms, previous_move_ms + max_inactive_time);
}
FORCE_INLINE static bool stepper_inactive_timeout(const millis_t ms=millis()) {
return ELAPSED(ms, previous_move_ms + stepper_inactive_time);
}
FORCE_INLINE static void reset_stepper_timeout(const millis_t ms=millis()) { previous_move_ms = ms; }
#if HAS_DISABLE_INACTIVE_AXIS
static millis_t stepper_inactive_time;
FORCE_INLINE static bool stepper_inactive_timeout(const millis_t ms=millis()) {
return ELAPSED(ms, previous_move_ms + stepper_inactive_time);
}
#else
static bool stepper_inactive_timeout(const millis_t) { return false; }
#endif
static void report_echo_start(const bool forReplay);
static void report_heading(const bool forReplay, FSTR_P const fstr, const bool eol=true);
+1 -1
View File
@@ -92,7 +92,7 @@ void GcodeSuite::G0_G1(TERN_(HAS_FAST_MOVES, const bool fast_move/*=false*/)) {
if (MIN_AUTORETRACT <= MAX_AUTORETRACT) {
// When M209 Autoretract is enabled, convert E-only moves to firmware retract/recover moves
if (fwretract.autoretract_enabled && parser.seen_test('E')
&& !parser.seen(NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W))
&& !parser.seen(STR_AXES_MAIN)
) {
const float echange = destination.e - current_position.e;
// Is this a retract or recover move?
+1 -1
View File
@@ -87,7 +87,7 @@ void GcodeSuite::M290() {
}
#endif
if (!parser.seen(NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W)) || parser.seen('R')) {
if (!parser.seen(STR_AXES_MAIN) || parser.seen('R')) {
SERIAL_ECHO_START();
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
+2 -2
View File
@@ -45,7 +45,7 @@
/**
* GCode parser
*
* - Parse a single gcode line for its letter, code, subcode, and parameters
* - Parse a single G-code line for its letter, code, subcode, and parameters
* - FASTER_GCODE_PARSER:
* - Flags existing params (1 bit each)
* - Stores value offsets (1 byte each)
@@ -225,7 +225,7 @@ public:
#endif // !FASTER_GCODE_PARSER
// Seen any axis parameter
static bool seen_axis() { return seen(LOGICAL_AXES_STRING); }
static bool seen_axis() { return seen(STR_AXES_LOGICAL); }
#if ENABLED(GCODE_QUOTED_STRINGS)
static char* unescape_string(char* &src);
+7 -7
View File
@@ -32,13 +32,13 @@ mpe_settings_t mpe_settings;
inline void mpe_settings_report() {
SERIAL_ECHO_MSG("Magnetic Parking Extruder");
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("L: Left parking :", mpe_settings.parking_xpos[0]);
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("R: Right parking :", mpe_settings.parking_xpos[1]);
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("I: Grab Offset :", mpe_settings.grab_distance);
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("J: Normal speed :", long(MMS_TO_MMM(mpe_settings.slow_feedrate)));
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("H: High speed :", long(MMS_TO_MMM(mpe_settings.fast_feedrate)));
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("D: Distance trav.:", mpe_settings.travel_distance);
SERIAL_ECHO_START(); SERIAL_ECHOLNPGM("C: Compenstion :", mpe_settings.compensation_factor);
SERIAL_ECHO_MSG("L: Left parking :", mpe_settings.parking_xpos[0]);
SERIAL_ECHO_MSG("R: Right parking :", mpe_settings.parking_xpos[1]);
SERIAL_ECHO_MSG("I: Grab Offset :", mpe_settings.grab_distance);
SERIAL_ECHO_MSG("J: Normal speed :", long(MMS_TO_MMM(mpe_settings.slow_feedrate)));
SERIAL_ECHO_MSG("H: High speed :", long(MMS_TO_MMM(mpe_settings.fast_feedrate)));
SERIAL_ECHO_MSG("D: Distance trav.:", mpe_settings.travel_distance);
SERIAL_ECHO_MSG("C: Compenstion :", mpe_settings.compensation_factor);
}
void mpe_settings_init() {
+6 -2
View File
@@ -36,6 +36,7 @@
* C<joules/kelvin> Block heat capacity.
* E<extruder> Extruder number to set. (Default: E0)
* F<watts/kelvin> Ambient heat transfer coefficient (fan on full).
* H<joules/kelvin/mm> Filament heat capacity per mm.
* P<watts> Heater power.
* R<kelvin/second/kelvin> Sensor responsiveness (= transfer coefficient / heat capcity).
*/
@@ -43,7 +44,7 @@
void GcodeSuite::M306() {
if (parser.seen_test('T')) { thermalManager.MPC_autotune(); return; }
if (parser.seen("ACFPR")) {
if (parser.seen("ACFPRH")) {
const heater_id_t hid = (heater_id_t)parser.intval('E', 0);
MPC_t &constants = thermalManager.temp_hotend[hid].constants;
if (parser.seenval('P')) constants.heater_power = parser.value_float();
@@ -53,6 +54,7 @@ void GcodeSuite::M306() {
#if ENABLED(MPC_INCLUDE_FAN)
if (parser.seenval('F')) constants.fan255_adjustment = parser.value_float() - constants.ambient_xfer_coeff_fan0;
#endif
if (parser.seenval('H')) constants.filament_heat_capacity_permm = parser.value_float();
return;
}
@@ -70,8 +72,10 @@ void GcodeSuite::M306_report(const bool forReplay/*=true*/) {
SERIAL_ECHOPAIR_F(" R", constants.sensor_responsiveness, 4);
SERIAL_ECHOPAIR_F(" A", constants.ambient_xfer_coeff_fan0, 4);
#if ENABLED(MPC_INCLUDE_FAN)
SERIAL_ECHOLNPAIR_F(" F", constants.ambient_xfer_coeff_fan0 + constants.fan255_adjustment, 4);
SERIAL_ECHOPAIR_F(" F", constants.ambient_xfer_coeff_fan0 + constants.fan255_adjustment, 4);
#endif
SERIAL_ECHOPAIR_F(" H", constants.filament_heat_capacity_permm, 4);
SERIAL_EOL();
}
}
+1 -1
View File
@@ -1241,7 +1241,7 @@
*/
#if ENABLED(AUTO_BED_LEVELING_UBL)
#undef LCD_BED_LEVELING
#if ENABLED(DELTA)
#if EITHER(DELTA, SEGMENT_LEVELED_MOVES)
#define UBL_SEGMENTED 1
#endif
#endif
+4
View File
@@ -1044,3 +1044,7 @@
#undef CONFIGURATION_EMBEDDING
#define CANNOT_EMBED_CONFIGURATION defined(__AVR__)
#endif
#if ANY(DISABLE_INACTIVE_X, DISABLE_INACTIVE_Y, DISABLE_INACTIVE_Z, DISABLE_INACTIVE_I, DISABLE_INACTIVE_J, DISABLE_INACTIVE_K, DISABLE_INACTIVE_U, DISABLE_INACTIVE_V, DISABLE_INACTIVE_W, DISABLE_INACTIVE_E)
#define HAS_DISABLE_INACTIVE_AXIS 1
#endif
+21 -13
View File
@@ -266,7 +266,7 @@
* No adjustable bed on non-cartesians
*/
#if IS_KINEMATIC
#undef LEVEL_BED_CORNERS
#undef LCD_BED_TRAMMING
#endif
/**
@@ -517,20 +517,28 @@
#define HAS_SHARED_MEDIA 1
#endif
// Set SD_DETECT_STATE based on hardware if not overridden
#if PIN_EXISTS(SD_DETECT) && !defined(SD_DETECT_STATE)
#if BOTH(HAS_MARLINUI_MENU, ELB_FULL_GRAPHIC_CONTROLLER) && (SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION))
#define SD_DETECT_STATE HIGH
#else
#define SD_DETECT_STATE LOW
#endif
#endif
// Extender cable doesn't support SD_DETECT_PIN
#if ENABLED(NO_SD_DETECT)
#undef SD_DETECT_PIN
#endif
// Not onboard or custom cable
#if SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION)
#define SD_CONNECTION_TYPICAL 1
#endif
// Set SD_DETECT_STATE based on hardware if not overridden
#if PIN_EXISTS(SD_DETECT)
#define HAS_SD_DETECT 1
#ifndef SD_DETECT_STATE
#if ALL(SD_CONNECTION_TYPICAL, HAS_MARLINUI_MENU, ELB_FULL_GRAPHIC_CONTROLLER)
#define SD_DETECT_STATE HIGH
#else
#define SD_DETECT_STATE LOW
#endif
#endif
#endif
#if DISABLED(USB_FLASH_DRIVE_SUPPORT) || BOTH(MULTI_VOLUME, VOLUME_SD_ONBOARD)
#if ENABLED(SDIO_SUPPORT)
#define NEED_SD2CARD_SDIO 1
@@ -539,10 +547,10 @@
#endif
#endif
#endif
#if HAS_SD_DETECT && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2)
#define REINIT_NOISY_LCD 1 // Have the LCD re-init on SD insertion
#endif
#if PIN_EXISTS(SD_DETECT) && NONE(HAS_GRAPHICAL_TFT, LCD_USE_DMA_FSMC, HAS_FSMC_GRAPHICAL_TFT, HAS_SPI_GRAPHICAL_TFT, IS_DWIN_MARLINUI, EXTENSIBLE_UI, HAS_DWIN_E3V2)
#define REINIT_NOISY_LCD 1 // Have the LCD re-init on SD insertion
#endif
/**
+32 -14
View File
@@ -371,7 +371,7 @@
#elif defined(FILAMENT_CHANGE_LOAD_LENGTH)
#error "FILAMENT_CHANGE_LOAD_LENGTH is now FILAMENT_CHANGE_FAST_LOAD_LENGTH."
#elif defined(LEVEL_CORNERS_INSET)
#error "LEVEL_CORNERS_INSET is now LEVEL_CORNERS_INSET_LFRB."
#error "LEVEL_CORNERS_INSET is now BED_TRAMMING_INSET_LFRB."
#elif defined(BEZIER_JERK_CONTROL)
#error "BEZIER_JERK_CONTROL is now S_CURVE_ACCELERATION."
#elif HAS_JUNCTION_DEVIATION && defined(JUNCTION_DEVIATION_FACTOR)
@@ -627,6 +627,12 @@
#error "Y_DUAL_STEPPER_DRIVERS is no longer needed and should be removed."
#elif defined(NUM_Z_STEPPER_DRIVERS)
#error "NUM_Z_STEPPER_DRIVERS is no longer needed and should be removed."
#elif defined(LEVEL_BED_CORNERS)
#error "LEVEL_BED_CORNERS is now LCD_BED_TRAMMING."
#elif defined(LEVEL_CORNERS_INSET_LFRB) || defined(LEVEL_CORNERS_HEIGHT) || defined(LEVEL_CORNERS_Z_HOP) || defined(LEVEL_CORNERS_USE_PROBE) || defined(LEVEL_CORNERS_PROBE_TOLERANCE) || defined(LEVEL_CORNERS_VERIFY_RAISED) || defined(LEVEL_CORNERS_AUDIO_FEEDBACK)
#error "LEVEL_CORNERS_* settings have been renamed BED_TRAMMING_*."
#elif defined(LEVEL_CENTER_TOO)
#error "LEVEL_CENTER_TOO is now BED_TRAMMING_INCLUDE_CENTER."
#endif
constexpr float arm[] = AXIS_RELATIVE_MODES;
@@ -887,9 +893,10 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
/**
* SD Card Settings
*/
#if ALL(SDSUPPORT, ELB_FULL_GRAPHIC_CONTROLLER, HAS_MARLINUI_MENU) && PIN_EXISTS(SD_DETECT) && SD_DETECT_STATE != HIGH && (SD_CONNECTION_IS(LCD) || !defined(SDCARD_CONNECTION))
#if ALL(SDSUPPORT, HAS_SD_DETECT, SD_CONNECTION_TYPICAL, ELB_FULL_GRAPHIC_CONTROLLER, HAS_MARLINUI_MENU) && SD_DETECT_STATE == LOW
#error "SD_DETECT_STATE must be set HIGH for SD on the ELB_FULL_GRAPHIC_CONTROLLER."
#endif
#undef SD_CONNECTION_TYPICAL
/**
* SD File Sorting
@@ -1824,14 +1831,14 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#endif
#if ENABLED(LEVEL_BED_CORNERS)
#ifndef LEVEL_CORNERS_INSET_LFRB
#error "LEVEL_BED_CORNERS requires LEVEL_CORNERS_INSET_LFRB values."
#elif ENABLED(LEVEL_CORNERS_USE_PROBE)
#if ENABLED(LCD_BED_TRAMMING)
#ifndef BED_TRAMMING_INSET_LFRB
#error "LCD_BED_TRAMMING requires BED_TRAMMING_INSET_LFRB values."
#elif ENABLED(BED_TRAMMING_USE_PROBE)
#if !HAS_BED_PROBE
#error "LEVEL_CORNERS_USE_PROBE requires a real probe."
#error "BED_TRAMMING_USE_PROBE requires a real probe."
#elif ENABLED(SENSORLESS_PROBING)
#error "LEVEL_CORNERS_USE_PROBE is incompatible with SENSORLESS_PROBING."
#error "BED_TRAMMING_USE_PROBE is incompatible with SENSORLESS_PROBING."
#endif
#endif
#endif
@@ -2952,8 +2959,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "DWIN_CREALITY_LCD does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU."
#elif EITHER(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU)
#error "DWIN_CREALITY_LCD does not support MPC_EDIT_MENU or MPC_AUTOTUNE_MENU."
#elif ENABLED(LEVEL_BED_CORNERS)
#error "DWIN_CREALITY_LCD does not support LEVEL_BED_CORNERS."
#elif ENABLED(LCD_BED_TRAMMING)
#error "DWIN_CREALITY_LCD does not support LCD_BED_TRAMMING."
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
#error "DWIN_CREALITY_LCD does not support LCD_BED_LEVELING with PROBE_MANUALLY."
#endif
@@ -2964,8 +2971,8 @@ static_assert(Y_MAX_LENGTH >= Y_BED_SIZE, "Movement bounds (Y_MIN_POS, Y_MAX_POS
#error "DWIN_LCD_PROUI does not support PID_EDIT_MENU or PID_AUTOTUNE_MENU."
#elif EITHER(MPC_EDIT_MENU, MPC_AUTOTUNE_MENU)
#error "DWIN_LCD_PROUI does not support MPC_EDIT_MENU or MPC_AUTOTUNE_MENU."
#elif ENABLED(LEVEL_BED_CORNERS)
#error "DWIN_LCD_PROUI does not support LEVEL_BED_CORNERS."
#elif ENABLED(LCD_BED_TRAMMING)
#error "DWIN_LCD_PROUI does not support LCD_BED_TRAMMING."
#elif BOTH(LCD_BED_LEVELING, PROBE_MANUALLY)
#error "DWIN_LCD_PROUI does not support LCD_BED_LEVELING with PROBE_MANUALLY."
#endif
@@ -3867,6 +3874,7 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
#error "Enabled an inline laser feature without inline laser power being enabled."
#endif
#endif
#define _PIN_CONFLICT(P) (PIN_EXISTS(P) && P##_PIN == SPINDLE_LASER_PWM_PIN)
#if BOTH(SPINDLE_FEATURE, LASER_FEATURE)
#error "Enable only one of SPINDLE_FEATURE or LASER_FEATURE."
@@ -3934,6 +3942,11 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
#endif
#endif
#undef _PIN_CONFLICT
#ifdef LASER_SAFETY_TIMEOUT_MS
static_assert(LASER_SAFETY_TIMEOUT_MS < (DEFAULT_STEPPER_DEACTIVE_TIME) * 1000UL, "LASER_SAFETY_TIMEOUT_MS must be less than DEFAULT_STEPPER_DEACTIVE_TIME (" STRINGIFY(DEFAULT_STEPPER_DEACTIVE_TIME) " seconds)");
#endif
#endif
#if ENABLED(COOLANT_MIST) && !PIN_EXISTS(COOLANT_MIST)
@@ -4115,8 +4128,8 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
#error "DGUS_LCD_UI_RELOADED requires a bed probe."
#elif !HAS_MESH
#error "DGUS_LCD_UI_RELOADED requires mesh leveling."
#elif DISABLED(LEVEL_BED_CORNERS)
#error "DGUS_LCD_UI_RELOADED requires LEVEL_BED_CORNERS."
#elif DISABLED(LCD_BED_TRAMMING)
#error "DGUS_LCD_UI_RELOADED requires LCD_BED_TRAMMING."
#elif DISABLED(BABYSTEP_ALWAYS_AVAILABLE)
#error "DGUS_LCD_UI_RELOADED requires BABYSTEP_ALWAYS_AVAILABLE."
#elif DISABLED(BABYSTEP_ZPROBE_OFFSET)
@@ -4137,3 +4150,8 @@ static_assert(_PLUS_TEST(4), "HOMING_FEEDRATE_MM_M values must be positive.");
#elif ENABLED(DISABLE_JTAG) && !defined(JTAG_DISABLE)
#error "DISABLE_JTAG is not supported for the selected MCU/Board."
#endif
// Check requirements for upload.py
#if ENABLED(XFER_BUILD) && !BOTH(BINARY_FILE_TRANSFER, CUSTOM_FIRMWARE_UPLOAD)
#error "BINARY_FILE_TRANSFER and CUSTOM_FIRMWARE_UPLOAD are required for custom upload."
#endif
+2 -2
View File
@@ -25,7 +25,7 @@
* Release version. Leave the Marlin version or apply a custom scheme.
*/
#ifndef SHORT_BUILD_VERSION
#define SHORT_BUILD_VERSION "bugfix-2.0.x"
#define SHORT_BUILD_VERSION "bugfix-2.1.x"
#endif
/**
@@ -42,7 +42,7 @@
* version was tagged.
*/
#ifndef STRING_DISTRIBUTION_DATE
#define STRING_DISTRIBUTION_DATE "2022-05-17"
#define STRING_DISTRIBUTION_DATE "2022-06-08"
#endif
/**
+5 -5
View File
@@ -992,7 +992,7 @@ void lcd_put_int(const int i) { lcd.print(i); }
// return < 0 on error
// return the advanced cols
int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
// find the HD44780 internal ROM first
int ret;
@@ -1047,9 +1047,9 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
*
* Draw a UTF-8 string
*/
static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
static int lcd_put_u8str_max_cb(const char * utf8_str, read_byte_cb_t cb_read_byte, const pixel_len_t max_length) {
pixel_len_t ret = 0;
uint8_t *p = (uint8_t *)utf8_str;
const uint8_t *p = (uint8_t *)utf8_str;
while (ret < max_length) {
wchar_t ch = 0;
p = get_utf8_value_cb(p, cb_read_byte, &ch);
@@ -1059,11 +1059,11 @@ static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(u
return (int)ret;
}
int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
}
int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
return lcd_put_u8str_max_cb(utf8_pstr, read_byte_rom, max_length);
}
+25 -24
View File
@@ -410,7 +410,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
// Scroll the PSTR 'text' in a 'len' wide field for 'time' milliseconds at position col,line
void lcd_scroll(const lcd_uint_t col, const lcd_uint_t line, FSTR_P const ftxt, const uint8_t len, const int16_t time) {
uint8_t slen = utf8_strlen_P(FTOP(ftxt));
uint8_t slen = utf8_strlen(ftxt);
if (slen < len) {
lcd_put_u8str_max(col, line, ftxt, len);
for (; slen < len; ++slen) lcd_put_wchar(' ');
@@ -437,10 +437,10 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
}
}
static void logo_lines(PGM_P const extra) {
int16_t indent = (LCD_WIDTH - 8 - utf8_strlen_P(extra)) / 2;
static void logo_lines(FSTR_P const extra) {
int16_t indent = (LCD_WIDTH - 8 - utf8_strlen(extra)) / 2;
lcd_put_wchar(indent, 0, '\x00'); lcd_put_u8str(F( "------" )); lcd_put_wchar('\x01');
lcd_put_u8str(indent, 1, F("|Marlin|")); lcd_put_u8str_P(extra);
lcd_put_u8str(indent, 1, F("|Marlin|")); lcd_put_u8str(extra);
lcd_put_wchar(indent, 2, '\x02'); lcd_put_u8str(F( "------" )); lcd_put_wchar('\x03');
}
@@ -468,7 +468,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
//
// Show the Marlin logo, splash line1, and splash line 2
//
logo_lines(PSTR(" " SHORT_BUILD_VERSION));
logo_lines(F(" " SHORT_BUILD_VERSION));
CENTER_OR_SCROLL(MARLIN_WEBSITE_URL, 2000);
}
else {
@@ -476,7 +476,7 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
// Show the Marlin logo and short build version
// After a delay show the website URL
//
logo_lines(NUL_STR);
logo_lines(FPSTR(NUL_STR));
CENTER_OR_SCROLL(SHORT_BUILD_VERSION, 1500);
CENTER_OR_SCROLL(MARLIN_WEBSITE_URL, 1500);
#ifdef STRING_SPLASH_LINE3
@@ -495,12 +495,13 @@ void MarlinUI::clear_lcd() { lcd.clear(); }
#endif // SHOW_BOOTSCREEN
void MarlinUI::draw_kill_screen() {
lcd_put_u8str(0, 0, status_message);
lcd_uint_t y = 2;
lcd_uint_t x = 0, y = 0;
lcd_put_u8str(x, y, status_message);
y = 2;
#if LCD_HEIGHT >= 4
lcd_put_u8str(0, y++, GET_TEXT_F(MSG_HALTED));
lcd_put_u8str(x, y++, GET_TEXT_F(MSG_HALTED));
#endif
lcd_put_u8str(0, y, GET_TEXT_F(MSG_PLEASE_RESET));
lcd_put_u8str(x, y, GET_TEXT_F(MSG_PLEASE_RESET));
}
//
@@ -1067,33 +1068,33 @@ void MarlinUI::draw_status_screen() {
#endif // ADVANCED_PAUSE_FEATURE
// Draw a static item with no left-right margin required. Centered by default.
void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
int8_t n = LCD_WIDTH;
lcd_moveto(0, row);
const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0,
const int8_t plen = fstr ? utf8_strlen(fstr) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
if (style & SS_CENTER) {
int8_t pad = (LCD_WIDTH - plen - vlen) / 2;
while (--pad >= 0) { lcd_put_wchar(' '); n--; }
}
if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n);
if (plen) n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n);
if (vlen) n -= lcd_put_u8str_max(vstr, n);
for (; n > 0; --n) lcd_put_wchar(' ');
}
// Draw a generic menu item with pre_char (if selected) and post_char
void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) {
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char pre_char, const char post_char) {
lcd_put_wchar(0, row, sel ? pre_char : ' ');
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2);
uint8_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2);
for (; n; --n) lcd_put_wchar(' ');
lcd_put_wchar(post_char);
}
// Draw a menu item with a (potentially) editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const inStr, const bool pgm) {
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0;
lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen);
uint8_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2 - vlen);
if (vlen) {
lcd_put_wchar(':');
for (; n; --n) lcd_put_wchar(' ');
@@ -1102,9 +1103,9 @@ void MarlinUI::draw_status_screen() {
}
// Low-level draw_edit_screen can be used to draw an edit screen from anyplace
void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) {
void MenuEditItemBase::draw_edit_screen(FSTR_P const ftpl, const char * const value/*=nullptr*/) {
ui.encoder_direction_normal();
uint8_t n = lcd_put_u8str_ind_P(0, 1, pstr, itemIndex, itemString, LCD_WIDTH - 1);
uint8_t n = lcd_put_u8str(0, 1, ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 1);
if (value) {
lcd_put_wchar(':'); n--;
const uint8_t len = utf8_strlen(value) + 1; // Plus one for a leading space
@@ -1115,21 +1116,21 @@ void MarlinUI::draw_status_screen() {
}
// The Select Screen presents a prompt and two "buttons"
void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) {
void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) {
ui.draw_select_screen_prompt(pref, string, suff);
if (no) {
SETCURSOR(0, LCD_HEIGHT - 1);
lcd_put_wchar(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd_put_wchar(yesno ? ' ' : ']');
lcd_put_wchar(yesno ? ' ' : '['); lcd_put_u8str(no); lcd_put_wchar(yesno ? ' ' : ']');
}
if (yes) {
SETCURSOR_RJ(utf8_strlen_P(yes) + 2, LCD_HEIGHT - 1);
lcd_put_wchar(yesno ? '[' : ' '); lcd_put_u8str_P(yes); lcd_put_wchar(yesno ? ']' : ' ');
SETCURSOR_RJ(utf8_strlen(yes) + 2, LCD_HEIGHT - 1);
lcd_put_wchar(yesno ? '[' : ' '); lcd_put_u8str(yes); lcd_put_wchar(yesno ? ']' : ' ');
}
}
#if ENABLED(SDSUPPORT)
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
lcd_put_wchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
constexpr uint8_t maxlen = LCD_WIDTH - 2;
uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
+5 -5
View File
@@ -991,7 +991,7 @@ void lcd_put_int(const int i) {
// return < 0 on error
// return the advanced cols
int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
// find the HD44780 internal ROM first
int ret;
@@ -1045,9 +1045,9 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
*
* Draw a UTF-8 string
*/
static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
static int lcd_put_u8str_max_cb(const char * utf8_str, read_byte_cb_t cb_read_byte, const pixel_len_t max_length) {
pixel_len_t ret = 0;
uint8_t *p = (uint8_t *)utf8_str;
const uint8_t *p = (uint8_t *)utf8_str;
while (ret < max_length) {
wchar_t ch = 0;
p = get_utf8_value_cb(p, cb_read_byte, &ch);
@@ -1057,11 +1057,11 @@ static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(u
return (int)ret;
}
int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
}
int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
return lcd_put_u8str_max_cb(utf8_pstr, read_byte_rom, max_length);
}
+90 -89
View File
@@ -380,13 +380,14 @@ void MarlinUI::clear_lcd() {
void MarlinUI::_set_contrast() { lcd.setContrast(contrast); }
#endif
static void center_text_P(PGM_P pstart, uint8_t y) {
uint8_t len = utf8_strlen_P(pstart);
if (len < LCD_WIDTH)
lcd.setCursor((LCD_WIDTH - len) / 2, y);
else
lcd.setCursor(0, y);
lcd_put_u8str_P(pstart);
#if !IS_TFTGLCD_PANEL
void lcd_moveto(const uint8_t col, const uint8_t row) { lcd.setCursor(col, row); }
#endif
static void center_text(FSTR_P const fstart, const uint8_t y) {
const uint8_t len = utf8_strlen(fstart);
lcd_moveto(len < LCD_WIDTH ? (LCD_WIDTH - len) / 2 : 0, y);
lcd_put_u8str(fstart);
}
#if ENABLED(SHOW_BOOTSCREEN)
@@ -399,11 +400,11 @@ static void center_text_P(PGM_P pstart, uint8_t y) {
uint8_t indent = (LCD_WIDTH - 8) / 2;
// symbols 217 (bottom right corner) and 218 (top left corner) are using for letters in some languages
// and they should be moved to beginning ASCII table as special symbols
lcd.setCursor(indent, 0); lcd.write(TLC); lcd_put_u8str(F("------")); lcd.write(TRC);
lcd.setCursor(indent, 1); lcd.write(LR); lcd_put_u8str(F("Marlin")); lcd.write(LR);
lcd.setCursor(indent, 2); lcd.write(BLC); lcd_put_u8str(F("------")); lcd.write(BRC);
center_text_P(PSTR(SHORT_BUILD_VERSION), 3);
center_text_P(PSTR(MARLIN_WEBSITE_URL), 4);
lcd_moveto(indent, 0); lcd.write(TLC); lcd_put_u8str(F("------")); lcd.write(TRC);
lcd_moveto(indent, 1); lcd.write(LR); lcd_put_u8str(F("Marlin")); lcd.write(LR);
lcd_moveto(indent, 2); lcd.write(BLC); lcd_put_u8str(F("------")); lcd.write(BRC);
center_text(F(SHORT_BUILD_VERSION), 3);
center_text(F(MARLIN_WEBSITE_URL), 4);
picBits = ICON_LOGO;
lcd.print_screen();
}
@@ -417,11 +418,11 @@ static void center_text_P(PGM_P pstart, uint8_t y) {
void MarlinUI::draw_kill_screen() {
if (!PanelDetected) return;
lcd.clear_buffer();
lcd.setCursor(0, 3); lcd.write(COLOR_ERROR);
lcd.setCursor((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3);
lcd_moveto(0, 3); lcd.write(COLOR_ERROR);
lcd_moveto((LCD_WIDTH - utf8_strlen(status_message)) / 2 + 1, 3);
lcd_put_u8str(status_message);
center_text_P(GET_TEXT(MSG_HALTED), 5);
center_text_P(GET_TEXT(MSG_PLEASE_RESET), 6);
center_text(GET_TEXT_F(MSG_HALTED), 5);
center_text(GET_TEXT_F(MSG_PLEASE_RESET), 6);
lcd.print_screen();
}
@@ -456,25 +457,25 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
#if HOTENDS < 2
if (heater_id == H_E0) {
lcd.setCursor(2, 5); lcd.print(prefix); //HE
lcd.setCursor(1, 6); lcd.print(i16tostr3rj(t1));
lcd.setCursor(1, 7);
lcd_moveto(2, 5); lcd.print(prefix); //HE
lcd_moveto(1, 6); lcd.print(i16tostr3rj(t1));
lcd_moveto(1, 7);
}
else {
lcd.setCursor(6, 5); lcd.print(prefix); //BED
lcd.setCursor(6, 6); lcd.print(i16tostr3rj(t1));
lcd.setCursor(6, 7);
lcd_moveto(6, 5); lcd.print(prefix); //BED
lcd_moveto(6, 6); lcd.print(i16tostr3rj(t1));
lcd_moveto(6, 7);
}
#else
if (heater_id > H_BED) {
lcd.setCursor(heater_id * 4, 5); lcd.print(prefix); // HE1 or HE2 or HE3
lcd.setCursor(heater_id * 4, 6); lcd.print(i16tostr3rj(t1));
lcd.setCursor(heater_id * 4, 7);
lcd_moveto(heater_id * 4, 5); lcd.print(prefix); // HE1 or HE2 or HE3
lcd_moveto(heater_id * 4, 6); lcd.print(i16tostr3rj(t1));
lcd_moveto(heater_id * 4, 7);
}
else {
lcd.setCursor(13, 5); lcd.print(prefix); //BED
lcd.setCursor(13, 6); lcd.print(i16tostr3rj(t1));
lcd.setCursor(13, 7);
lcd_moveto(13, 5); lcd.print(prefix); //BED
lcd_moveto(13, 6); lcd.print(i16tostr3rj(t1));
lcd_moveto(13, 7);
}
#endif // HOTENDS <= 1
@@ -515,9 +516,9 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
FORCE_INLINE void _draw_cooler_status(const bool blink) {
const celsius_t t2 = thermalManager.degTargetCooler();
lcd.setCursor(0, 5); lcd_put_u8str(F("COOL"));
lcd.setCursor(1, 6); lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegCooler()));
lcd.setCursor(1, 7);
lcd_moveto(0, 5); lcd_put_u8str(F("COOL"));
lcd_moveto(1, 6); lcd_put_u8str(i16tostr3rj(thermalManager.wholeDegCooler()));
lcd_moveto(1, 7);
#if !HEATER_IDLE_HANDLER
UNUSED(blink);
@@ -543,9 +544,9 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
#if ENABLED(LASER_COOLANT_FLOW_METER)
FORCE_INLINE void _draw_flowmeter_status() {
lcd.setCursor(5, 5); lcd_put_u8str(F("FLOW"));
lcd.setCursor(7, 6); lcd_put_wchar('L');
lcd.setCursor(6, 7); lcd_put_u8str(ftostr11ns(cooler.flowrate));
lcd_moveto(5, 5); lcd_put_u8str(F("FLOW"));
lcd_moveto(7, 6); lcd_put_wchar('L');
lcd_moveto(6, 7); lcd_put_u8str(ftostr11ns(cooler.flowrate));
if (cooler.flowrate) picBits |= ICON_FAN;
else picBits &= ~ICON_FAN;
@@ -556,18 +557,18 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
#if ENABLED(I2C_AMMETER)
FORCE_INLINE void _draw_ammeter_status() {
lcd.setCursor(10, 5); lcd_put_u8str(F("ILAZ"));
lcd_moveto(10, 5); lcd_put_u8str(F("ILAZ"));
ammeter.read();
lcd.setCursor(11, 6);
lcd_moveto(11, 6);
if (ammeter.current <= 0.999f)
{
lcd_put_u8str("mA");
lcd.setCursor(10, 7);
lcd_moveto(10, 7);
lcd_put_wchar(' '); lcd_put_u8str(ui16tostr3rj(uint16_t(ammeter.current * 1000 + 0.5f)));
}
else {
lcd_put_u8str(" A");
lcd.setCursor(10, 7);
lcd_moveto(10, 7);
lcd_put_u8str(ftostr12ns(ammeter.current));
}
@@ -580,16 +581,16 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
#if HAS_CUTTER
FORCE_INLINE void _draw_cutter_status() {
lcd.setCursor(15, 5); lcd_put_u8str(F("CUTT"));
lcd_moveto(15, 5); lcd_put_u8str(F("CUTT"));
#if CUTTER_UNIT_IS(RPM)
lcd.setCursor(16, 6); lcd_put_u8str(F("RPM"));
lcd.setCursor(15, 7); lcd_put_u8str(ftostr31ns(float(cutter.unitPower) / 1000));
lcd_moveto(16, 6); lcd_put_u8str(F("RPM"));
lcd_moveto(15, 7); lcd_put_u8str(ftostr31ns(float(cutter.unitPower) / 1000));
lcd_put_wchar('K');
#elif CUTTER_UNIT_IS(PERCENT)
lcd.setCursor(17, 6); lcd_put_wchar('%');
lcd.setCursor(18, 7); lcd_put_u8str(cutter_power2str(cutter.unitPower));
lcd_moveto(17, 6); lcd_put_wchar('%');
lcd_moveto(18, 7); lcd_put_u8str(cutter_power2str(cutter.unitPower));
#else
lcd.setCursor(17, 7); lcd_put_u8str(cutter_power2str(cutter.unitPower));
lcd_moveto(17, 7); lcd_put_u8str(cutter_power2str(cutter.unitPower));
#endif
if (cutter.unitPower) picBits |= ICON_HOT;
@@ -625,10 +626,10 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
lcd.write('%'); lcd.write(percent);
}
else { // For progress bar test
lcd.setCursor(LCD_WIDTH / 2 - 2, MIDDLE_Y);
lcd.print(i16tostr3rj(percent)); lcd.write('%');
lcd_moveto(LCD_WIDTH / 2 - 2, MIDDLE_Y);
lcd.print(i16tostr3rj(percent)); lcd.write('%');
lcd.print_line();
lcd.setCursor(0, MIDDLE_Y + 1);
lcd_moveto(0, MIDDLE_Y + 1);
lcd.write('%'); lcd.write(percent);
lcd.print_line();
}
@@ -638,7 +639,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
void MarlinUI::draw_status_message(const bool blink) {
if (!PanelDetected) return;
lcd.setCursor(0, 3);
lcd_moveto(0, 3);
#if BOTH(FILAMENT_LCD_DISPLAY, SDSUPPORT)
// Alternate Status message and Filament display
@@ -787,7 +788,7 @@ void MarlinUI::draw_status_screen() {
// Line 1 - XYZ coordinates
//
lcd.setCursor(0, 0);
lcd_moveto(0, 0);
const xyz_pos_t lpos = current_position.asLogical();
_draw_axis_value(X_AXIS, ftostr4sign(lpos.x), blink); lcd.write(' ');
_draw_axis_value(Y_AXIS, ftostr4sign(lpos.y), blink); lcd.write(' ');
@@ -801,11 +802,11 @@ void MarlinUI::draw_status_screen() {
// Line 2 - feedrate, , time
//
lcd.setCursor(0, 1);
lcd_moveto(0, 1);
lcd_put_u8str(F("FR")); lcd.print(i16tostr3rj(feedrate_percentage)); lcd.write('%');
#if BOTH(SDSUPPORT, HAS_PRINT_PROGRESS)
lcd.setCursor(LCD_WIDTH / 2 - 3, 1);
lcd_moveto(LCD_WIDTH / 2 - 3, 1);
_draw_print_progress();
#endif
@@ -813,14 +814,14 @@ void MarlinUI::draw_status_screen() {
duration_t elapsed = print_job_timer.duration();
uint8_t len = elapsed.toDigital(buffer);
lcd.setCursor((LCD_WIDTH - 1) - len, 1);
lcd_moveto((LCD_WIDTH - 1) - len, 1);
lcd.write(LCD_STR_CLOCK[0]); lcd.print(buffer);
//
// Line 3 - progressbar
//
lcd.setCursor(0, 2);
lcd_moveto(0, 2);
#if ENABLED(LCD_PROGRESS_BAR)
draw_progress_bar(_get_progress());
#else
@@ -839,7 +840,7 @@ void MarlinUI::draw_status_screen() {
#if HOTENDS <= 1 || (HOTENDS <= 2 && !HAS_HEATED_BED)
#if DUAL_MIXING_EXTRUDER
lcd.setCursor(0, 4);
lcd_moveto(0, 4);
// Two-component mix / gradient instead of XY
char mixer_messages[12];
const char *mix_label;
@@ -895,9 +896,9 @@ void MarlinUI::draw_status_screen() {
#else
#define FANX 17
#endif
lcd.setCursor(FANX, 5); lcd_put_u8str(F("FAN"));
lcd.setCursor(FANX + 1, 6); lcd.write('%');
lcd.setCursor(FANX, 7);
lcd_moveto(FANX, 5); lcd_put_u8str(F("FAN"));
lcd_moveto(FANX + 1, 6); lcd.write('%');
lcd_moveto(FANX, 7);
lcd.print(i16tostr3rj(per));
if (TERN0(HAS_FAN0, thermalManager.fan_speed[0]) || TERN0(HAS_FAN1, thermalManager.fan_speed[1]) || TERN0(HAS_FAN2, thermalManager.fan_speed[2]))
@@ -930,7 +931,7 @@ void MarlinUI::draw_status_screen() {
void MarlinUI::draw_hotend_status(const uint8_t row, const uint8_t extruder) {
if (!PanelDetected) return;
lcd.setCursor((LCD_WIDTH - 14) / 2, row + 1);
lcd_moveto((LCD_WIDTH - 14) / 2, row + 1);
lcd.write(LCD_STR_THERMOMETER[0]); lcd_put_u8str(F(" E")); lcd.write('1' + extruder); lcd.write(' ');
lcd.print(i16tostr3rj(thermalManager.wholeDegHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]); lcd.write('/');
lcd.print(i16tostr3rj(thermalManager.degTargetHotend(extruder))); lcd.write(LCD_STR_DEGREE[0]);
@@ -940,58 +941,58 @@ void MarlinUI::draw_status_screen() {
#endif
// Draw a static item with no left-right margin required. Centered by default.
void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const fstr, const uint8_t style/*=SS_DEFAULT*/, const char * const valstr/*=nullptr*/) {
if (!PanelDetected) return;
uint8_t n = LCD_WIDTH;
lcd.setCursor(0, row);
lcd_moveto(0, row);
if ((style & SS_CENTER) && !valstr) {
int8_t pad = (LCD_WIDTH - utf8_strlen_P(pstr)) / 2;
int8_t pad = (LCD_WIDTH - utf8_strlen(fstr)) / 2;
while (--pad >= 0) { lcd.write(' '); n--; }
}
n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n);
n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, n);
if (valstr) n -= lcd_put_u8str_max(valstr, n);
for (; n; --n) lcd.write(' ');
lcd.print_line();
}
// Draw a generic menu item with pre_char (if selected) and post_char
void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char pre_char, const char post_char) {
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char pre_char, const char post_char) {
if (!PanelDetected) return;
lcd.setCursor(0, row);
lcd_moveto(0, row);
lcd.write(sel ? pre_char : ' ');
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2);
uint8_t n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2);
for (; n; --n) lcd.write(' ');
lcd.write(post_char);
lcd.print_line();
}
// Draw a menu item with a (potentially) editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const data, const bool pgm) {
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const fstr, const char * const inStr, const bool pgm) {
if (!PanelDetected) return;
const uint8_t vlen = data ? (pgm ? utf8_strlen_P(data) : utf8_strlen(data)) : 0;
lcd.setCursor(0, row);
const uint8_t vlen = inStr ? (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)) : 0;
lcd_moveto(0, row);
lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
uint8_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vlen);
uint8_t n = lcd_put_u8str(fstr, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2 - vlen);
if (vlen) {
lcd.write(':');
for (; n; --n) lcd.write(' ');
if (pgm) lcd_put_u8str_P(data); else lcd_put_u8str(data);
if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr);
}
lcd.print_line();
}
// Low-level draw_edit_screen can be used to draw an edit screen from anyplace
// This line moves to the last line of the screen for UBL plot screen on the panel side
void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) {
void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char * const value/*=nullptr*/) {
if (!PanelDetected) return;
ui.encoder_direction_normal();
const uint8_t y = TERN0(AUTO_BED_LEVELING_UBL, ui.external_control) ? LCD_HEIGHT - 1 : MIDDLE_Y;
lcd.setCursor(0, y);
lcd_moveto(0, y);
lcd.write(COLOR_EDIT);
lcd_put_u8str_P(pstr);
lcd_put_u8str(fstr);
if (value) {
lcd.write(':');
lcd.setCursor((LCD_WIDTH - 1) - (utf8_strlen(value) + 1), y); // Right-justified, padded by spaces
lcd_moveto((LCD_WIDTH - 1) - (utf8_strlen(value) + 1), y); // Right-justified, padded by spaces
lcd.write(' '); // Overwrite char if value gets shorter
lcd.print(value);
lcd.write(' ');
@@ -1000,26 +1001,26 @@ void MarlinUI::draw_status_screen() {
}
// The Select Screen presents a prompt and two "buttons"
void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string, PGM_P const suff) {
void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const pref, const char * const string, FSTR_P const suff) {
if (!PanelDetected) return;
ui.draw_select_screen_prompt(pref, string, suff);
lcd.write(COLOR_EDIT);
if (no) {
lcd.setCursor(0, MIDDLE_Y);
lcd.write(yesno ? ' ' : '['); lcd_put_u8str_P(no); lcd.write(yesno ? ' ' : ']');
lcd_moveto(0, MIDDLE_Y);
lcd.write(yesno ? ' ' : '['); lcd_put_u8str(no); lcd.write(yesno ? ' ' : ']');
}
if (yes) {
lcd.setCursor(LCD_WIDTH - utf8_strlen_P(yes) - 3, MIDDLE_Y);
lcd.write(yesno ? '[' : ' '); lcd_put_u8str_P(yes); lcd.write(yesno ? ']' : ' ');
lcd_moveto(LCD_WIDTH - utf8_strlen(yes) - 3, MIDDLE_Y);
lcd.write(yesno ? '[' : ' '); lcd_put_u8str(yes); lcd.write(yesno ? ']' : ' ');
}
lcd.print_line();
}
#if ENABLED(SDSUPPORT)
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
if (!PanelDetected) return;
lcd.setCursor(0, row);
lcd_moveto(0, row);
lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
constexpr uint8_t maxlen = LCD_WIDTH - 2;
uint8_t n = maxlen - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
@@ -1058,30 +1059,30 @@ void MarlinUI::draw_status_screen() {
lcd.clear_buffer();
//print only top left corner. All frame with grid points will be printed by panel
lcd.setCursor(0, 0);
lcd_moveto(0, 0);
*fb++ = TLC; //top left corner - marker for plot parameters
*fb = (GRID_MAX_POINTS_X << 4) + GRID_MAX_POINTS_Y; //set mesh size
// Print plot position
lcd.setCursor(_LCD_W_POS, 0);
*fb++ = '('; lcd.print(i16tostr3left(x_plot));
*fb++ = ','; lcd.print(i16tostr3left(y_plot)); *fb = ')';
lcd_moveto(_LCD_W_POS, 0);
*fb++ = '('; lcd.print(i16tostr3left(x_plot));
*fb++ = ','; lcd.print(i16tostr3left(y_plot)); *fb = ')';
// Show all values
lcd.setCursor(_LCD_W_POS, 1); lcd_put_u8str(F("X:"));
lcd_moveto(_LCD_W_POS, 1); lcd_put_u8str(F("X:"));
lcd.print(ftostr52(LOGICAL_X_POSITION(pgm_read_float(&bedlevel._mesh_index_to_xpos[x_plot]))));
lcd.setCursor(_LCD_W_POS, 2); lcd_put_u8str(F("Y:"));
lcd_moveto(_LCD_W_POS, 2); lcd_put_u8str(F("Y:"));
lcd.print(ftostr52(LOGICAL_Y_POSITION(pgm_read_float(&bedlevel._mesh_index_to_ypos[y_plot]))));
// Show the location value
lcd.setCursor(_LCD_W_POS, 3); lcd_put_u8str(F("Z:"));
lcd_moveto(_LCD_W_POS, 3); lcd_put_u8str(F("Z:"));
if (!isnan(bedlevel.z_values[x_plot][y_plot]))
lcd.print(ftostr43sign(bedlevel.z_values[x_plot][y_plot]));
else
lcd_put_u8str(F(" -----"));
center_text_P(GET_TEXT(MSG_UBL_FINE_TUNE_MESH), 8);
center_text(GET_TEXT_F(MSG_UBL_FINE_TUNE_MESH), 8);
lcd.print_screen();
}
+3 -3
View File
@@ -28,7 +28,7 @@ void lcd_put_int(const int i) { u8g.print(i); }
// return < 0 on error
// return the advanced pixels
int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
if (c < 256) {
u8g.print((char)c);
return u8g_GetFontBBXWidth(u8g.getU8g());
@@ -39,14 +39,14 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
return ret;
}
int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
ret = uxg_DrawUtf8Str(u8g.getU8g(), x, y, utf8_str, max_length);
u8g.setPrintPos(x + ret, y);
return ret;
}
int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
u8g_uint_t x = u8g.getPrintCol(), y = u8g.getPrintRow(),
ret = uxg_DrawUtf8StrP(u8g.getU8g(), x, y, utf8_pstr, max_length);
u8g.setPrintPos(x + ret, y);
+24 -24
View File
@@ -330,13 +330,13 @@ void MarlinUI::update_language_font() {
// The kill screen is displayed for unrecoverable conditions
void MarlinUI::draw_kill_screen() {
TERN_(LIGHTWEIGHT_UI, ST7920_Lite_Status_Screen::clear_text_buffer());
const u8g_uint_t h4 = u8g.getHeight() / 4;
const u8g_uint_t x = 0, h4 = u8g.getHeight() / 4;
u8g.firstPage();
do {
set_font(FONT_MENU);
lcd_put_u8str(0, h4 * 1, status_message);
lcd_put_u8str(0, h4 * 2, GET_TEXT_F(MSG_HALTED));
lcd_put_u8str(0, h4 * 3, GET_TEXT_F(MSG_PLEASE_RESET));
lcd_put_u8str(x, h4 * 1, status_message);
lcd_put_u8str(x, h4 * 2, GET_TEXT_F(MSG_HALTED));
lcd_put_u8str(x, h4 * 3, GET_TEXT_F(MSG_PLEASE_RESET));
} while (u8g.nextPage());
}
@@ -412,28 +412,28 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
}
// Draw a static line of text in the same idiom as a menu item
void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
if (mark_as_selected(row, style & SS_INVERT)) {
pixel_len_t n = LCD_PIXEL_WIDTH; // pixel width of string allowed
const int plen = pstr ? calculateWidth(pstr) : 0,
const int plen = ftpl ? calculateWidth(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
if (style & SS_CENTER) {
int pad = (LCD_PIXEL_WIDTH - plen - vlen * MENU_FONT_WIDTH) / MENU_FONT_WIDTH / 2;
while (--pad >= 0) n -= lcd_put_wchar(' ');
}
if (plen) n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH);
if (plen) n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, n / (MENU_FONT_WIDTH)) * (MENU_FONT_WIDTH);
if (vlen) n -= lcd_put_u8str_max(vstr, n);
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
}
}
// Draw a generic menu item
void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) {
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) {
if (mark_as_selected(row, sel)) {
pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 1) * (MENU_FONT_WIDTH);
pixel_len_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 1) * (MENU_FONT_WIDTH);
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
lcd_put_wchar(LCD_PIXEL_WIDTH - (MENU_FONT_WIDTH), row_y2, post_char);
lcd_put_wchar(' ');
@@ -441,27 +441,27 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
}
// Draw a menu item with an editable value
void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char * const inStr, const bool pgm) {
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
if (mark_as_selected(row, sel)) {
const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen((char*)inStr)),
pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), (char*)inStr));
const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(inStr)),
pixelwidth = (pgm ? uxg_GetUtf8StrPixelWidthP(u8g.getU8g(), inStr) : uxg_GetUtf8StrPixelWidth(u8g.getU8g(), inStr));
const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;
pixel_len_t n = lcd_put_u8str_ind_P(pstr, itemIndex, itemString, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH);
pixel_len_t n = lcd_put_u8str(ftpl, itemIndex, itemStringC, itemStringF, LCD_WIDTH - 2 - vallen * prop) * (MENU_FONT_WIDTH);
if (vallen) {
lcd_put_wchar(':');
while (n > MENU_FONT_WIDTH) n -= lcd_put_wchar(' ');
lcd_moveto(LCD_PIXEL_WIDTH - _MAX((MENU_FONT_WIDTH) * vallen, pixelwidth + 2), row_y2);
if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str((char*)inStr);
if (pgm) lcd_put_u8str_P(inStr); else lcd_put_u8str(inStr);
}
}
}
void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char * const value/*=nullptr*/) {
void MenuEditItemBase::draw_edit_screen(FSTR_P const ftpl, const char * const value/*=nullptr*/) {
ui.encoder_direction_normal();
const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;
const u8g_uint_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value);
const u8g_uint_t labellen = utf8_strlen(ftpl), vallen = utf8_strlen(value);
bool extra_row = labellen * prop > LCD_WIDTH - 2 - vallen * prop;
#if ENABLED(USE_BIG_EDIT_FONT)
@@ -490,7 +490,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
// Assume the label is alpha-numeric (with a descender)
bool onpage = PAGE_CONTAINS(baseline - (EDIT_FONT_ASCENT - 1), baseline + EDIT_FONT_DESCENT);
if (onpage) lcd_put_u8str_ind_P(0, baseline, pstr, itemIndex, itemString);
if (onpage) lcd_put_u8str(0, baseline, ftpl, itemIndex, itemStringC, itemStringF);
// If a value is included, print a colon, then print the value right-justified
if (value) {
@@ -508,8 +508,8 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
TERN_(USE_BIG_EDIT_FONT, ui.set_font(FONT_MENU));
}
inline void draw_boxed_string(const u8g_uint_t x, const u8g_uint_t y, PGM_P const pstr, const bool inv) {
const u8g_uint_t len = utf8_strlen_P(pstr),
inline void draw_boxed_string(const u8g_uint_t x, const u8g_uint_t y, FSTR_P const fstr, const bool inv) {
const u8g_uint_t len = utf8_strlen(fstr),
by = (y + 1) * (MENU_FONT_HEIGHT);
const u8g_uint_t prop = USE_WIDE_GLYPH ? 2 : 1;
const pixel_len_t bw = len * prop * (MENU_FONT_WIDTH), bx = x * prop * (MENU_FONT_WIDTH);
@@ -518,19 +518,19 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
u8g.drawBox(bx / prop - 1, by - (MENU_FONT_ASCENT), bw + 2, MENU_FONT_HEIGHT);
u8g.setColorIndex(0);
}
lcd_put_u8str_P(bx / prop, by, pstr);
lcd_put_u8str(bx / prop, by, fstr);
if (inv) u8g.setColorIndex(1);
}
void MenuItem_confirm::draw_select_screen(PGM_P const yes, PGM_P const no, const bool yesno, PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/) {
ui.draw_select_screen_prompt(pref, string, suff);
void MenuItem_confirm::draw_select_screen(FSTR_P const yes, FSTR_P const no, const bool yesno, FSTR_P const fpre, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/) {
ui.draw_select_screen_prompt(fpre, string, suff);
if (no) draw_boxed_string(1, LCD_HEIGHT - 1, no, !yesno);
if (yes) draw_boxed_string(LCD_WIDTH - (utf8_strlen_P(yes) * (USE_WIDE_GLYPH ? 2 : 1) + 1), LCD_HEIGHT - 1, yes, yesno);
if (yes) draw_boxed_string(LCD_WIDTH - (utf8_strlen(yes) * (USE_WIDE_GLYPH ? 2 : 1) + 1), LCD_HEIGHT - 1, yes, yesno);
}
#if ENABLED(SDSUPPORT)
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
if (mark_as_selected(row, sel)) {
const uint8_t maxlen = LCD_WIDTH - isDir;
if (isDir) lcd_put_wchar(LCD_STR_FOLDER[0]);
@@ -517,14 +517,14 @@ U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT,
drawCross(x, y, TFT_MARLINBG_COLOR);
}
const char *str = nullptr;
FSTR_P str = nullptr;
if (calibration_stage < CALIBRATION_SUCCESS) {
// handle current state
switch (calibration_stage) {
case CALIBRATION_TOP_LEFT: str = GET_TEXT(MSG_TOP_LEFT); break;
case CALIBRATION_BOTTOM_LEFT: str = GET_TEXT(MSG_BOTTOM_LEFT); break;
case CALIBRATION_TOP_RIGHT: str = GET_TEXT(MSG_TOP_RIGHT); break;
case CALIBRATION_BOTTOM_RIGHT: str = GET_TEXT(MSG_BOTTOM_RIGHT); break;
case CALIBRATION_TOP_LEFT: str = GET_TEXT_F(MSG_TOP_LEFT); break;
case CALIBRATION_BOTTOM_LEFT: str = GET_TEXT_F(MSG_BOTTOM_LEFT); break;
case CALIBRATION_TOP_RIGHT: str = GET_TEXT_F(MSG_TOP_RIGHT); break;
case CALIBRATION_BOTTOM_RIGHT: str = GET_TEXT_F(MSG_BOTTOM_RIGHT); break;
default: break;
}
@@ -534,7 +534,7 @@ U8G_PB_DEV(u8g_dev_tft_320x240_upscale_from_128x64, WIDTH, HEIGHT, PAGE_HEIGHT,
}
else {
// end calibration
str = calibration_stage == CALIBRATION_SUCCESS ? GET_TEXT(MSG_CALIBRATION_COMPLETED) : GET_TEXT(MSG_CALIBRATION_FAILED);
str = calibration_stage == CALIBRATION_SUCCESS ? GET_TEXT_F(MSG_CALIBRATION_COMPLETED) : GET_TEXT_F(MSG_CALIBRATION_FAILED);
defer_status_screen(false);
touch_calibration.calibration_end();
TERN_(HAS_TOUCH_BUTTONS, redrawTouchButtons = true);
+1 -1
View File
@@ -104,7 +104,7 @@ static void fontgroup_drawwchar(font_group_t *group, const font_t *fnt_default,
* Get the screen pixel width of a ROM UTF-8 string
*/
static void fontgroup_drawstring(font_group_t *group, const font_t *fnt_default, const char *utf8_msg, read_byte_cb_t cb_read_byte, void * userdata, fontgroup_cb_draw_t cb_draw_ram) {
uint8_t *p = (uint8_t*)utf8_msg;
const uint8_t *p = (uint8_t*)utf8_msg;
for (;;) {
wchar_t val = 0;
p = get_utf8_value_cb(p, cb_read_byte, &val);
+3 -3
View File
@@ -26,10 +26,10 @@ typedef struct _uxg_fontinfo_t {
int uxg_SetUtf8Fonts(const uxg_fontinfo_t * fntinfo, int number); // fntinfo is type of PROGMEM
unsigned int uxg_DrawWchar(u8g_t *pu8g, unsigned int x, unsigned int y, wchar_t ch, pixel_len_t max_length);
unsigned int uxg_DrawWchar(u8g_t *pu8g, unsigned int x, unsigned int y, wchar_t ch, const pixel_len_t max_length);
unsigned int uxg_DrawUtf8Str(u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, pixel_len_t max_length);
unsigned int uxg_DrawUtf8StrP(u8g_t *pu8g, unsigned int x, unsigned int y, PGM_P utf8_msg, pixel_len_t max_length);
unsigned int uxg_DrawUtf8Str(u8g_t *pu8g, unsigned int x, unsigned int y, const char *utf8_msg, const pixel_len_t max_length);
unsigned int uxg_DrawUtf8StrP(u8g_t *pu8g, unsigned int x, unsigned int y, PGM_P utf8_msg, const pixel_len_t max_length);
int uxg_GetUtf8StrPixelWidth(u8g_t *pu8g, const char *utf8_msg);
int uxg_GetUtf8StrPixelWidthP(u8g_t *pu8g, PGM_P utf8_msg);
+1 -1
View File
@@ -1,6 +1,6 @@
# DWIN for Creality Ender 3 v2
Marlin's Ender 3 v2 support requires the `DWIN_SET` included with the Ender 3 V2 [example configuration](https://github.com/MarlinFirmware/Configurations/tree/bugfix-2.0.x/config/examples/Creality/Ender-3%20V2).
Marlin's Ender 3 v2 support requires the `DWIN_SET` included with the Ender 3 V2 [example configuration](https://github.com/MarlinFirmware/Configurations/tree/bugfix-2.1.x/config/examples/Creality/Ender-3%20V2).
## Easy Install
+1 -1
View File
@@ -74,7 +74,7 @@ inline void DWIN_Text(size_t &i, const char * const string, uint16_t rlimit=0xFF
inline void DWIN_Text(size_t &i, FSTR_P string, uint16_t rlimit=0xFFFF) {
if (!string) return;
const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, _MIN(rlimit, strlen_P((PGM_P)string))); // cast to PGM_P (const char*) measure with strlen_P.
const size_t len = _MIN(sizeof(DWIN_SendBuf) - i, _MIN(rlimit, strlen_P(FTOP(string))));
if (len == 0) return;
memcpy_P(&DWIN_SendBuf[i+1], string, len);
i += len;
+1 -1
View File
@@ -1,6 +1,6 @@
# DWIN for Creality Ender 3 v2
Marlin's Ender 3 v2 support requires the `DWIN_SET` included with the Ender 3 V2 [example configuration](https://github.com/MarlinFirmware/Configurations/tree/bugfix-2.0.x/config/examples/Creality/Ender-3%20V2).
Marlin's Ender 3 v2 support requires the `DWIN_SET` included with the Ender 3 V2 [example configuration](https://github.com/MarlinFirmware/Configurations/tree/bugfix-2.1.x/config/examples/Creality/Ender-3%20V2).
## Easy Install
+173 -8
View File
@@ -121,6 +121,26 @@
#define MIN_BED_TEMP 0
#endif
/**
* Custom menu items with jyersLCD
*/
#if ENABLED(CUSTOM_MENU_CONFIG)
#ifdef CONFIG_MENU_ITEM_5_DESC
#define CUSTOM_MENU_COUNT 5
#elif defined(CONFIG_MENU_ITEM_4_DESC)
#define CUSTOM_MENU_COUNT 4
#elif defined(CONFIG_MENU_ITEM_3_DESC)
#define CUSTOM_MENU_COUNT 3
#elif defined(CONFIG_MENU_ITEM_2_DESC)
#define CUSTOM_MENU_COUNT 2
#elif defined(CONFIG_MENU_ITEM_1_DESC)
#define CUSTOM_MENU_COUNT 1
#endif
#if CUSTOM_MENU_COUNT
#define HAS_CUSTOM_MENU 1
#endif
#endif
constexpr uint16_t TROWS = 6, MROWS = TROWS - 1,
TITLE_HEIGHT = 30,
MLINE = 53,
@@ -1078,7 +1098,8 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/
#define PREPARE_PREHEAT (PREPARE_ZOFFSET + ENABLED(HAS_PREHEAT))
#define PREPARE_COOLDOWN (PREPARE_PREHEAT + EITHER(HAS_HOTEND, HAS_HEATED_BED))
#define PREPARE_CHANGEFIL (PREPARE_COOLDOWN + ENABLED(ADVANCED_PAUSE_FEATURE))
#define PREPARE_TOTAL PREPARE_CHANGEFIL
#define PREPARE_CUSTOM_MENU (PREPARE_CHANGEFIL + ENABLED(HAS_CUSTOM_MENU))
#define PREPARE_TOTAL PREPARE_CUSTOM_MENU
switch (item) {
case PREPARE_BACK:
@@ -1153,6 +1174,18 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/
break;
#endif
#if HAS_CUSTOM_MENU
case PREPARE_CUSTOM_MENU:
#ifndef CUSTOM_MENU_CONFIG_TITLE
#define CUSTOM_MENU_CONFIG_TITLE "Custom Commands"
#endif
if (draw)
Draw_Menu_Item(row, ICON_Version, F(CUSTOM_MENU_CONFIG_TITLE));
else
Draw_Menu(MenuCustom);
break;
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE)
case PREPARE_CHANGEFIL:
if (draw) {
@@ -1750,6 +1783,126 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/
break;
#endif // FILAMENT_LOAD_UNLOAD_GCODES
#if HAS_CUSTOM_MENU
case MenuCustom:
#define CUSTOM_MENU_BACK 0
#define CUSTOM_MENU_1 1
#define CUSTOM_MENU_2 2
#define CUSTOM_MENU_3 3
#define CUSTOM_MENU_4 4
#define CUSTOM_MENU_5 5
#define CUSTOM_MENU_TOTAL CUSTOM_MENU_COUNT
switch (item) {
case CUSTOM_MENU_BACK:
if (draw)
Draw_Menu_Item(row, ICON_Back, F("Back"));
else
Draw_Menu(Prepare, PREPARE_CUSTOM_MENU);
break;
#if CUSTOM_MENU_COUNT >= 1
case CUSTOM_MENU_1:
if (draw)
Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_1_DESC));
else {
Popup_Handler(Custom);
//queue.inject(F(CONFIG_MENU_ITEM_1_GCODE)); // Old code
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_1_GCODE));
planner.synchronize();
Redraw_Menu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
AudioFeedback();
#endif
#ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN
queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE));
#endif
}
break;
#endif
#if CUSTOM_MENU_COUNT >= 2
case CUSTOM_MENU_2:
if (draw)
Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_2_DESC));
else {
Popup_Handler(Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_2_GCODE));
planner.synchronize();
Redraw_Menu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
AudioFeedback();
#endif
#ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN
queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE));
#endif
}
break;
#endif
#if CUSTOM_MENU_COUNT >= 3
case CUSTOM_MENU_3:
if (draw)
Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_3_DESC));
else {
Popup_Handler(Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_3_GCODE));
planner.synchronize();
Redraw_Menu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
AudioFeedback();
#endif
#ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN
queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE));
#endif
}
break;
#endif
#if CUSTOM_MENU_COUNT >= 4
case CUSTOM_MENU_4:
if (draw)
Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_4_DESC));
else {
Popup_Handler(Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_4_GCODE));
planner.synchronize();
Redraw_Menu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
AudioFeedback();
#endif
#ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN
queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE));
#endif
}
break;
#endif
#if CUSTOM_MENU_COUNT >= 5
case CUSTOM_MENU_5:
if (draw)
Draw_Menu_Item(row, ICON_Info, F(CONFIG_MENU_ITEM_5_DESC));
else {
Popup_Handler(Custom);
gcode.process_subcommands_now(F(CONFIG_MENU_ITEM_5_GCODE));
planner.synchronize();
Redraw_Menu();
#if ENABLED(CUSTOM_MENU_CONFIG_SCRIPT_AUDIBLE_FEEDBACK)
AudioFeedback();
#endif
#ifdef CUSTOM_MENU_CONFIG_SCRIPT_RETURN
queue.inject(F(CUSTOM_MENU_CONFIG_SCRIPT_DONE));
#endif
}
break;
#endif // Custom Menu
}
break;
#endif // HAS_CUSTOM_MENU
case Control:
#define CONTROL_BACK 0
@@ -2944,7 +3097,7 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/
break;
case LEVELING_VIEW:
if (draw)
Draw_Menu_Item(row, ICON_Mesh, GET_TEXT(MSG_MESH_VIEW), nullptr, true);
Draw_Menu_Item(row, ICON_Mesh, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true);
else {
#if ENABLED(AUTO_BED_LEVELING_UBL)
if (bedlevel.storage_slot < 0) {
@@ -3017,7 +3170,7 @@ void CrealityDWINClass::Menu_Item_Handler(uint8_t menu, uint8_t item, bool draw/
break;
case LEVELING_VIEW_MESH:
if (draw)
Draw_Menu_Item(row, ICON_PrintSize, GET_TEXT(MSG_MESH_VIEW), nullptr, true);
Draw_Menu_Item(row, ICON_PrintSize, GET_TEXT_F(MSG_MESH_VIEW), nullptr, true);
else
Draw_Menu(MeshViewer);
break;
@@ -3688,6 +3841,14 @@ FSTR_P CrealityDWINClass::Get_Menu_Title(uint8_t menu) {
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
case ChangeFilament: return F("Change Filament");
#endif
#if HAS_CUSTOM_MENU
case MenuCustom:
#ifdef CUSTOM_MENU_CONFIG_TITLE
return F(CUSTOM_MENU_CONFIG_TITLE);
#else
return F("Custom Commands");
#endif
#endif
case Control: return F("Control");
case TempMenu: return F("Temperature");
#if HAS_HOTEND || HAS_HEATED_BED
@@ -3753,6 +3914,9 @@ uint8_t CrealityDWINClass::Get_Menu_Size(uint8_t menu) {
#if ENABLED(FILAMENT_LOAD_UNLOAD_GCODES)
case ChangeFilament: return CHANGEFIL_TOTAL;
#endif
#if HAS_CUSTOM_MENU
case MenuCustom: return CUSTOM_MENU_TOTAL;
#endif
case Control: return CONTROL_TOTAL;
case TempMenu: return TEMP_TOTAL;
#if HAS_HOTEND || HAS_HEATED_BED
@@ -3831,6 +3995,7 @@ void CrealityDWINClass::Popup_Handler(PopupID popupid, bool option/*=false*/) {
case Runout: Draw_Popup(F("Filament Runout"), F(""), F(""), Wait, ICON_BLTouch); break;
case PIDWait: Draw_Popup(F("PID Autotune"), F("in process"), F("Please wait until done."), Wait, ICON_BLTouch); break;
case Resuming: Draw_Popup(F("Resuming Print"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break;
case Custom: Draw_Popup(F("Running Custom GCode"), F("Please wait until done."), F(""), Wait, ICON_BLTouch); break;
default: break;
}
}
@@ -4115,14 +4280,14 @@ void CrealityDWINClass::Print_Screen_Control() {
card.startOrResumeFilePrinting();
TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
#else
char cmnd[20];
char cmd[20];
#if HAS_HEATED_BED
cmnd[sprintf_P(cmnd, PSTR("M140 S%i"), pausebed)] = '\0';
gcode.process_subcommands_now(cmnd);
sprintf_P(cmd, PSTR("M140 S%i"), pausebed);
gcode.process_subcommands_now(cmd);
#endif
#if HAS_EXTRUDERS
cmnd[sprintf_P(cmnd, PSTR("M109 S%i"), pausetemp)] = '\0';
gcode.process_subcommands_now(cmnd);
sprintf_P(cmd, PSTR("M109 S%i"), pausetemp);
gcode.process_subcommands_now(cmd);
#endif
TERN_(HAS_FAN, thermalManager.fan_speed[0] = pausefan);
planner.synchronize();
+2 -1
View File
@@ -43,7 +43,7 @@ enum processID : uint8_t {
enum PopupID : uint8_t {
Pause, Stop, Resume, SaveLevel, ETemp, ConfFilChange, PurgeMore, MeshSlot,
Level, Home, MoveWait, Heating, FilLoad, FilChange, TempWarn, Runout, PIDWait, Resuming, ManualProbing,
FilInsert, HeaterTime, UserInput, LevelError, InvalidMesh, UI, Complete
FilInsert, HeaterTime, UserInput, LevelError, InvalidMesh, UI, Complete, Custom
};
enum menuID : uint8_t {
@@ -55,6 +55,7 @@ enum menuID : uint8_t {
ZOffset,
Preheat,
ChangeFilament,
MenuCustom,
Control,
TempMenu,
PID,
+31 -29
View File
@@ -27,35 +27,35 @@
#include "dwin_string.h"
//#include "../../fontutils.h"
uint8_t DWIN_String::data[];
char DWIN_String::data[];
uint16_t DWIN_String::span;
uint8_t DWIN_String::len;
uint8_t DWIN_String::length;
void DWIN_String::set() {
//*data = 0x00;
memset(data, 0x00, sizeof(data));
span = 0;
len = 0;
length = 0;
}
uint8_t read_byte(uint8_t *byte) { return *byte; }
uint8_t read_byte(const uint8_t *byte) { return *byte; }
/**
* Add a string, applying substitutions for the following characters:
*
* $ displays the clipped C-string given by the itemString argument
* $ displays the clipped string given by fstr or cstr
* = displays '0'....'10' for indexes 0 - 10
* ~ displays '1'....'11' for indexes 0 - 10
* * displays 'E1'...'E11' for indexes 0 - 10 (By default. Uses LCD_FIRST_TOOL)
* @ displays an axis name such as XYZUVW, or E for an extruder
*/
void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *itemString/*=nullptr*/) {
void DWIN_String::add(const char *tpl, const int8_t index, const char *cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/) {
wchar_t wchar;
while (*string) {
string = get_utf8_value_cb(string, read_byte, &wchar);
while (*tpl) {
tpl = get_utf8_value_cb(tpl, read_byte, &wchar);
if (wchar > 255) wchar |= 0x0080;
uint8_t ch = uint8_t(wchar & 0x00FF);
const uint8_t ch = uint8_t(wchar & 0x00FF);
if (ch == '=' || ch == '~' || ch == '*') {
if (index >= 0) {
@@ -65,10 +65,12 @@ void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *itemString/*
add_character('0' + inum);
}
else
add(index == -2 ? GET_TEXT(MSG_CHAMBER) : GET_TEXT(MSG_BED));
add(index == -2 ? GET_TEXT_F(MSG_CHAMBER) : GET_TEXT_F(MSG_BED));
}
else if (ch == '$' && itemString)
add(itemString);
else if (ch == '$' && fstr)
add(fstr);
else if (ch == '$' && cstr)
add(cstr);
else if (ch == '@')
add_character(AXIS_CHAR(index));
else
@@ -77,10 +79,10 @@ void DWIN_String::add(uint8_t *string, const int8_t index, uint8_t *itemString/*
eol();
}
void DWIN_String::add(uint8_t *string, uint8_t max_len) {
void DWIN_String::add(const char *cstr, uint8_t max_len/*=MAX_STRING_LENGTH*/) {
wchar_t wchar;
while (*string && max_len) {
string = get_utf8_value_cb(string, read_byte, &wchar);
while (*cstr && max_len) {
cstr = get_utf8_value_cb(cstr, read_byte, &wchar);
/*
if (wchar > 255) wchar |= 0x0080;
uint8_t ch = uint8_t(wchar & 0x00FF);
@@ -92,7 +94,7 @@ void DWIN_String::add(uint8_t *string, uint8_t max_len) {
eol();
}
void DWIN_String::add(wchar_t character) {
void DWIN_String::add(const wchar_t character) {
int ret;
size_t idx = 0;
dwin_charmap_t pinval;
@@ -127,18 +129,18 @@ void DWIN_String::add(wchar_t character) {
if (str[1]) add_character(str[1]);
}
void DWIN_String::add_character(const uint8_t character) {
if (len < MAX_STRING_LENGTH) {
data[len] = character;
len++;
void DWIN_String::add_character(const char character) {
if (length < MAX_STRING_LENGTH) {
data[length] = character;
length++;
//span += glyph(character)->DWidth;
}
}
void DWIN_String::rtrim(const uint8_t character) {
while (len) {
if (data[len - 1] == 0x20 || data[len - 1] == character) {
len--;
void DWIN_String::rtrim(const char character) {
while (length) {
if (data[length - 1] == 0x20 || data[length - 1] == character) {
length--;
//span -= glyph(data[length])->DWidth;
eol();
}
@@ -147,18 +149,18 @@ void DWIN_String::rtrim(const uint8_t character) {
}
}
void DWIN_String::ltrim(const uint8_t character) {
void DWIN_String::ltrim(const char character) {
uint16_t i, j;
for (i = 0; (i < len) && (data[i] == 0x20 || data[i] == character); i++) {
for (i = 0; (i < length) && (data[i] == 0x20 || data[i] == character); i++) {
//span -= glyph(data[i])->DWidth;
}
if (i == 0) return;
for (j = 0; i < len; data[j++] = data[i++]);
len = j;
for (j = 0; i < length; data[j++] = data[i++]);
length = j;
eol();
}
void DWIN_String::trim(const uint8_t character) {
void DWIN_String::trim(const char character) {
rtrim(character);
ltrim(character);
}
+64 -20
View File
@@ -21,6 +21,8 @@
*/
#pragma once
// TODO: Make AVR-compatible with separate ROM / RAM string methods
#include "../../fontutils.h"
#include "../../marlinui.h"
@@ -41,14 +43,14 @@ class DWIN_String {
//static glyph_t *glyphs[256];
//static font_t *font_header;
static uint8_t data[MAX_STRING_LENGTH + 1];
static char data[MAX_STRING_LENGTH + 1];
static uint16_t span; // in pixels
static uint8_t len; // in characters
static void add_character(const uint8_t character);
static void eol() { data[len] = 0x00; }
static void add_character(const char character);
static void eol() { data[length] = 0x00; }
public:
static uint8_t length; // in characters
//static void set_font(const uint8_t *font);
//static void add_glyphs(const uint8_t *font);
@@ -57,29 +59,71 @@ class DWIN_String {
//static glyph_t *glyph(uint8_t character) { return glyphs[character] ?: glyphs[0x3F]; } /* Use '?' for unknown glyphs */
//static glyph_t *glyph(uint8_t *character) { return glyph(*character); }
/**
* @brief Set the string empty
*/
static void set();
//static void add(uint8_t character) { add_character(character); eol(); }
//static void add(const char character) { add_character(character); eol(); }
/**
* @brief Append a UTF-8 character
*
* @param character The UTF-8 character
*/
static void add(wchar_t character);
static void add(uint8_t *string, uint8_t max_len=MAX_STRING_LENGTH);
static void add(uint8_t *string, const int8_t index, uint8_t *itemString=nullptr);
static void set(uint8_t *string) { set(); add(string); }
static void set(wchar_t character) { set(); add(character); }
static void set(uint8_t *string, int8_t index, const char *itemString=nullptr) { set(); add(string, index, (uint8_t *)itemString); }
static void set(FSTR_P fstring) { set((uint8_t *)fstring); }
static void set(const char *string) { set((uint8_t *)string); }
static void set(const char *string, int8_t index, const char *itemString=nullptr) { set((uint8_t *)string, index, itemString); }
static void add(const char *string) { add((uint8_t *)string); }
static void trim(const uint8_t character=0x20);
static void rtrim(const uint8_t character=0x20);
static void ltrim(const uint8_t character=0x20);
/**
* @brief Append / Set C-string
*
* @param cstr The string
* @param max_len Character limit
*/
static void add(const char *cstr, uint8_t max_len=MAX_STRING_LENGTH);
static void set(const char *cstr) { set(); add(cstr); }
static void truncate(uint8_t maxlen) { if (len > maxlen) { len = maxlen; eol(); } }
/**
* @brief Append / Set F-string
*
* @param fstr The string
* @param max_len Character limit
*/
static void add(FSTR_P const fstr, uint8_t max_len=MAX_STRING_LENGTH) { add(FTOP(fstr), max_len); }
static void set(FSTR_P const fstr) { set(FTOP(fstr)); }
static uint8_t length() { return len; }
/**
* @brief Append / Set C-string with optional substitution
*
* @param tpl A string with optional substitution
* @param index An index
* @param cstr An SRAM C-string to use for $ substitution
* @param fstr A ROM F-string to use for $ substitution
*/
static void add(const char *tpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr);
static void set(const char *tpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { set(); add(tpl, index, cstr, fstr); }
/**
* @brief Append / Set F-string with optional substitution
*
* @param ftpl A ROM F-string with optional substitution
* @param index An index
* @param cstr An SRAM C-string to use for $ substitution
* @param fstr A ROM F-string to use for $ substitution
*/
static void add(FSTR_P const ftpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { add(FTOP(ftpl), index, cstr, fstr); }
static void set(FSTR_P const ftpl, const int8_t index, const char *cstr=nullptr, FSTR_P const fstr=nullptr) { set(); add(ftpl, index, cstr, fstr); }
// Common string ops
static void trim(const char character=' ');
static void rtrim(const char character=' ');
static void ltrim(const char character=' ');
static void truncate(const uint8_t maxlen) { if (length > maxlen) { length = maxlen; eol(); } }
// Accessors
static char *string() { return data; }
static uint16_t width() { return span; }
static uint8_t *string() { return data; }
static uint16_t center(uint16_t width) { return span > width ? 0 : (width - span) / 2; }
static uint16_t center(const uint16_t width) { return span > width ? 0 : (width - span) / 2; }
};
int dwin_charmap_compare(dwin_charmap_t *v1, dwin_charmap_t *v2);
+20 -21
View File
@@ -56,20 +56,20 @@ void lcd_put_int(const int i) {
}
int lcd_put_dwin_string() {
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
lcd_advance_cursor(dwin_string.length());
return dwin_string.length();
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
lcd_advance_cursor(dwin_string.length);
return dwin_string.length;
}
// return < 0 on error
// return the advanced cols
int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
int lcd_put_wchar_max(const wchar_t c, const pixel_len_t max_length) {
dwin_string.set(c);
dwin_string.truncate(max_length);
// Draw the char(s) at the cursor and advance the cursor
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
lcd_advance_cursor(dwin_string.length());
return dwin_string.length();
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
lcd_advance_cursor(dwin_string.length);
return dwin_string.length;
}
/**
@@ -83,35 +83,34 @@ int lcd_put_wchar_max(wchar_t c, pixel_len_t max_length) {
*
* Draw a UTF-8 string
*/
static int lcd_put_u8str_max_cb(const char * utf8_str, uint8_t (*cb_read_byte)(uint8_t * str), pixel_len_t max_length) {
uint8_t *p = (uint8_t *)utf8_str;
static int lcd_put_u8str_max_cb(const char * utf8_str, read_byte_cb_t cb_read_byte, const pixel_len_t max_length) {
const uint8_t *p = (uint8_t *)utf8_str;
dwin_string.set();
while (dwin_string.length() < max_length) {
while (dwin_string.length < max_length) {
wchar_t ch = 0;
p = get_utf8_value_cb(p, cb_read_byte, &ch);
if (!ch) break;
dwin_string.add(ch);
}
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
lcd_advance_cursor(dwin_string.length());
return dwin_string.length();
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
lcd_advance_cursor(dwin_string.length);
return dwin_string.length;
}
int lcd_put_u8str_max(const char * utf8_str, pixel_len_t max_length) {
int lcd_put_u8str_max(const char * utf8_str, const pixel_len_t max_length) {
return lcd_put_u8str_max_cb(utf8_str, read_byte_ram, max_length);
}
int lcd_put_u8str_max_P(PGM_P utf8_pstr, pixel_len_t max_length) {
int lcd_put_u8str_max_P(PGM_P utf8_pstr, const pixel_len_t max_length) {
return lcd_put_u8str_max_cb(utf8_pstr, read_byte_rom, max_length);
}
lcd_uint_t lcd_put_u8str_ind_P(PGM_P const pstr, const int8_t ind, PGM_P const inStr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
dwin_string.set();
dwin_string.add((uint8_t*)pstr, ind, (uint8_t*)inStr);
lcd_uint_t lcd_put_u8str_P(PGM_P const ptpl, const int8_t ind, const char * const cstr/*=nullptr*/, FSTR_P const fstr/*=nullptr*/, const lcd_uint_t maxlen/*=LCD_WIDTH*/) {
dwin_string.set(ptpl, ind, cstr, fstr);
dwin_string.truncate(maxlen);
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, (char*)dwin_string.string());
lcd_advance_cursor(dwin_string.length());
return dwin_string.length();
DWIN_Draw_String(dwin_font.solid, dwin_font.index, dwin_font.fg, dwin_font.bg, cursor.x, cursor.y, dwin_string.string());
lcd_advance_cursor(dwin_string.length);
return dwin_string.length;
}
#if ENABLED(DEBUG_LCDPRINT)
+28 -30
View File
@@ -110,7 +110,7 @@ void MarlinUI::clear_lcd() {
#define VERSION_Y 84
#endif
DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length() * 10) / 2, VERSION_Y, S(dwin_string.string()));
DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length * 10) / 2, VERSION_Y, S(dwin_string.string()));
TERN_(SHOW_CUSTOM_BOOTSCREEN, safe_delay(CUSTOM_BOOTSCREEN_TIMEOUT));
clear_lcd();
@@ -127,7 +127,7 @@ void MarlinUI::clear_lcd() {
DWIN_ICON_Show(BOOT_ICON, ICON_MarlinURL, INFO_CENTER - 100 / 2, 152);
DWIN_ICON_Show(BOOT_ICON, ICON_Copyright, INFO_CENTER - 126 / 2, 200);
#endif
DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length() * 10) / 2, VERSION_Y, S(dwin_string.string()));
DWIN_Draw_String(false, font10x20, Color_Yellow, Color_Bg_Black, INFO_CENTER - (dwin_string.length * 10) / 2, VERSION_Y, S(dwin_string.string()));
DWIN_UpdateLCD();
}
@@ -284,7 +284,7 @@ void MarlinUI::draw_status_message(const bool blink) {
else
dwin_string.add(PSTR(" "));
lcd_moveto(LCD_WIDTH - dwin_string.length(), row);
lcd_moveto(LCD_WIDTH - dwin_string.length, row);
lcd_put_dwin_string();
}
@@ -311,7 +311,7 @@ void MarlinUI::draw_status_message(const bool blink) {
// Draw a static line of text in the same idiom as a menu item
void MenuItem_static::draw(const uint8_t row, PGM_P const pstr, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t style/*=SS_DEFAULT*/, const char * const vstr/*=nullptr*/) {
// Call mark_as_selected to draw a bigger selection box
// and draw the text without a background
if (mark_as_selected(row, (bool)(style & SS_INVERT), true)) {
@@ -320,15 +320,15 @@ void MarlinUI::draw_status_message(const bool blink) {
dwin_font.fg = Color_White;
dwin_string.set();
const int8_t plen = pstr ? utf8_strlen_P(pstr) : 0,
const int8_t plen = ftpl ? utf8_strlen(ftpl) : 0,
vlen = vstr ? utf8_strlen(vstr) : 0;
if (style & SS_CENTER) {
int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2;
while (--pad) dwin_string.add(' ');
}
if (plen) dwin_string.add((uint8_t*)pstr, itemIndex, (uint8_t*)itemString);
if (vlen) dwin_string.add((uint8_t*)vstr);
if (plen) dwin_string.add(ftpl, itemIndex, itemStringC, itemStringF);
if (vlen) dwin_string.add(vstr);
if (style & SS_CENTER) {
int8_t pad = (LCD_WIDTH - 1 - plen - vlen) / 2;
while (--pad) dwin_string.add(' ');
@@ -340,15 +340,15 @@ void MarlinUI::draw_status_message(const bool blink) {
}
// Draw a generic menu item
void MenuItemBase::_draw(const bool sel, const uint8_t row, PGM_P const pstr, const char, const char post_char) {
void MenuItemBase::_draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char, const char post_char) {
if (mark_as_selected(row, sel)) {
ui.set_font(DWIN_FONT_MENU);
dwin_font.solid = false;
dwin_font.fg = Color_White;
dwin_string.set(pstr, itemIndex, itemString);
dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF);
pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length();
pixel_len_t n = LCD_WIDTH - 1 - dwin_string.length;
while (--n > 1) dwin_string.add(' ');
dwin_string.add(post_char);
@@ -361,15 +361,15 @@ void MarlinUI::draw_status_message(const bool blink) {
//
// Draw a menu item with an editable value
//
void MenuEditItemBase::draw(const bool sel, const uint8_t row, PGM_P const pstr, const char* const data, const bool pgm) {
void MenuEditItemBase::draw(const bool sel, const uint8_t row, FSTR_P const ftpl, const char * const inStr, const bool pgm) {
if (mark_as_selected(row, sel)) {
ui.set_font(DWIN_FONT_MENU);
dwin_font.solid = false;
dwin_font.fg = Color_White;
const uint8_t vallen = (pgm ? utf8_strlen_P(data) : utf8_strlen(S(data)));
const uint8_t vallen = (pgm ? utf8_strlen_P(inStr) : utf8_strlen(S(inStr)));
dwin_string.set(pstr, itemIndex, itemString);
dwin_string.set(ftpl, itemIndex, itemStringC, itemStringF);
if (vallen) dwin_string.add(':');
lcd_moveto(1, row);
@@ -377,7 +377,7 @@ void MarlinUI::draw_status_message(const bool blink) {
if (vallen) {
dwin_font.fg = Color_Yellow;
dwin_string.set(data);
dwin_string.set(inStr);
lcd_moveto(LCD_WIDTH - vallen - 1, row);
lcd_put_dwin_string();
}
@@ -387,13 +387,12 @@ void MarlinUI::draw_status_message(const bool blink) {
//
// Draw an edit screen with label and current value
//
void MenuEditItemBase::draw_edit_screen(PGM_P const pstr, const char* const value/*=nullptr*/) {
void MenuEditItemBase::draw_edit_screen(FSTR_P const fstr, const char* const value/*=nullptr*/) {
ui.encoder_direction_normal();
const dwin_coord_t labellen = utf8_strlen_P(pstr), vallen = utf8_strlen(value);
const dwin_coord_t labellen = utf8_strlen(fstr), vallen = utf8_strlen(value);
dwin_string.set();
dwin_string.add((uint8_t*)pstr, itemIndex);
dwin_string.set(FTOP(fstr), itemIndex);
if (vallen) dwin_string.add(':'); // If a value is included, add a colon
// Assume the label is alpha-numeric (with a descender)
@@ -406,8 +405,7 @@ void MarlinUI::draw_status_message(const bool blink) {
// If a value is included, print the value in larger text below the label
if (vallen) {
dwin_string.set();
dwin_string.add(value);
dwin_string.set(value);
const dwin_coord_t by = (row * MENU_LINE_HEIGHT) + MENU_FONT_HEIGHT + EXTRA_ROW_HEIGHT / 2;
DWIN_Draw_String(true, font16x32, Color_Yellow, Color_Bg_Black, (LCD_PIXEL_WIDTH - vallen * 16) / 2, by, S(dwin_string.string()));
@@ -430,19 +428,19 @@ void MarlinUI::draw_status_message(const bool blink) {
}
}
inline void draw_boxed_string(const bool yesopt, PGM_P const pstr, const bool inv) {
const uint8_t len = utf8_strlen_P(pstr),
inline void draw_boxed_string(const bool yesopt, FSTR_P const fstr, const bool inv) {
const uint8_t len = utf8_strlen(fstr),
mar = TERN(DWIN_MARLINUI_PORTRAIT, 1, 4),
col = yesopt ? LCD_WIDTH - mar - len : mar,
row = (LCD_HEIGHT >= 8 ? LCD_HEIGHT / 2 + 3 : LCD_HEIGHT - 1);
lcd_moveto(col, row);
DWIN_Draw_Box(1, inv ? Select_Color : Color_Bg_Black, cursor.x - dwin_font.width, cursor.y + 1, dwin_font.width * (len + 2), dwin_font.height + 2);
lcd_put_u8str_P(col, row, pstr);
lcd_put_u8str(col, row, fstr);
}
void MenuItem_confirm::draw_select_screen(
PGM_P const yes, PGM_P const no, const bool yesno,
PGM_P const pref, const char * const string/*=nullptr*/, PGM_P const suff/*=nullptr*/
FSTR_P const yes, FSTR_P const no, const bool yesno,
FSTR_P const pref, const char * const string/*=nullptr*/, FSTR_P const suff/*=nullptr*/
) {
ui.set_font(DWIN_FONT_MENU);
dwin_font.solid = false;
@@ -454,7 +452,7 @@ void MarlinUI::draw_status_message(const bool blink) {
#if ENABLED(SDSUPPORT)
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, PGM_P const, CardReader &theCard, const bool isDir) {
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
if (mark_as_selected(row, sel)) {
dwin_string.set();
@@ -464,8 +462,8 @@ void MarlinUI::draw_status_message(const bool blink) {
maxlen -= 2;
}
dwin_string.add((uint8_t*)ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
uint8_t n = maxlen - dwin_string.length();
dwin_string.add(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
uint8_t n = maxlen - dwin_string.length;
while (n > 0) { dwin_string.add(' '); --n; }
lcd_moveto(1, row);
lcd_put_dwin_string();
@@ -548,7 +546,7 @@ void MarlinUI::draw_status_message(const bool blink) {
dwin_string.add(i8tostr3rj(y_plot));
dwin_string.add(")");
lcd_moveto(
TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length()),
TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length),
TERN(DWIN_MARLINUI_LANDSCAPE, LCD_HEIGHT - 2, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 1)
);
lcd_put_dwin_string();
@@ -560,7 +558,7 @@ void MarlinUI::draw_status_message(const bool blink) {
else
dwin_string.add(PSTR(" -----"));
lcd_moveto(
TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length()),
TERN(DWIN_MARLINUI_LANDSCAPE, ((x_offset + x_map_pixels) / MENU_FONT_WIDTH) + 2, LCD_WIDTH - dwin_string.length),
TERN(DWIN_MARLINUI_LANDSCAPE, LCD_HEIGHT - 1, ((y_offset + y_map_pixels) / MENU_LINE_HEIGHT) + 2)
);
lcd_put_dwin_string();
@@ -72,17 +72,16 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
uint8_t vallen = utf8_strlen(value);
if (!ui.did_first_redraw) {
dwin_string.set();
dwin_string.add('X' + axis);
dwin_string.set('X' + axis);
DWIN_Draw_String(true, font16x32, Color_IconBlue, Color_Bg_Black, x + (vallen * 14 - 14) / 2, y + 2, S(dwin_string.string()));
}
dwin_string.set();
if (blink)
dwin_string.add(value);
else if (!TEST(axis_homed, axis))
else if (!TEST(axes_homed, axis))
while (const char c = *value++) dwin_string.add(c <= '.' ? c : '?');
else if (NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING) && !TEST(axis_trusted, axis))
else if (NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING) && !TEST(axes_trusted, axis))
dwin_string.add(TERN1(DWIN_MARLINUI_PORTRAIT, axis == Z_AXIS) ? PSTR(" ") : PSTR(" "));
else
dwin_string.add(value);
@@ -96,8 +95,7 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
#else // !DWIN_MARLINUI_PORTRAIT
if (!ui.did_first_redraw || ui.old_is_printing != print_job_timer.isRunning()) {
dwin_string.set();
dwin_string.add('X' + axis);
dwin_string.set('X' + axis);
DWIN_Draw_String(true, font16x32, Color_IconBlue, Color_Bg_Black, x, y, S(dwin_string.string()));
}
@@ -105,11 +103,11 @@ FORCE_INLINE void _draw_axis_value(const AxisEnum axis, const char *value, const
if (blink)
dwin_string.add(value);
else {
if (!TEST(axis_homed, axis))
if (!TEST(axes_homed, axis))
while (const char c = *value++) dwin_string.add(c <= '.' ? c : '?');
else {
#if NONE(HOME_AFTER_DEACTIVATE, DISABLE_REDUCED_ACCURACY_WARNING)
if (!TEST(axis_trusted, axis))
if (!TEST(axes_trusted, axis))
dwin_string.add(TERN1(DWIN_MARLINUI_PORTRAIT, axis == Z_AXIS) ? PSTR(" ") : PSTR(" "));
else
#endif
@@ -391,7 +389,7 @@ void MarlinUI::draw_status_screen() {
time.toDigital(buffer);
dwin_string.add(prefix);
dwin_string.add(buffer);
DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, (LCD_PIXEL_WIDTH - ((dwin_string.length() + 1) * 14)), 290, S(dwin_string.string()));
DWIN_Draw_String(true, font14x28, Color_White, Color_Bg_Black, (LCD_PIXEL_WIDTH - ((dwin_string.length + 1) * 14)), 290, S(dwin_string.string()));
#else
@@ -454,7 +452,7 @@ void MarlinUI::draw_status_screen() {
dwin_string.add(PSTR("%"));
DWIN_Draw_String(
false, font16x32, Percent_Color, Color_Bg_Black,
pb_left + (pb_width - dwin_string.length() * 16) / 2,
pb_left + (pb_width - dwin_string.length * 16) / 2,
pb_top + (pb_height - 32) / 2,
S(dwin_string.string())
);
+208
View File
@@ -0,0 +1,208 @@
/**
* Base64 encoder/decoder for arduino repo
* Uses common web conventions - '+' for 62, '/' for 63, '=' for padding.
* Note that invalid base64 characters are interpreted as padding.
* Author: Densaugeo
* Maintainer: Densaugeo
* Version: 1.2.1.1
* Changed unsigned int to uint16_t for use in the professional Ender 3V2/S1 firmware
* Url: https://www.arduino.cc/reference/en/libraries/base64/
*/
#ifndef BASE64_H_INCLUDED
#define BASE64_H_INCLUDED
/* binary_to_base64:
* Description:
* Converts a single byte from a binary value to the corresponding base64 character
* Parameters:
* v - Byte to convert
* Returns:
* ascii code of base64 character. If byte is >= 64, then there is not corresponding base64 character
* and 255 is returned
*/
unsigned char binary_to_base64(unsigned char v);
/* base64_to_binary:
* Description:
* Converts a single byte from a base64 character to the corresponding binary value
* Parameters:
* c - Base64 character (as ascii code)
* Returns:
* 6-bit binary value
*/
unsigned char base64_to_binary(unsigned char c);
/* encode_base64_length:
* Description:
* Calculates length of base64 string needed for a given number of binary bytes
* Parameters:
* input_length - Amount of binary data in bytes
* Returns:
* Number of base64 characters needed to encode input_length bytes of binary data
*/
uint16_t encode_base64_length(uint16_t input_length);
/* decode_base64_length:
* Description:
* Calculates number of bytes of binary data in a base64 string
* Variant that does not use input_length no longer used within library, retained for API compatibility
* Parameters:
* input - Base64-encoded null-terminated string
* input_length (optional) - Number of bytes to read from input pointer
* Returns:
* Number of bytes of binary data in input
*/
uint16_t decode_base64_length(unsigned char input[]);
uint16_t decode_base64_length(unsigned char input[], uint16_t input_length);
/* encode_base64:
* Description:
* Converts an array of bytes to a base64 null-terminated string
* Parameters:
* input - Pointer to input data
* input_length - Number of bytes to read from input pointer
* output - Pointer to output string. Null terminator will be added automatically
* Returns:
* Length of encoded string in bytes (not including null terminator)
*/
uint16_t encode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]);
/* decode_base64:
* Description:
* Converts a base64 null-terminated string to an array of bytes
* Parameters:
* input - Pointer to input string
* input_length (optional) - Number of bytes to read from input pointer
* output - Pointer to output array
* Returns:
* Number of bytes in the decoded binary
*/
uint16_t decode_base64(unsigned char input[], unsigned char output[]);
uint16_t decode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]);
unsigned char binary_to_base64(unsigned char v) {
// Capital letters - 'A' is ascii 65 and base64 0
if (v < 26) return v + 'A';
// Lowercase letters - 'a' is ascii 97 and base64 26
if (v < 52) return v + 71;
// Digits - '0' is ascii 48 and base64 52
if (v < 62) return v - 4;
// '+' is ascii 43 and base64 62
if (v == 62) return '+';
// '/' is ascii 47 and base64 63
if (v == 63) return '/';
return 64;
}
unsigned char base64_to_binary(unsigned char c) {
// Capital letters - 'A' is ascii 65 and base64 0
if ('A' <= c && c <= 'Z') return c - 'A';
// Lowercase letters - 'a' is ascii 97 and base64 26
if ('a' <= c && c <= 'z') return c - 71;
// Digits - '0' is ascii 48 and base64 52
if ('0' <= c && c <= '9') return c + 4;
// '+' is ascii 43 and base64 62
if (c == '+') return 62;
// '/' is ascii 47 and base64 63
if (c == '/') return 63;
return 255;
}
uint16_t encode_base64_length(uint16_t input_length) {
return (input_length + 2)/3*4;
}
uint16_t decode_base64_length(unsigned char input[]) {
return decode_base64_length(input, -1);
}
uint16_t decode_base64_length(unsigned char input[], uint16_t input_length) {
unsigned char *start = input;
while (base64_to_binary(input[0]) < 64 && (unsigned char)(input - start) < input_length) {
++input;
}
input_length = input - start;
return input_length/4*3 + (input_length % 4 ? input_length % 4 - 1 : 0);
}
uint16_t encode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]) {
uint16_t full_sets = input_length/3;
// While there are still full sets of 24 bits...
for (uint16_t i = 0; i < full_sets; ++i) {
output[0] = binary_to_base64( input[0] >> 2);
output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
output[2] = binary_to_base64((input[1] & 0x0F) << 2 | input[2] >> 6);
output[3] = binary_to_base64( input[2] & 0x3F);
input += 3;
output += 4;
}
switch(input_length % 3) {
case 0:
output[0] = '\0';
break;
case 1:
output[0] = binary_to_base64( input[0] >> 2);
output[1] = binary_to_base64((input[0] & 0x03) << 4);
output[2] = '=';
output[3] = '=';
output[4] = '\0';
break;
case 2:
output[0] = binary_to_base64( input[0] >> 2);
output[1] = binary_to_base64((input[0] & 0x03) << 4 | input[1] >> 4);
output[2] = binary_to_base64((input[1] & 0x0F) << 2);
output[3] = '=';
output[4] = '\0';
break;
}
return encode_base64_length(input_length);
}
uint16_t decode_base64(unsigned char input[], unsigned char output[]) {
return decode_base64(input, -1, output);
}
uint16_t decode_base64(unsigned char input[], uint16_t input_length, unsigned char output[]) {
uint16_t output_length = decode_base64_length(input, input_length);
// While there are still full sets of 24 bits...
for (uint16_t i = 2; i < output_length; i += 3) {
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
output[2] = base64_to_binary(input[2]) << 6 | base64_to_binary(input[3]);
input += 4;
output += 3;
}
switch(output_length % 3) {
case 1:
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
break;
case 2:
output[0] = base64_to_binary(input[0]) << 2 | base64_to_binary(input[1]) >> 4;
output[1] = base64_to_binary(input[1]) << 4 | base64_to_binary(input[2]) >> 2;
break;
}
return output_length;
}
#endif // ifndef
+217 -74
View File
@@ -31,6 +31,37 @@
#if ENABLED(DWIN_LCD_PROUI)
#if DISABLED(LIMITED_MAX_FR_EDITING)
#warning "LIMITED_MAX_FR_EDITING is recommended with ProUI."
#endif
#if DISABLED(LIMITED_MAX_ACCEL_EDITING)
#warning "LIMITED_MAX_ACCEL_EDITING is recommended with ProUI."
#endif
#if ENABLED(CLASSIC_JERK) && DISABLED(LIMITED_JERK_EDITING)
#warning "LIMITED_JERK_EDITING is recommended with ProUI."
#endif
#if DISABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU)
#warning "INDIVIDUAL_AXIS_HOMING_SUBMENU is recommended with ProUI."
#endif
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
#warning "LCD_SET_PROGRESS_MANUALLY is recommended with ProUI."
#endif
#if DISABLED(STATUS_MESSAGE_SCROLLING)
#warning "STATUS_MESSAGE_SCROLLING is recommended with ProUI."
#endif
#if DISABLED(BAUD_RATE_GCODE)
#warning "BAUD_RATE_GCODE is recommended with ProUI."
#endif
#if DISABLED(SOUND_MENU_ITEM)
#warning "SOUND_MENU_ITEM is recommended with ProUI."
#endif
#if DISABLED(PRINTCOUNTER)
#warning "PRINTCOUNTER is recommended with ProUI."
#endif
#if HAS_MESH && DISABLED(MESH_EDIT_MENU)
#warning "MESH_EDIT_MENU is recommended with ProUI."
#endif
#include "dwin.h"
#include "menus.h"
#include "dwin_popup.h"
@@ -98,6 +129,14 @@
#include "endstop_diag.h"
#endif
#if HAS_PIDPLOT
#include "plot.h"
#endif
#if HAS_GCODE_PREVIEW
#include "gcode_preview.h"
#endif
#if HAS_MESH
#include "meshviewer.h"
#endif
@@ -162,7 +201,12 @@
#define DWIN_SCROLL_UPDATE_INTERVAL SEC_TO_MS(2)
#define DWIN_REMAIN_TIME_UPDATE_INTERVAL SEC_TO_MS(20)
#define BABY_Z_VAR TERN(HAS_BED_PROBE, probe.offset.z, HMI_data.ManualZOffset)
#if HAS_MESH
#define BABY_Z_VAR TERN(HAS_BED_PROBE, probe.offset.z, HMI_data.ManualZOffset)
#else
float z_offset = 0;
#define BABY_Z_VAR z_offset
#endif
// Structs
HMI_value_t HMI_value;
@@ -200,11 +244,28 @@ uint8_t index_file = MROWS;
bool hash_changed = true; // Flag to know if message status was changed
constexpr float max_feedrate_edit_values[] = MAX_FEEDRATE_EDIT_VALUES;
constexpr float max_acceleration_edit_values[] = MAX_ACCEL_EDIT_VALUES;
constexpr float max_feedrate_edit_values[] =
#ifdef MAX_FEEDRATE_EDIT_VALUES
MAX_FEEDRATE_EDIT_VALUES
#else
{ 1000, 1000, 10, 50 }
#endif
;
constexpr float max_acceleration_edit_values[] =
#ifdef MAX_ACCEL_EDIT_VALUES
MAX_ACCEL_EDIT_VALUES
#else
{ 1000, 1000, 200, 2000 }
#endif
;
#if HAS_CLASSIC_JERK
constexpr float max_jerk_edit_values[] = MAX_JERK_EDIT_VALUES;
constexpr float max_jerk_edit_values[] =
#ifdef MAX_JERK_EDIT_VALUES
MAX_JERK_EDIT_VALUES
#else
{ DEFAULT_XJERK * 2, DEFAULT_YJERK * 2, DEFAULT_ZJERK * 2, DEFAULT_EJERK * 2 }
#endif
;
#endif
static uint8_t _percent_done = 0;
@@ -652,13 +713,19 @@ void Draw_PrintDone() {
Title.ShowCaption(GET_TEXT_F(MSG_PRINT_DONE));
DWINUI::ClearMainArea();
DWIN_Print_Header(nullptr);
Draw_Print_ProgressBar();
Draw_Print_Labels();
DWINUI::Draw_Icon(ICON_PrintTime, 15, 173);
DWINUI::Draw_Icon(ICON_RemainTime, 150, 171);
Draw_Print_ProgressElapsed();
Draw_Print_ProgressRemain();
DWINUI::Draw_Button(BTN_Continue, 86, 273);
if (sdprint && TERN0(HAS_GCODE_PREVIEW, Preview_Valid())) {
DWIN_ICON_Show(0, 0, 1, 21, 100, 0x00);
DWINUI::Draw_Button(BTN_Continue, 86, 300);
}
else {
Draw_Print_ProgressBar();
Draw_Print_Labels();
DWINUI::Draw_Icon(ICON_PrintTime, 15, 173);
DWINUI::Draw_Icon(ICON_RemainTime, 150, 171);
Draw_Print_ProgressElapsed();
Draw_Print_ProgressRemain();
DWINUI::Draw_Button(BTN_Continue, 86, 273);
}
}
void Goto_PrintDone() {
@@ -815,6 +882,8 @@ void update_variable() {
else
DWINUI::Draw_Icon(ICON_Zoffset, 187, 416);
}
#else
DWINUI::Draw_Icon(ICON_Zoffset, 187, 416);
#endif
_draw_xyz_position(false);
@@ -1354,6 +1423,9 @@ void EachMomentUpdate() {
#if HAS_ESDIAG
if (checkkey == ESDiagProcess) ESDiag.Update();
#endif
#if HAS_PIDPLOT
if (checkkey == PidProcess) Plot.Update((HMI_value.pidresult == PID_EXTR_START) ? thermalManager.wholeDegHotend(0) : thermalManager.wholeDegBed());
#endif
}
#if HAS_STATUS_MESSAGE_TIMEOUT
@@ -1580,15 +1652,49 @@ void DWIN_LevelingDone() {
#endif
// PID process
#if HAS_PIDPLOT
void DWIN_Draw_PIDPopup() {
frame_rect_t gfrm = {40, 180, DWIN_WIDTH - 80, 120};
DWINUI::ClearMainArea();
Draw_Popup_Bkgd();
DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 100, GET_TEXT_F(MSG_PID_AUTOTUNE));
DWINUI::Draw_String(HMI_data.PopupTxt_Color, gfrm.x, gfrm.y - DWINUI::fontHeight() - 4, F("PID target: Celsius"));
switch (HMI_value.pidresult) {
case PID_EXTR_START:
DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 120, F("for Nozzle is running."));
Plot.Draw(gfrm, thermalManager.hotend_maxtemp[0], HMI_data.HotendPidT);
DWINUI::Draw_Int(HMI_data.PopupTxt_Color, 3, gfrm.x + 90, gfrm.y - DWINUI::fontHeight() - 4, HMI_data.HotendPidT);
break;
case PID_BED_START:
DWINUI::Draw_CenteredString(HMI_data.PopupTxt_Color, 120, F("for BED is running."));
Plot.Draw(gfrm, BED_MAXTEMP, HMI_data.BedPidT);
DWINUI::Draw_Int(HMI_data.PopupTxt_Color, 3, gfrm.x + 90, gfrm.y - DWINUI::fontHeight() - 4, HMI_data.BedPidT);
break;
default:
break;
}
}
#endif
void DWIN_PidTuning(pidresult_t result) {
HMI_value.pidresult = result;
switch (result) {
case PID_BED_START:
HMI_SaveProcessID(NothingToDo);
DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for BED is running."));
HMI_SaveProcessID(PidProcess);
#if HAS_PIDPLOT
DWIN_Draw_PIDPopup();
#else
DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for BED is running."));
#endif
break;
case PID_EXTR_START:
HMI_SaveProcessID(NothingToDo);
DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for Nozzle is running."));
HMI_SaveProcessID(PidProcess);
#if HAS_PIDPLOT
DWIN_Draw_PIDPopup();
#else
DWIN_Draw_Popup(ICON_TempTooHigh, GET_TEXT_F(MSG_PID_AUTOTUNE), F("for Nozzle is running."));
#endif
break;
case PID_BAD_EXTRUDER_NUM:
checkkey = last_checkkey;
@@ -1905,10 +2011,30 @@ void HMI_LockScreen() {
}
void Goto_ConfirmToPrint() {
card.openAndPrintFile(card.filename);
DWIN_Print_Started(true);
}
#if HAS_GCODE_PREVIEW
void onClick_ConfirmToPrint() {
if (HMI_flag.select_flag) { // Confirm
card.openAndPrintFile(card.filename);
return DWIN_Print_Started(true);
}
else { // Cancel
DWIN_ResetStatusLine();
checkkey = SelectFile;
return Draw_Print_File_Menu();
}
}
void Goto_ConfirmToPrint() {
Goto_Popup(Preview_DrawFromSD, onClick_ConfirmToPrint);
}
#else
void Goto_ConfirmToPrint() {
card.openAndPrintFile(card.filename);
DWIN_Print_Started(true);
}
#endif
#if HAS_ESDIAG
void Draw_EndStopDiag() {
@@ -2292,48 +2418,45 @@ void ApplyFlow() { planner.refresh_e_factor(0); }
void SetFlow() { SetPIntOnClick(MIN_PRINT_FLOW, MAX_PRINT_FLOW, ApplyFlow); }
// Bed Tramming
TERN(HAS_BED_PROBE, float, void) Tram(uint8_t point) {
char cmd[100] = "";
#if HAS_BED_PROBE
void TramXY(const uint8_t point, const float &margin, float &x, float &y) {
switch (point) {
case 0:
LCD_MESSAGE(MSG_LEVBED_FL);
x = y = margin;
break;
case 1:
LCD_MESSAGE(MSG_LEVBED_FR);
x = X_BED_SIZE - margin; y = margin;
break;
case 2:
LCD_MESSAGE(MSG_LEVBED_BR);
x = X_BED_SIZE - margin; y = Y_BED_SIZE - margin;
break;
case 3:
LCD_MESSAGE(MSG_LEVBED_BL);
x = margin; y = Y_BED_SIZE - margin;
break;
case 4:
LCD_MESSAGE(MSG_LEVBED_C);
x = X_CENTER; y = Y_CENTER;
break;
}
}
#if HAS_BED_PROBE
float Tram(const uint8_t point) {
char cmd[100] = "";
static bool inLev = false;
float xpos = 0, ypos = 0, zval = 0, margin = 0;
char str_1[6] = "", str_2[6] = "", str_3[6] = "";
if (inLev) return NAN;
margin = HMI_data.FullManualTramming ? 30 : PROBING_MARGIN;
#else
int16_t xpos = 0, ypos = 0;
int16_t margin = 30;
#endif
switch (point) {
case 0:
LCD_MESSAGE(MSG_LEVBED_FL);
xpos = ypos = margin;
break;
case 1:
LCD_MESSAGE(MSG_LEVBED_FR);
xpos = X_BED_SIZE - margin; ypos = margin;
break;
case 2:
LCD_MESSAGE(MSG_LEVBED_BR);
xpos = X_BED_SIZE - margin; ypos = Y_BED_SIZE - margin;
break;
case 3:
LCD_MESSAGE(MSG_LEVBED_BL);
xpos = margin; ypos = Y_BED_SIZE - margin;
break;
case 4:
LCD_MESSAGE(MSG_LEVBED_C);
xpos = X_BED_SIZE / 2; ypos = Y_BED_SIZE / 2;
break;
}
planner.synchronize();
#if HAS_BED_PROBE
TramXY(point, margin, xpos, ypos);
if (HMI_data.FullManualTramming) {
planner.synchronize();
sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%sY%sF5000\nG0Z0F300"),
dtostrf(xpos, 1, 1, str_1),
dtostrf(ypos, 1, 1, str_2)
@@ -2341,6 +2464,20 @@ TERN(HAS_BED_PROBE, float, void) Tram(uint8_t point) {
queue.inject(cmd);
}
else {
// AUTO_BED_LEVELING_BILINEAR does not define MESH_INSET
#ifndef MESH_MIN_X
#define MESH_MIN_X (_MAX(X_MIN_BED + PROBING_MARGIN, X_MIN_POS))
#endif
#ifndef MESH_MIN_Y
#define MESH_MIN_Y (_MAX(Y_MIN_BED + PROBING_MARGIN, Y_MIN_POS))
#endif
#ifndef MESH_MAX_X
#define MESH_MAX_X (_MIN(X_MAX_BED - (PROBING_MARGIN), X_MAX_POS))
#endif
#ifndef MESH_MAX_Y
#define MESH_MAX_Y (_MIN(Y_MAX_BED - (PROBING_MARGIN), Y_MAX_POS))
#endif
LIMIT(xpos, MESH_MIN_X, MESH_MAX_X);
LIMIT(ypos, MESH_MIN_Y, MESH_MAX_Y);
probe.stow();
@@ -2360,14 +2497,20 @@ TERN(HAS_BED_PROBE, float, void) Tram(uint8_t point) {
inLev = false;
}
return zval;
}
#else // !HAS_BED_PROBE
#else
sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%iY%iF5000\nG0Z0F300"), xpos, ypos);
void Tram(const uint8_t point) {
float xpos = 0, ypos = 0, margin = 30;
TramXY(point, margin, xpos, ypos);
char cmd[100] = "", str_1[6] = "", str_2[6] = "";
sprintf_P(cmd, PSTR("M420S0\nG28O\nG90\nG0Z5F300\nG0X%sY%sF5000\nG0Z0F300"), dtostrf(xpos, 1, 1, str_1), dtostrf(ypos, 1, 1, str_2));
queue.inject(cmd);
}
#endif
}
#endif
void TramFL() { Tram(0); }
void TramFR() { Tram(1); }
@@ -3437,14 +3580,14 @@ void Draw_MaxSpeed_Menu() {
if (!MaxSpeedMenu) MaxSpeedMenu = new MenuClass();
if (CurrentMenu != MaxSpeedMenu) {
CurrentMenu = MaxSpeedMenu;
SetMenuTitle({1, 16, 28, 13}, GET_TEXT_F(MSG_MAXSPEED));
SetMenuTitle({1, 16, 28, 13}, GET_TEXT_F(MSG_MAX_SPEED));
MenuItemsPrepare(5);
BACK_ITEM(Draw_Motion_Menu);
EDIT_ITEM_F(ICON_MaxSpeedX, MSG_MAXSPEED_X, onDrawMaxSpeedX, SetMaxSpeedX, &planner.settings.max_feedrate_mm_s[X_AXIS]);
EDIT_ITEM_F(ICON_MaxSpeedY, MSG_MAXSPEED_Y, onDrawMaxSpeedY, SetMaxSpeedY, &planner.settings.max_feedrate_mm_s[Y_AXIS]);
EDIT_ITEM_F(ICON_MaxSpeedZ, MSG_MAXSPEED_Z, onDrawMaxSpeedZ, SetMaxSpeedZ, &planner.settings.max_feedrate_mm_s[Z_AXIS]);
EDIT_ITEM_F(ICON_MaxSpeedX, MSG_VMAX_A, onDrawMaxSpeedX, SetMaxSpeedX, &planner.settings.max_feedrate_mm_s[X_AXIS]);
EDIT_ITEM_F(ICON_MaxSpeedY, MSG_VMAX_B, onDrawMaxSpeedY, SetMaxSpeedY, &planner.settings.max_feedrate_mm_s[Y_AXIS]);
EDIT_ITEM_F(ICON_MaxSpeedZ, MSG_VMAX_C, onDrawMaxSpeedZ, SetMaxSpeedZ, &planner.settings.max_feedrate_mm_s[Z_AXIS]);
#if HAS_HOTEND
EDIT_ITEM_F(ICON_MaxSpeedE, MSG_MAXSPEED_E, onDrawMaxSpeedE, SetMaxSpeedE, &planner.settings.max_feedrate_mm_s[E_AXIS]);
EDIT_ITEM_F(ICON_MaxSpeedE, MSG_VMAX_E, onDrawMaxSpeedE, SetMaxSpeedE, &planner.settings.max_feedrate_mm_s[E_AXIS]);
#endif
}
CurrentMenu->draw();
@@ -3606,18 +3749,18 @@ void Draw_Steps_Menu() {
void SetBedLevT() { SetPIntOnClick(MIN_BEDTEMP, MAX_BEDTEMP); }
#endif
uint8_t mesh_x = 0;
uint8_t mesh_y = 0;
#define Z_OFFSET_MIN -3
#define Z_OFFSET_MAX 3
void LiveEditMesh() { ((MenuItemPtrClass*)EditZValueItem)->value = &bedlevel.z_values[HMI_value.Select ? mesh_x : MenuData.Value][HMI_value.Select ? MenuData.Value : mesh_y]; EditZValueItem->redraw(); }
void ApplyEditMeshX() { mesh_x = MenuData.Value; }
void SetEditMeshX() { HMI_value.Select = 0; SetIntOnClick(0, GRID_MAX_POINTS_X - 1, mesh_x, ApplyEditMeshX, LiveEditMesh); }
void ApplyEditMeshY() { mesh_y = MenuData.Value; }
void SetEditMeshY() { HMI_value.Select = 1; SetIntOnClick(0, GRID_MAX_POINTS_Y - 1, mesh_y, ApplyEditMeshY, LiveEditMesh); }
void SetEditZValue() { SetPFloatOnClick(Z_OFFSET_MIN, Z_OFFSET_MAX, 3); }
#if ENABLED(MESH_EDIT_MENU)
uint8_t mesh_x = 0, mesh_y = 0;
#define Z_OFFSET_MIN -3
#define Z_OFFSET_MAX 3
void LiveEditMesh() { ((MenuItemPtrClass*)EditZValueItem)->value = &bedlevel.z_values[HMI_value.Select ? mesh_x : MenuData.Value][HMI_value.Select ? MenuData.Value : mesh_y]; EditZValueItem->redraw(); }
void ApplyEditMeshX() { mesh_x = MenuData.Value; }
void SetEditMeshX() { HMI_value.Select = 0; SetIntOnClick(0, GRID_MAX_POINTS_X - 1, mesh_x, ApplyEditMeshX, LiveEditMesh); }
void ApplyEditMeshY() { mesh_y = MenuData.Value; }
void SetEditMeshY() { HMI_value.Select = 1; SetIntOnClick(0, GRID_MAX_POINTS_Y - 1, mesh_y, ApplyEditMeshY, LiveEditMesh); }
void SetEditZValue() { SetPFloatOnClick(Z_OFFSET_MIN, Z_OFFSET_MAX, 3); }
#endif
#endif
#if ENABLED(AUTO_BED_LEVELING_UBL)
+1 -3
View File
@@ -238,9 +238,7 @@ void Draw_Tramming_Menu();
#if HAS_BED_PROBE
void Draw_ProbeSet_Menu();
#endif
#if HAS_FILAMENT_SENSOR
void Draw_FilSet_Menu();
#endif
void Draw_FilSet_Menu();
#if ENABLED(NOZZLE_PARK_FEATURE)
void Draw_ParkPos_Menu();
#endif
+2 -31
View File
@@ -35,41 +35,12 @@
#include <stddef.h>
#define HAS_ESDIAG 1
#define HAS_PIDPLOT 1
#define HAS_GCODE_PREVIEW 1
#if defined(__STM32F1__) || defined(STM32F1)
#define DASH_REDRAW 1
#endif
#if DISABLED(LIMITED_MAX_FR_EDITING)
#error "LIMITED_MAX_FR_EDITING is required with ProUI."
#endif
#if DISABLED(LIMITED_MAX_ACCEL_EDITING)
#error "LIMITED_MAX_ACCEL_EDITING is required with ProUI."
#endif
#if ENABLED(CLASSIC_JERK) && DISABLED(LIMITED_JERK_EDITING)
#error "LIMITED_JERK_EDITING is required with ProUI."
#endif
#if DISABLED(FILAMENT_RUNOUT_SENSOR)
#error "FILAMENT_RUNOUT_SENSOR is required with ProUI."
#endif
#if DISABLED(INDIVIDUAL_AXIS_HOMING_SUBMENU)
#error "INDIVIDUAL_AXIS_HOMING_SUBMENU is required with ProUI."
#endif
#if DISABLED(LCD_SET_PROGRESS_MANUALLY)
#error "LCD_SET_PROGRESS_MANUALLY is required with ProUI."
#endif
#if DISABLED(STATUS_MESSAGE_SCROLLING)
#error "STATUS_MESSAGE_SCROLLING is required with ProUI."
#endif
#if DISABLED(BAUD_RATE_GCODE)
#error "BAUD_RATE_GCODE is required with ProUI."
#endif
#if DISABLED(SOUND_MENU_ITEM)
#error "SOUND_MENU_ITEM is required with ProUI."
#endif
#if DISABLED(PRINTCOUNTER)
#error "PRINTCOUNTER is required with ProUI."
#endif
#include "../common/dwin_color.h"
#if ENABLED(LED_CONTROL_MENU)
#include "../../../feature/leds/leds.h"
+1 -1
View File
@@ -147,7 +147,7 @@ void DWIN_SRAMToPic(uint8_t picID) {
//--------------------------Test area -------------------------
//void DWIN_ReadSRAM(uint16_t addr, uint8_t length, const char * const data) {
//void DWIN_ReadSRAM(uint16_t addr, const uint8_t length, const char * const data) {
// size_t i = 0;
// DWIN_Byte(i, 0x32);
// DWIN_Byte(i, 0x5A); // 0x5A Read from SRAM - 0xA5 Read from Flash
+253
View File
@@ -0,0 +1,253 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* DWIN g-code thumbnail preview
* Author: Miguel A. Risco-Castillo
* version: 2.1
* Date: 2021/06/19
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* For commercial applications additional licenses can be requested
*/
#include "dwin_defines.h"
#if HAS_GCODE_PREVIEW
#include "../../../core/types.h"
#include "../../marlinui.h"
#include "../../../sd/cardreader.h"
#include "dwin_lcd.h"
#include "dwinui.h"
#include "dwin.h"
#include "dwin_popup.h"
#include "base64.hpp"
#include "gcode_preview.h"
typedef struct {
char name[13] = ""; //8.3 + null
uint32_t thumbstart = 0;
int thumbsize = 0;
int thumbheight = 0;
int thumbwidth = 0;
uint8_t *thumbdata = nullptr;
float time = 0;
float filament = 0;
float layer = 0;
float width = 0;
float height = 0;
float length = 0;
void setname(const char * const fn);
void clear();
} fileprop_t;
fileprop_t fileprop;
void fileprop_t::setname(const char * const fn) {
const uint8_t len = _MIN(sizeof(name) - 1, strlen(fn));
memcpy(&name[0], fn, len);
name[len] = '\0';
}
void fileprop_t::clear() {
fileprop.name[0] = '\0';
fileprop.thumbstart = 0;
fileprop.thumbsize = 0;
fileprop.thumbheight = 0;
fileprop.thumbwidth = 0;
fileprop.thumbdata = nullptr;
fileprop.time = 0;
fileprop.filament = 0;
fileprop.layer = 0;
fileprop.height = 0;
fileprop.width = 0;
fileprop.length = 0;
}
void Get_Value(char *buf, const char * const key, float &value) {
char num[10] = "";
char * posptr = 0;
uint8_t i = 0;
if (!!value) return;
posptr = strstr(buf, key);
if (posptr != nullptr) {
while (i < sizeof(num)) {
char c = posptr[0];
if (!ISEOL(c) && (c != 0)) {
if ((c > 47 && c < 58) || (c == '.')) num[i++] = c;
posptr++;
}
else {
num[i] = '\0';
value = atof(num);
return;
}
}
}
}
bool Has_Preview() {
const char * tbstart = "; thumbnail begin 230x180";
char * posptr = 0;
uint8_t nbyte = 1;
uint32_t indx = 0;
char buf[256];
float tmp = 0;
fileprop.clear();
fileprop.setname(card.filename);
card.openFileRead(fileprop.name);
while ((nbyte > 0) && (indx < 4 * sizeof(buf)) && !fileprop.thumbstart) {
nbyte = card.read(buf, sizeof(buf) - 1);
if (nbyte > 0) {
buf[nbyte] = '\0';
Get_Value(buf, ";TIME:", fileprop.time);
Get_Value(buf, ";Filament used:", fileprop.filament);
Get_Value(buf, ";Layer height:", fileprop.layer);
Get_Value(buf, ";MINX:", tmp);
Get_Value(buf, ";MAXX:", fileprop.width);
fileprop.width -= tmp;
tmp = 0;
Get_Value(buf, ";MINY:", tmp);
Get_Value(buf, ";MAXY:", fileprop.length);
fileprop.length -= tmp;
tmp = 0;
Get_Value(buf, ";MINZ:", tmp);
Get_Value(buf, ";MAXZ:", fileprop.height);
fileprop.height -= tmp;
posptr = strstr(buf, tbstart);
if (posptr != NULL) {
fileprop.thumbstart = indx + (posptr - &buf[0]);
}
else {
indx += _MAX(10, nbyte - (signed)strlen(tbstart));
card.setIndex(indx);
}
}
}
if (!fileprop.thumbstart) {
card.closefile();
LCD_MESSAGE_F("Thumbnail not found");
return 0;
}
// Get the size of the thumbnail
card.setIndex(fileprop.thumbstart + strlen(tbstart));
for (uint8_t i = 0; i < 16; i++) {
char c = card.get();
if (!ISEOL(c)) {
buf[i] = c;
}
else {
buf[i] = 0;
break;
}
}
fileprop.thumbsize = atoi(buf);
// Exit if there isn't a thumbnail
if (!fileprop.thumbsize) {
card.closefile();
LCD_MESSAGE_F("Invalid Thumbnail Size");
return 0;
}
uint16_t readed = 0;
uint8_t buf64[fileprop.thumbsize];
fileprop.thumbdata = new uint8_t[3 + 3 * (fileprop.thumbsize / 4)]; // Reserve space for the JPEG thumbnail
while (readed < fileprop.thumbsize) {
uint8_t c = card.get();
if (!ISEOL(c) && (c != ';') && (c != ' ')) {
buf64[readed] = c;
readed++;
}
}
card.closefile();
buf64[readed] = 0;
fileprop.thumbsize = decode_base64(buf64, fileprop.thumbdata); card.closefile();
DWINUI::WriteToSRAM(0x00, fileprop.thumbsize, fileprop.thumbdata);
delete[] fileprop.thumbdata;
return true;
}
void Preview_DrawFromSD() {
if (Has_Preview()) {
char buf[46];
char str_1[6] = "";
char str_2[6] = "";
char str_3[6] = "";
DWIN_Draw_Rectangle(1, HMI_data.Background_Color, 0, 0, DWIN_WIDTH, STATUS_Y - 1);
if (fileprop.time) {
sprintf_P(buf, PSTR("Estimated time: %i:%02i"), (uint16_t)fileprop.time / 3600, ((uint16_t)fileprop.time % 3600) / 60);
DWINUI::Draw_String(20, 10, buf);
}
if (fileprop.filament) {
sprintf_P(buf, PSTR("Filament used: %s m"), dtostrf(fileprop.filament, 1, 2, str_1));
DWINUI::Draw_String(20, 30, buf);
}
if (fileprop.layer) {
sprintf_P(buf, PSTR("Layer height: %s mm"), dtostrf(fileprop.layer, 1, 2, str_1));
DWINUI::Draw_String(20, 50, buf);
}
if (fileprop.width) {
sprintf_P(buf, PSTR("Volume: %sx%sx%s mm"), dtostrf(fileprop.width, 1, 1, str_1), dtostrf(fileprop.length, 1, 1, str_2), dtostrf(fileprop.height, 1, 1, str_3));
DWINUI::Draw_String(20, 70, buf);
}
DWINUI::Draw_Button(BTN_Print, 26, 290);
DWINUI::Draw_Button(BTN_Cancel, 146, 290);
DWIN_ICON_Show(0, 0, 1, 21, 90, 0x00);
Draw_Select_Highlight(true, 290);
DWIN_UpdateLCD();
}
else {
HMI_flag.select_flag = 1;
wait_for_user = false;
}
}
bool Preview_Valid() {
return !!fileprop.thumbstart;
}
void Preview_Reset() {
fileprop.thumbsize = 0;
}
#endif // HAS_GCODE_PREVIEW
+27
View File
@@ -0,0 +1,27 @@
/**
* DWIN g-code thumbnail preview
* Author: Miguel A. Risco-Castillo
* version: 2.1
* Date: 2021/06/19
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* For commercial applications additional licenses can be requested
*/
#pragma once
void Preview_DrawFromSD();
bool Preview_Valid();
void Preview_Reset();
+94
View File
@@ -0,0 +1,94 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* DWIN Single var plot
* Author: Miguel A. Risco-Castillo
* Version: 2.0
* Date: 2022/01/31
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* For commercial applications additional licenses can be requested
*/
#include "../../../inc/MarlinConfigPre.h"
#ifdef DWIN_LCD_PROUI
#include "plot.h"
#include "../../../core/types.h"
#include "../../marlinui.h"
#include "dwin_lcd.h"
#include "dwinui.h"
#include "dwin_popup.h"
#include "dwin.h"
#define Plot_Bg_Color RGB( 1, 12, 8)
PlotClass Plot;
uint16_t grphpoints, r, x2, y2 = 0;
frame_rect_t grphframe = {0};
float scale = 0;
void PlotClass::Draw(const frame_rect_t frame, const float max, const float ref) {
grphframe = frame;
grphpoints = 0;
scale = frame.h / max;
x2 = frame.x + frame.w - 1;
y2 = frame.y + frame.h - 1;
r = round((y2) - ref * scale);
DWINUI::Draw_Box(1, Plot_Bg_Color, frame);
for (uint8_t i = 1; i < 4; i++) if (i*50 < frame.w) DWIN_Draw_VLine(Line_Color, i*50 + frame.x, frame.y, frame.h);
DWINUI::Draw_Box(0, Color_White, DWINUI::ExtendFrame(frame, 1));
DWIN_Draw_HLine(Color_Red, frame.x, r, frame.w);
}
void PlotClass::Update(const float value) {
if (!scale) return;
uint16_t y = round((y2) - value * scale);
if (grphpoints < grphframe.w) {
DWIN_Draw_Point(Color_Yellow, 1, 1, grphpoints + grphframe.x, y);
}
else {
DWIN_Frame_AreaMove(1, 0, 1, Plot_Bg_Color, grphframe.x, grphframe.y, x2, y2);
if ((grphpoints % 50) == 0) DWIN_Draw_VLine(Line_Color, x2 - 1, grphframe.y + 1, grphframe.h - 2);
DWIN_Draw_Point(Color_Red, 1, 1, x2 - 1, r);
DWIN_Draw_Point(Color_Yellow, 1, 1, x2 - 1, y);
}
grphpoints++;
}
#endif // DWIN_LCD_PROUI
+54
View File
@@ -0,0 +1,54 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
/**
* DWIN Single var plot
* Author: Miguel A. Risco-Castillo
* Version: 1.0
* Date: 2022/01/30
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser 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 Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
* For commercial applications additional licenses can be requested
*/
#pragma once
#include "dwinui.h"
class PlotClass {
public:
void Draw(frame_rect_t frame, float max, float ref = 0);
void Update(float value);
};
extern PlotClass Plot;
+17 -9
View File
@@ -1,10 +1,9 @@
/**
* UBL Tools and Mesh Viewer for Pro UI
* Version: 1.0.0
* Date: 2022/04/13
* Marlin 3D Printer Firmware
* Copyright (c) 2022 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Original Author: Henri-J-Norden
* Original Source: https://github.com/Jyers/Marlin/pull/126
* 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
@@ -21,11 +20,20 @@
*
*/
/**
* UBL Tools and Mesh Viewer for Pro UI
* Version: 1.0.0
* Date: 2022/04/13
*
* Original Author: Henri-J-Norden
* Original Source: https://github.com/Jyers/Marlin/pull/126
*/
#include "../../../inc/MarlinConfigPre.h"
#if BOTH(DWIN_LCD_PROUI, AUTO_BED_LEVELING_UBL)
#include "ubl_tools.h"
#if ENABLED(DWIN_LCD_PROUI)
#include "../../marlinui.h"
#include "../../../core/types.h"
#include "dwin.h"
@@ -249,4 +257,4 @@ bool UBLMeshToolsClass::validate() {
}
#endif
#endif // DWIN_LCD_PROUI
#endif // DWIN_LCD_PROUI && AUTO_BED_LEVELING_UBL
@@ -708,7 +708,7 @@ void ChironTFT::PanelAction(uint8_t req) {
// Old TFT A22 X -1F1500 A22 X +1F1500
// New TFT A22 X-1.0 F1500 A22 X1.0 F1500
// lets just wrap this in a gcode relative nonprint move and let the controller deal with it
// Send a G-code-relative non-print move and let the controller deal with it
// G91 G0 <panel command> G90
if (!isPrinting()) { // Ignore request if printing
@@ -86,7 +86,7 @@ void AnycubicTFTClass::OnSetup() {
delay_ms(10);
// Init the state of the key pins running on the TFT
#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
#if BOTH(SDSUPPORT, HAS_SD_DETECT)
SET_INPUT_PULLUP(SD_DETECT_PIN);
#endif
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
@@ -916,7 +916,7 @@ void AnycubicTFTClass::GetCommandFromTFT() {
}
void AnycubicTFTClass::DoSDCardStateCheck() {
#if ENABLED(SDSUPPORT) && PIN_EXISTS(SD_DETECT)
#if BOTH(SDSUPPORT, HAS_SD_DETECT)
bool isInserted = isMediaInserted();
if (isInserted)
SENDLINE_DBG_PGM("J00", "TFT Serial Debug: SD card state changed... isInserted");
+1 -1
View File
@@ -243,7 +243,7 @@ void DGUSDisplay::WritePGM(const char str[], uint8_t len) {
}
void DGUSDisplay::loop() {
// protect against recursion ProcessRx() may indirectly call idle() when injecting gcode commands.
// Protect against recursion. ProcessRx() may indirectly call idle() when injecting G-code commands.
if (!no_reentrance) {
no_reentrance = true;
ProcessRx();
@@ -193,7 +193,6 @@ void DGUSScreenHandlerMKS::DGUSLCD_SendTMCStepValue(DGUS_VP_Variable &var) {
if (!ExtUI::isPrintingFromMedia()) return; // avoid race condition when user stays in this menu and printer finishes.
switch (swap16(*(uint16_t*)val_ptr)) {
case 0: { // Resume
auto cs = getCurrentScreen();
if (runout_mks.runout_status != RUNOUT_WAITING_STATUS && runout_mks.runout_status != UNRUNOUT_STATUS) {
if (cs == MKSLCD_SCREEN_PRINT || cs == MKSLCD_SCREEN_PAUSE)
@@ -213,7 +212,6 @@ void DGUSScreenHandlerMKS::DGUSLCD_SendTMCStepValue(DGUS_VP_Variable &var) {
} break;
case 1: // Pause
GotoScreen(MKSLCD_SCREEN_PAUSE);
if (!ExtUI::isPrintingFromMediaPaused()) {
nozzle_park_mks.print_pause_start_flag = 1;
@@ -222,6 +220,7 @@ void DGUSScreenHandlerMKS::DGUSLCD_SendTMCStepValue(DGUS_VP_Variable &var) {
//ExtUI::mks_pausePrint();
}
break;
case 2: // Abort
HandleUserConfirmationPopUp(VP_SD_AbortPrintConfirmed, nullptr, PSTR("Abort printing"), filelist.filename(), PSTR("?"), true, true, false, true);
break;

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