Compare commits

..

48 Commits

Author SHA1 Message Date
InsanityAutomation 1bbae4676f Speed tweaks 2024-06-03 08:19:46 -04:00
InsanityAutomation 6802260626 Merge branch 'LPC4078_DevUpd' of https://github.com/InsanityAutomation/Marlin into LPC4078_DevUpd 2024-05-29 12:21:31 -04:00
InsanityAutomation ed34dbb4b6 Update Configuration_adv.h 2024-05-29 12:21:14 -04:00
InsanityAutomation 721209a898 uint64_t planner test 2024-05-29 12:21:04 -04:00
InsanityAutomation 7c6dfc4ec2 Update planner.cpp 2024-05-28 14:10:47 -04:00
Mihail Dumitrescu 62008024cd Protect pulse generation timing by disabling interrupts for longer. 2024-05-28 14:10:46 -04:00
Mihail Dumitrescu e09672edac Fully guard multistepping code in Stepper::pulse_phase_isr(). 2024-05-28 14:10:46 -04:00
Mihail Dumitrescu 825e0b800c Add 4th order S_CURVE_ACCELERATION with configurable S_CURVE_FACTOR. 2024-05-28 14:10:46 -04:00
Mihail Dumitrescu 0f489c6584 PR27035
Smoother motion by fixing calculating trapezoids and ISR stepping.

Fix rounding directions in calculate_trapezoid_for_block().
Fix off-by-ones errors in ac/deceleration steps in block_phase_isr.
Half-initialize ac/deceleration_time to smooth the speed change shock that happens between segments, which is critical as jerk/deviation adds to this.

The result is a smoother motion profile that follows the imposed acceleration limits with a well defined 0.5-1.5x error factor (or 2x if axis is starting from ~0). Errors are due to converting a real-valued motion profile into discrete numbers of steps.
Fixes are general and improve S_CURVE_ACCELERATION too (no endorsement implied).

Tested by looking at the generated step/dir impulses with a logic analyzer.

Enjoy the smoother motion or use more aggresive acceleration/jerk/deviation values for faster prints.

Also improves: #12491

Remove nominal_length, remove MINIMAL_STEP_RATE, add min_entry_speed_sqr, initial clean up of reverse_pass_kernel and forward_pass_kernel.

Removing MINIMAL_STEP_RATE allows for correct handling of moves with low acceleration, including fixing judder that's caused when the planner computes an entry speed based on minimum_planner_speed_sqr that's then promptly overriden by MINIMAL_STEP_RATE.

Added min_entry_speed_sqr to avoid a specific potential source of judder due to working with discrete steps rather continuous real-valued physics. The first step of any segment runs at initial_rate. If it is too low compared to acceleration_steps_per_s2 it will result in too much accumulated acceleration_time (see stepper.cpp) which will mean the following step will be at a much higher speed, and the speed change will significantly surpass the set acceleration_steps_per_s2 limit. Making sure we can match this limit is why we have minimum_planner_speed_sqr in the first place.

Optimal number of sqrts and trapezoid calculations.

Remove forward_pass(). Call forward_pass_kernel() from recalculate() instead.
Fix potential for large speed changes if planner falls behind.

group for clarity and review

as described

combined float sq

match modified names

Optimal number of sqrts and trapezoid calculations.

Remove forward_pass(). Call forward_pass_kernel() from recalculate() instead.
Fix potential for large speed changes if planner falls behind.

Save and use block->steps_per_mm to avoid many divisions.
2024-05-28 14:10:46 -04:00
John Robertson 6ae43349f7 PR26881
Fix planner wrong trap generation

If the planner `entry_rate` or `final_rate` are larger thanthe  `block->nominal_rate` then the trapezoid entry ramp continuously accelerates. Only happens if feed rate is less than MAXIMAL_STEP_RATE.

Update planner.cpp

removed

Update planner.h

Moved MINIMAL_STEP_RATE to this file.

Update planner.h

Added calc for MINIMAL_STEP_RATE

Update planner.h

fix minimal_step_rate calc

Update planner.h

Remove MINIMAL_STEP_RATE

Revert "Update planner.cpp"

This reverts commit 5e0158a8ee1340e5b0e6a7313eb5f5f7058bfa15.

Revert "Update planner.h"

This reverts commit 3da5d0c00102620dc7eddf46a30044773770a667.

Update planner.cpp

Update planner.h

Update planner.cpp

ws

Apply to min_step_rate
2024-05-28 14:10:45 -04:00
Mihail Dumitrescu f6b52a80d6 PR26555
Fix menu responsiveness when HAS_MARLINUI_U8GLIB.

Co-Authored-By: Jason Smith <jason.inet@gmail.com>
2024-05-28 14:10:45 -04:00
InsanityAutomation 38711ed5e6 Update lpc176x.ini 2024-05-28 14:10:45 -04:00
InsanityAutomation 5a714c76b8 Update Configuration.h 2024-05-28 14:10:45 -04:00
InsanityAutomation 8c1a547f2a Config Tweak 2024-05-28 14:10:45 -04:00
InsanityAutomation 16be10d2f3 SPI updates from @p3p upstream 2024-05-28 14:10:44 -04:00
InsanityAutomation d4dde255ad Debug 2024-05-28 14:10:44 -04:00
InsanityAutomation b5c7712531 Update Configuration.h 2024-05-28 14:10:44 -04:00
InsanityAutomation 8dc8361f02 tmc5160 and spi 2024-05-28 14:10:44 -04:00
InsanityAutomation 433f3ba3ab Change read function for PS_ON and EDM pins 2024-05-28 14:10:37 -04:00
InsanityAutomation 78e2aa6eac Fix interupts and pin debugging 2024-05-28 14:10:29 -04:00
InsanityAutomation 54da1da13f Tweaks 2024-05-28 14:10:29 -04:00
InsanityAutomation 544765f1a1 Update Configuration.h 2024-05-28 14:10:25 -04:00
InsanityAutomation f261fea59a Redundant Power control with EDM - First Pass 2024-05-28 14:10:24 -04:00
InsanityAutomation 00785eb14e Update Configuration_adv.h
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-05-28 14:10:04 -04:00
InsanityAutomation 6713185aea LPC4078 Initial Commit
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-05-28 14:09:51 -04:00
InsanityAutomation 298c3f2344 Update planner.cpp 2024-05-28 11:15:33 -04:00
Mihail Dumitrescu 82c1171028 Protect pulse generation timing by disabling interrupts for longer. 2024-05-28 10:46:49 -04:00
Mihail Dumitrescu 122b01d253 Fully guard multistepping code in Stepper::pulse_phase_isr(). 2024-05-28 10:46:13 -04:00
Mihail Dumitrescu 42e4321b6f Add 4th order S_CURVE_ACCELERATION with configurable S_CURVE_FACTOR. 2024-05-28 10:45:45 -04:00
Mihail Dumitrescu 87faa73bee PR27035
Smoother motion by fixing calculating trapezoids and ISR stepping.

Fix rounding directions in calculate_trapezoid_for_block().
Fix off-by-ones errors in ac/deceleration steps in block_phase_isr.
Half-initialize ac/deceleration_time to smooth the speed change shock that happens between segments, which is critical as jerk/deviation adds to this.

The result is a smoother motion profile that follows the imposed acceleration limits with a well defined 0.5-1.5x error factor (or 2x if axis is starting from ~0). Errors are due to converting a real-valued motion profile into discrete numbers of steps.
Fixes are general and improve S_CURVE_ACCELERATION too (no endorsement implied).

Tested by looking at the generated step/dir impulses with a logic analyzer.

Enjoy the smoother motion or use more aggresive acceleration/jerk/deviation values for faster prints.

Also improves: #12491

Remove nominal_length, remove MINIMAL_STEP_RATE, add min_entry_speed_sqr, initial clean up of reverse_pass_kernel and forward_pass_kernel.

Removing MINIMAL_STEP_RATE allows for correct handling of moves with low acceleration, including fixing judder that's caused when the planner computes an entry speed based on minimum_planner_speed_sqr that's then promptly overriden by MINIMAL_STEP_RATE.

Added min_entry_speed_sqr to avoid a specific potential source of judder due to working with discrete steps rather continuous real-valued physics. The first step of any segment runs at initial_rate. If it is too low compared to acceleration_steps_per_s2 it will result in too much accumulated acceleration_time (see stepper.cpp) which will mean the following step will be at a much higher speed, and the speed change will significantly surpass the set acceleration_steps_per_s2 limit. Making sure we can match this limit is why we have minimum_planner_speed_sqr in the first place.

Optimal number of sqrts and trapezoid calculations.

Remove forward_pass(). Call forward_pass_kernel() from recalculate() instead.
Fix potential for large speed changes if planner falls behind.

group for clarity and review

as described

combined float sq

match modified names

Optimal number of sqrts and trapezoid calculations.

Remove forward_pass(). Call forward_pass_kernel() from recalculate() instead.
Fix potential for large speed changes if planner falls behind.

Save and use block->steps_per_mm to avoid many divisions.
2024-05-28 10:43:59 -04:00
John Robertson 666e8c0116 PR26881
Fix planner wrong trap generation

If the planner `entry_rate` or `final_rate` are larger thanthe  `block->nominal_rate` then the trapezoid entry ramp continuously accelerates. Only happens if feed rate is less than MAXIMAL_STEP_RATE.

Update planner.cpp

removed

Update planner.h

Moved MINIMAL_STEP_RATE to this file.

Update planner.h

Added calc for MINIMAL_STEP_RATE

Update planner.h

fix minimal_step_rate calc

Update planner.h

Remove MINIMAL_STEP_RATE

Revert "Update planner.cpp"

This reverts commit 5e0158a8ee1340e5b0e6a7313eb5f5f7058bfa15.

Revert "Update planner.h"

This reverts commit 3da5d0c00102620dc7eddf46a30044773770a667.

Update planner.cpp

Update planner.h

Update planner.cpp

ws

Apply to min_step_rate
2024-05-28 10:29:03 -04:00
Mihail Dumitrescu 5a0332ddee PR26555
Fix menu responsiveness when HAS_MARLINUI_U8GLIB.

Co-Authored-By: Jason Smith <jason.inet@gmail.com>
2024-05-28 10:29:02 -04:00
InsanityAutomation f67a0f847f Update lpc176x.ini 2024-05-28 09:39:16 -04:00
InsanityAutomation 0f1a5a7434 Update Configuration.h 2024-05-28 09:32:10 -04:00
InsanityAutomation 01df7e11dc Config Tweak 2024-05-26 15:04:33 -04:00
InsanityAutomation 9200e8c284 SPI updates from @p3p upstream 2024-05-26 14:59:09 -04:00
InsanityAutomation 0dcfc91c9e Debug 2024-05-25 19:53:01 -04:00
InsanityAutomation acf53d6f84 Merge branch 'bugfix-2.1.x' into LPC4078_DevUpd 2024-05-25 18:34:14 -04:00
InsanityAutomation da068d5bb1 Update Configuration.h 2024-03-06 10:53:44 -05:00
InsanityAutomation 7f339f7001 tmc5160 and spi 2024-03-06 10:53:00 -05:00
ellensp 7150d0eb5c 🔨 No strlcpy in Windows (#26748) 2024-02-27 10:35:13 -05:00
InsanityAutomation ca18690349 Change read function for PS_ON and EDM pins 2024-01-30 11:52:57 -05:00
InsanityAutomation 0316242347 Fix interupts and pin debugging 2024-01-18 22:36:36 -05:00
InsanityAutomation 6087ab6347 Tweaks 2024-01-14 15:41:52 -05:00
InsanityAutomation a44871b272 Update Configuration.h 2024-01-14 15:38:54 -05:00
InsanityAutomation bef646d52c Redundant Power control with EDM - First Pass 2024-01-14 15:36:28 -05:00
InsanityAutomation 4d78a91cbd Update Configuration_adv.h
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-01-14 15:36:03 -05:00
InsanityAutomation 95bafca9d9 LPC4078 Initial Commit
Co-Authored-By: Chris Pepper <24342+p3p@users.noreply.github.com>
2024-01-14 15:35:57 -05:00
1241 changed files with 72947 additions and 54055 deletions
-21
View File
@@ -1,21 +0,0 @@
# Build artifacts
buildroot/
*.o
*.a
*.so
*.dylib
*.dll
*.exe
# Web assets
*.min.js
*.min.css
# Generated files
__pycache__/
*.pyc
.DS_Store
# IDE files
.vscode/
.idea/
+1 -1
View File
@@ -7,7 +7,7 @@ contact_links:
url: https://www.facebook.com/groups/1049718498464482
about: Please ask and answer questions here.
- name: 🕹 Marlin on Discord
url: https://discord.com/servers/marlin-firmware-461605380783472640
url: https://discord.gg/n5NJ59y
about: Join the Discord server for support and discussion.
- name: 🔗 Marlin Discussion Forum
url: https://reprap.org/forum/list.php?415
+1 -1
View File
@@ -43,7 +43,7 @@ We have a Message Board and a Facebook group where our knowledgable user communi
If chat is more your speed, you can join the MarlinFirmware Discord server:
* Use the link https://discord.com/servers/marlin-firmware-461605380783472640 to join up as a General User.
* Use the link https://discord.gg/n5NJ59y to join up as a General User.
* Even though our Discord is pretty active, it may take a while for community members to respond &mdash; please be patient!
* Use the `#general` channel for general questions or discussion about Marlin.
* Other channels exist for certain topics or are limited to Patrons. Check the channel list.
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
autolabel:
name: Auto Label
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- name: Auto Label for [BUG]
uses: actions/github-script@v7
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
name: Bump Distribution Date
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
name: PR Bad Target
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: superbrothers/close-pull-request@v3
+5 -18
View File
@@ -34,19 +34,14 @@ jobs:
name: Build Test
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
test-platform:
# RP2040
- SKR_Pico
# Native
- linux_native
- simulator_linux_release
# AVR
- mega2560
@@ -109,11 +104,11 @@ jobs:
# STM32F4
- ARMED
- BTT_BTT002
- BTT_GTR_V1_0
- BTT_SKR_PRO
- BIGTREE_BTT002
- BIGTREE_GTR_V1_0
- BIGTREE_SKR_PRO
- FLYF407ZG
- STM32F446VE_fysetc
- FYSETC_S6
- LERDGEK
- LERDGEX
- mks_robin_pro2
@@ -186,14 +181,6 @@ jobs:
pio upgrade --dev
pio pkg update --global
- name: Install Simulator dependencies
run: |
sudo apt-get update
sudo apt-get install build-essential
sudo apt-get install libsdl2-dev
sudo apt-get install libsdl2-net-dev
sudo apt-get install libglm-dev
- name: Run ${{ matrix.test-platform }} Tests
run: |
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
+1 -1
View File
@@ -36,7 +36,7 @@ jobs:
# pulls them into additional branches.
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- name: Check out the PR
-48
View File
@@ -1,48 +0,0 @@
#
# ci-validate-boards.yml
# Validate boards.h to make sure it's all set up correctly
#
name: CI - Validate boards.h
# We can do the on: section as two items, one for pull requests and one for pushes...
on:
pull_request:
branches:
- bugfix-2.1.x
paths:
- 'Marlin/src/core/boards.h'
push:
branches:
- bugfix-2.1.x
paths:
- 'Marlin/src/core/boards.h'
jobs:
validate_pins_files:
name: Validate boards.h
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
steps:
- name: Check out the PR
uses: actions/checkout@v4
- name: Cache pip
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Select Python 3.9
uses: actions/setup-python@v5
with:
python-version: '3.9'
architecture: 'x64'
- name: Validate core/boards.h
run: |
make validate-boards -j
+1 -1
View File
@@ -26,7 +26,7 @@ jobs:
name: Validate Pins Files
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- name: Check out the PR
+1 -1
View File
@@ -13,7 +13,7 @@ on:
jobs:
remove_label:
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
matrix:
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
name: Close Stale Issues
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v9
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
name: Lock Closed Issues
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v5
+1 -1
View File
@@ -14,7 +14,7 @@ jobs:
name: Unlock Reopened
if: github.repository == 'MarlinFirmware/Marlin'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
steps:
- uses: OSDKDev/unlock-issues@v1.1
-4
View File
@@ -125,7 +125,6 @@ vc-fileutils.settings
# Visual Studio Code
.vscode/*
!.vscode/extensions.json
*.code-workspace
# Simulation files
imgui.ini
@@ -169,6 +168,3 @@ __pycache__
tags
*.logs
*.bak
.aider*
!.aiderignore
.env
-16
View File
@@ -1,16 +0,0 @@
/**
* Marlin-specific settings for Zed
*
* For a full list of overridable settings, and general information on folder-specific settings,
* see the documentation: https://zed.dev/docs/configuring-zed#settings-files
*/
{
"languages": {
"C": {
"enable_language_server": false
},
"C++": {
"enable_language_server": false
}
}
}
+1 -10
View File
@@ -6,10 +6,9 @@ UNIT_TEST_CONFIG ?= default
help:
@echo "Tasks for local development:"
@echo "make marlin : Build Marlin for the configured board"
@echo "make marlin : Build marlin for the configured board"
@echo "make format-pins -j : Reformat all pins files (-j for parallel execution)"
@echo "make validate-pins -j : Validate all pins files, fails if any require reformatting"
@echo "make validate-boards -j : Validate boards.h and pins.h for standards compliance"
@echo "make tests-single-ci : Run a single test from inside the CI"
@echo "make tests-single-local : Run a single test locally"
@echo "make tests-single-local-docker : Run a single test locally, using docker"
@@ -103,11 +102,3 @@ format-pins: $(PINS)
validate-pins: format-pins
@echo "Validating pins files"
@git diff --exit-code || (git status && echo "\nError: Pins files are not formatted correctly. Run \"make format-pins\" to fix.\n" && exit 1)
BOARDS_FILE := Marlin/src/core/boards.h
.PHONY: validate-boards
validate-boards:
@echo "Validating boards.h file"
@python $(SCRIPTS_DIR)/validate_boards.py $(BOARDS_FILE) || (echo "\nError: boards.h file is not valid. Please check and correct it.\n" && exit 1)
+203 -285
View File
File diff suppressed because it is too large Load Diff
+257 -402
View File
File diff suppressed because it is too large Load Diff
+74 -105
View File
@@ -187,17 +187,6 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1033)
# RAMPS Plus 3DYMY (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1034)
# RAMPS 1.6+ (Power outputs: Hotend, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1035)
# RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1036)
# RAMPS 1.6+ (Power outputs: Hotend, Fan0, Fan1)
else ifeq ($(HARDWARE_MOTHERBOARD),1037)
# RAMPS 1.6+ (Power outputs: Hotend0, Hotend1, Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1038)
# RAMPS 1.6+ (Power outputs: Spindle, Controller Fan)
else ifeq ($(HARDWARE_MOTHERBOARD),1039)
#
# RAMPS Derivatives - ATmega1280, ATmega2560
#
@@ -232,113 +221,108 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1112)
else ifeq ($(HARDWARE_MOTHERBOARD),1113)
# BigTreeTech or BIQU KFB2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1114)
# Zonestar zrib V2.0 (Chinese RAMPS replica)
# zrib V2.0 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1115)
# Zonestar zrib V5.2 (Chinese RAMPS replica)
# zrib V5.2 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1116)
# Zonestar zrib V5.3 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
# Felix 2.0+ Electronics Board (RAMPS like)
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
else ifeq ($(HARDWARE_MOTHERBOARD),1117)
# Invent-A-Part RigidBoard
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
else ifeq ($(HARDWARE_MOTHERBOARD),1118)
# Invent-A-Part RigidBoard V2
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
else ifeq ($(HARDWARE_MOTHERBOARD),1119)
# Sainsmart 2-in-1 board
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
else ifeq ($(HARDWARE_MOTHERBOARD),1120)
# Ultimaker
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
else ifeq ($(HARDWARE_MOTHERBOARD),1121)
# Ultimaker (Older electronics. Pre 1.5.4. This is rare)
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
else ifeq ($(HARDWARE_MOTHERBOARD),1122)
MCU ?= atmega1280
PROG_MCU ?= m1280
# Azteeg X3
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
else ifeq ($(HARDWARE_MOTHERBOARD),1123)
# Azteeg X3 Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
else ifeq ($(HARDWARE_MOTHERBOARD),1124)
# Ultimainboard 2.x (Uses TEMP_SENSOR 20)
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
else ifeq ($(HARDWARE_MOTHERBOARD),1125)
# Rumba
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
else ifeq ($(HARDWARE_MOTHERBOARD),1126)
# Raise3D N series Rumba derivative
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
else ifeq ($(HARDWARE_MOTHERBOARD),1127)
# Rapide Lite 200 (v1, low-cost RUMBA clone with drv)
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
else ifeq ($(HARDWARE_MOTHERBOARD),1128)
# Formbot T-Rex 2 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
else ifeq ($(HARDWARE_MOTHERBOARD),1129)
# Formbot T-Rex 3
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
else ifeq ($(HARDWARE_MOTHERBOARD),1130)
# Formbot Raptor
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
else ifeq ($(HARDWARE_MOTHERBOARD),1131)
# Formbot Raptor 2
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
else ifeq ($(HARDWARE_MOTHERBOARD),1132)
# bq ZUM Mega 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
else ifeq ($(HARDWARE_MOTHERBOARD),1133)
# MakeBoard Mini v2.1.2 by MicroMake
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
else ifeq ($(HARDWARE_MOTHERBOARD),1134)
# TriGorilla Anycubic version 1.3-based on RAMPS EFB
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
else ifeq ($(HARDWARE_MOTHERBOARD),1135)
# ... Ver 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
else ifeq ($(HARDWARE_MOTHERBOARD),1136)
# ... Rev 1.1 (new servo pin order)
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
else ifeq ($(HARDWARE_MOTHERBOARD),1137)
# Creality: Ender-4, CR-8
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
else ifeq ($(HARDWARE_MOTHERBOARD),1138)
# Creality: CR10S, CR20, CR-X
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
else ifeq ($(HARDWARE_MOTHERBOARD),1139)
# Dagoma F5
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# Dagoma D6 (as found in the Dagoma DiscoUltimate V2 TMC)
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
else ifeq ($(HARDWARE_MOTHERBOARD),1140)
# FYSETC F6 1.3
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
else ifeq ($(HARDWARE_MOTHERBOARD),1141)
# FYSETC F6 1.4
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
else ifeq ($(HARDWARE_MOTHERBOARD),1142)
# Wanhao Duplicator i3 Plus
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
else ifeq ($(HARDWARE_MOTHERBOARD),1143)
# VORON Design
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
else ifeq ($(HARDWARE_MOTHERBOARD),1144)
# Tronxy TRONXY-V3-1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
else ifeq ($(HARDWARE_MOTHERBOARD),1145)
# Z-Bolt X Series
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
else ifeq ($(HARDWARE_MOTHERBOARD),1146)
# TT OSCAR
else ifeq ($(HARDWARE_MOTHERBOARD),1147)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1148)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1149)
# BIQU Tango V1
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1150)
# MKS GEN L V2
# BIQU Tango V1
else ifeq ($(HARDWARE_MOTHERBOARD),1151)
# MKS GEN L V2.1
# MKS GEN L V2
else ifeq ($(HARDWARE_MOTHERBOARD),1152)
# Copymaster 3D
# MKS GEN L V2.1
else ifeq ($(HARDWARE_MOTHERBOARD),1153)
# Ortur 4
# Copymaster 3D
else ifeq ($(HARDWARE_MOTHERBOARD),1154)
# Tenlog D3 Hero IDEX printer
# Ortur 4
else ifeq ($(HARDWARE_MOTHERBOARD),1155)
# Tenlog D3, D5, D6 IDEX Printer
# Tenlog D3 Hero IDEX printer
else ifeq ($(HARDWARE_MOTHERBOARD),1156)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
# Tenlog D3,5,6 Pro IDEX printers
else ifeq ($(HARDWARE_MOTHERBOARD),1157)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Fan, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1158)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend0, Hotend1, Hotend2, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1159)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
# Ramps S 1.2 by Sakul.cz (Power outputs: Hotend, Fan0, Fan1, Bed)
else ifeq ($(HARDWARE_MOTHERBOARD),1160)
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
# Longer LK1 PRO / Alfawise U20 Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1161)
# Pxmalion Core I3
# Longer LKx PRO / Alfawise Uxx Pro (PRO version)
else ifeq ($(HARDWARE_MOTHERBOARD),1162)
# Panowin Cutlass (as found in the Panowin F1)
# Zonestar zrib V5.3 (Chinese RAMPS replica)
else ifeq ($(HARDWARE_MOTHERBOARD),1163)
# Kodama Bardo V1.x (as found in the Kodama Trinus)
# Pxmalion Core I3
else ifeq ($(HARDWARE_MOTHERBOARD),1164)
# XTLW MFF V1.0
else ifeq ($(HARDWARE_MOTHERBOARD),1165)
# XTLW MFF V2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1166)
#
# RAMBo and derivatives
@@ -356,7 +340,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1203)
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
# abee Scoovo X9H
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
# ThinkerV2
# Rambo ThinkerV2
else ifeq ($(HARDWARE_MOTHERBOARD),1206)
#
@@ -399,40 +383,30 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1315)
else ifeq ($(HARDWARE_MOTHERBOARD),1316)
# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1317)
# Geeetech GT2560 Rev B for Mecreator2
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
# Geeetech GT2560 Rev B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
else ifeq ($(HARDWARE_MOTHERBOARD),1318)
# Geeetech GT2560 Rev B for Mecreator2
else ifeq ($(HARDWARE_MOTHERBOARD),1319)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1321)
else ifeq ($(HARDWARE_MOTHERBOARD),1320)
# Einstart retrofit
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
else ifeq ($(HARDWARE_MOTHERBOARD),1321)
# Wanhao 0ne+ i3 Mini
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# Overlord/Overlord Pro
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# ADIMLab Gantry v1
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# ADIMLab Gantry v2
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
else ifeq ($(HARDWARE_MOTHERBOARD),1322)
# Leapfrog Xeed 2015
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
else ifeq ($(HARDWARE_MOTHERBOARD),1323)
# PICA Shield (original version)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
else ifeq ($(HARDWARE_MOTHERBOARD),1324)
# PICA Shield (rev C or later)
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
else ifeq ($(HARDWARE_MOTHERBOARD),1325)
# Intamsys 4.0 (Funmat HT)
else ifeq ($(HARDWARE_MOTHERBOARD),1330)
else ifeq ($(HARDWARE_MOTHERBOARD),1326)
# Malyan M180 Mainboard Version 2 (no display function, direct G-code only)
else ifeq ($(HARDWARE_MOTHERBOARD),1331)
else ifeq ($(HARDWARE_MOTHERBOARD),1327)
# Geeetech GT2560 Rev B for A20(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1328)
# Mega controller & Protoneer CNC Shield V3.00
else ifeq ($(HARDWARE_MOTHERBOARD),1332)
# WEEDO 62A board (TINA2, Monoprice Cadet, etc.)
else ifeq ($(HARDWARE_MOTHERBOARD),1333)
# Geeetech GT2560 V4.1B for A10(M/T/D)
else ifeq ($(HARDWARE_MOTHERBOARD),1334)
else ifeq ($(HARDWARE_MOTHERBOARD),1329)
#
# ATmega1281, ATmega2561
@@ -466,7 +440,7 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1502)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega644p
PROG_MCU ?= m644p
# Melzi V2
# Melzi V2.0
else ifeq ($(HARDWARE_MOTHERBOARD),1503)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
@@ -476,38 +450,33 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1504)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# Melzi Creality3D (for CR-10 etc)
# Melzi Creality3D board (for CR-10 etc)
else ifeq ($(HARDWARE_MOTHERBOARD),1505)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# Melzi Creality3D (for Ender-2)
# Melzi Malyan M150 board
else ifeq ($(HARDWARE_MOTHERBOARD),1506)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# Melzi Malyan M150
# Tronxy X5S
else ifeq ($(HARDWARE_MOTHERBOARD),1507)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# Tronxy X5S
# STB V1.1
else ifeq ($(HARDWARE_MOTHERBOARD),1508)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# STB V1.1
# Azteeg X1
else ifeq ($(HARDWARE_MOTHERBOARD),1509)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# Azteeg X1
else ifeq ($(HARDWARE_MOTHERBOARD),1510)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
# Anet 1.0 (Melzi clone)
else ifeq ($(HARDWARE_MOTHERBOARD),1511)
else ifeq ($(HARDWARE_MOTHERBOARD),1510)
HARDWARE_VARIANT ?= Sanguino
MCU ?= atmega1284p
PROG_MCU ?= m1284p
@@ -1026,7 +995,7 @@ extcoff: $(TARGET).elf
$(NM) -n $< > $@
# Link: create ELF output file from library.
LDFLAGS+= -Wl,-V
$(BUILD_DIR)/$(TARGET).elf: $(OBJ) Configuration.h
$(Pecho) " CXX $@"
$P $(CXX) $(LD_PREFIX) $(ALL_CXXFLAGS) -o $@ -L. $(OBJ) $(LDFLAGS) $(LD_SUFFIX)
+3 -10
View File
@@ -41,14 +41,7 @@
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2025-03-18"
/**
* The protocol for communication to the host. Protocol indicates communication
* standards such as the use of ASCII, "echo:" and "error:" line prefixes, etc.
* (Other behaviors are given by the firmware version and capabilities report.)
*/
//#define PROTOCOL_VERSION "1.0"
//#define STRING_DISTRIBUTION_DATE "2024-05-27"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
@@ -75,8 +68,8 @@
//#define WEBSITE_URL "marlinfw.org"
/**
* Set the vendor info the serial USB interface, if changeable.
* Currently only supported by DUE platform.
* Set the vendor info the serial USB interface, if changable
* Currently only supported by DUE platform
*/
//#define USB_DEVICE_VENDOR_ID 0x0000
//#define USB_DEVICE_PRODUCT_ID 0x0000
+44 -41
View File
@@ -62,11 +62,6 @@ motherboard = BOARD_RAMPS_14_EFB
serial_port = 0
baudrate = 250000
string_config_h_author = "(default from config.ini)"
capabilities_report = on
extended_capabilities_report = on
use_watchdog = on
thermal_protection_hotends = on
thermal_protection_hysteresis = 4
@@ -82,7 +77,9 @@ temp_sensor_0 = 1
temp_hysteresis = 3
heater_0_mintemp = 5
heater_0_maxtemp = 275
preheat_1_temp_hotend = 180
bang_max = 255
pidtemp = on
pid_k1 = 0.95
pid_max = 255
@@ -92,14 +89,6 @@ default_kp = 22.20
default_ki = 1.08
default_kd = 114.00
temp_sensor_bed = 1
bed_mintemp = 5
bed_maxtemp = 150
thermal_protection_bed = on
thermal_protection_bed_hysteresis = 2
thermal_protection_bed_period = 20
x_driver_type = A4988
y_driver_type = A4988
z_driver_type = A4988
@@ -132,10 +121,10 @@ default_max_acceleration = { 3000, 3000, 100, 10000 }
homing_feedrate_mm_m = { (50*60), (50*60), (4*60) }
homing_bump_divisor = { 2, 2, 4 }
x_enable_on = LOW
y_enable_on = LOW
z_enable_on = LOW
e_enable_on = LOW
x_enable_on = 0
y_enable_on = 0
z_enable_on = 0
e_enable_on = 0
invert_x_dir = false
invert_y_dir = true
@@ -147,6 +136,11 @@ step_state_x = HIGH
step_state_y = HIGH
step_state_z = HIGH
disable_x = off
disable_y = off
disable_z = off
disable_e = off
proportional_font_ratio = 1.0
default_nominal_filament_dia = 1.75
@@ -159,13 +153,18 @@ default_retract_acceleration = 3000
default_minimumfeedrate = 0.0
default_mintravelfeedrate = 0.0
minimum_planner_speed = 0.05
min_steps_per_segment = 6
default_minsegmenttime = 20000
[config:basic]
bed_overshoot = 10
busy_while_heating = on
default_ejerk = 5.0
default_keepalive_interval = 2
default_leveling_fade_height = 0.0
disable_other_extruders = on
display_charset_hd44780 = JAPANESE
eeprom_boot_silent = on
eeprom_chitchat = on
endstoppullups = on
@@ -174,8 +173,10 @@ extrude_mintemp = 170
host_keepalive_feature = on
hotend_overshoot = 15
jd_handle_small_segments = on
lcd_info_screen_style = 0
lcd_language = en
max_bed_power = 255
mesh_inset = 0
min_software_endstops = on
max_software_endstops = on
min_software_endstop_x = on
@@ -184,48 +185,50 @@ min_software_endstop_z = on
max_software_endstop_x = on
max_software_endstop_y = on
max_software_endstop_z = on
preheat_1_label = "PLA"
preheat_1_temp_hotend = 180
preheat_1_temp_bed = 70
preheat_1_fan_speed = 0
preheat_2_label = "ABS"
preheat_2_temp_hotend = 240
preheat_2_temp_bed = 110
preheat_2_fan_speed = 0
preheat_1_label = "PLA"
preheat_1_temp_bed = 70
prevent_cold_extrusion = on
prevent_lengthy_extrude = on
printjob_timer_autostart = on
probing_margin = 10
show_bootscreen = on
soft_pwm_scale = 0
string_config_h_author = "(none, default config)"
temp_bed_hysteresis = 3
temp_bed_residency_time = 10
temp_bed_window = 1
temp_residency_time = 10
temp_window = 1
validate_homing_endstops = on
editable_steps_per_unit = on
xy_probe_feedrate = (133*60)
z_clearance_between_probes = 5
z_clearance_deploy_probe = 10
z_clearance_multi_probe = 5
[config:advanced]
arc_support = on
auto_report_temperatures = on
autotemp = on
autotemp_min = 210
autotemp_max = 250
autotemp_factor = 0.1f
autotemp_oldweight = 0.98
bed_check_interval = 5000
default_stepper_timeout_sec = 120
default_volumetric_extruder_limit = 0.00
disable_idle_x = on
disable_idle_y = on
disable_idle_z = on
disable_idle_e = on
e0_auto_fan_pin = -1
encoder_100x_steps_per_sec = 80
encoder_10x_steps_per_sec = 30
encoder_rate_multiplier = on
extended_capabilities_report = on
extruder_auto_fan_speed = 255
extruder_auto_fan_temperature = 50
fanmux0_pin = -1
fanmux1_pin = -1
fanmux2_pin = -1
faster_gcode_parser = on
debug_flags_gcode = on
homing_bump_mm = { 5, 5, 2 }
max_arc_segment_mm = 1.0
min_arc_segment_mm = 0.1
@@ -234,11 +237,11 @@ n_arc_correction = 25
serial_overrun_protection = on
slowdown = on
slowdown_divisor = 2
temp_sensor_bed = 0
thermal_protection_bed_hysteresis = 2
thermocouple_max_errors = 15
tx_buffer_size = 0
bed_check_interval = 5000
watch_bed_temp_increase = 2
watch_bed_temp_period = 60
watch_temp_increase = 2
watch_temp_period = 40
watch_temp_period = 20
+6 -6
View File
@@ -129,11 +129,11 @@ typedef Servo hal_servo_t;
#endif
#endif
#ifdef MMU_SERIAL_PORT
#if !WITHIN(MMU_SERIAL_PORT, 0, 3)
#error "MMU_SERIAL_PORT must be from 0 to 3"
#ifdef MMU2_SERIAL_PORT
#if !WITHIN(MMU2_SERIAL_PORT, 0, 3)
#error "MMU2_SERIAL_PORT must be from 0 to 3"
#endif
#define MMU_SERIAL mmuSerial
#define MMU2_SERIAL mmuSerial
#endif
#ifdef LCD_SERIAL_PORT
@@ -141,7 +141,7 @@ typedef Servo hal_servo_t;
#error "LCD_SERIAL_PORT must be from 0 to 3."
#endif
#define LCD_SERIAL lcdSerial
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
#if HAS_DGUS_LCD
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free()
#endif
#endif
@@ -159,7 +159,7 @@ typedef Servo hal_servo_t;
#define GET_PIN_MAP_INDEX(pin) pin
#define PARSED_PIN_INDEX(code, dval) parser.intval(code, dval)
#define HAL_SENSITIVE_PINS 0, 1
#define HAL_SENSITIVE_PINS 0, 1,
#ifdef __AVR_AT90USB1286__
#define JTAG_DISABLE() do{ MCUCR = 0x80; MCUCR = 0x80; }while(0)
+8 -8
View File
@@ -601,20 +601,20 @@ MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser);
#endif // SERIAL_PORT_3
#ifdef MMU_SERIAL_PORT
#ifdef MMU2_SERIAL_PORT
ISR(SERIAL_REGNAME(USART, MMU_SERIAL_PORT, _RX_vect)) {
MarlinSerial<MMU2SerialCfg<MMU_SERIAL_PORT>>::store_rxd_char();
ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _RX_vect)) {
MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>>::store_rxd_char();
}
ISR(SERIAL_REGNAME(USART, MMU_SERIAL_PORT, _UDRE_vect)) {
MarlinSerial<MMU2SerialCfg<MMU_SERIAL_PORT>>::_tx_udr_empty_irq();
ISR(SERIAL_REGNAME(USART, MMU2_SERIAL_PORT, _UDRE_vect)) {
MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>>::_tx_udr_empty_irq();
}
template class MarlinSerial< MMU2SerialCfg<MMU_SERIAL_PORT> >;
template class MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> >;
MSerialMMU2 mmuSerial(MSerialMMU2::HasEmergencyParser);
#endif // MMU_SERIAL_PORT
#endif // MMU2_SERIAL_PORT
#ifdef LCD_SERIAL_PORT
@@ -629,7 +629,7 @@ MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser);
template class MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> >;
MSerialLCD lcdSerial(MSerialLCD::HasEmergencyParser);
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
#if HAS_DGUS_LCD
template<typename Cfg>
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
+3 -3
View File
@@ -205,7 +205,7 @@
static ring_buffer_pos_t available();
static void write(const uint8_t c);
static void flushTX();
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
#if HAS_DGUS_LCD
static ring_buffer_pos_t get_tx_buffer_free();
#endif
@@ -246,7 +246,7 @@
#endif // !USBCON
#ifdef MMU_SERIAL_PORT
#ifdef MMU2_SERIAL_PORT
template <uint8_t serial>
struct MMU2SerialCfg {
static constexpr int PORT = serial;
@@ -260,7 +260,7 @@
static constexpr bool RX_OVERRUNS = false;
};
typedef Serial1Class< MarlinSerial< MMU2SerialCfg<MMU_SERIAL_PORT> > > MSerialMMU2;
typedef Serial1Class< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialMMU2;
extern MSerialMMU2 mmuSerial;
#endif
-8
View File
@@ -345,14 +345,6 @@ void setup_endstop_interrupts() {
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
#if USE_CALIBRATION
#if (digitalPinToInterrupt(CALIBRATION_PIN) != NOT_AN_INTERRUPT)
_ATTACH(CALIBRATION_PIN);
#else
static_assert(digitalPinHasPCICR(CALIBRATION_PIN), "CALIBRATION_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(CALIBRATION_PIN);
#endif
#endif
// If we arrive here without raising an assertion, each pin has either an EXT-interrupt or a PCI.
}
+1 -1
View File
@@ -150,7 +150,7 @@ void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
else {
if (p == 32 || p == 128) continue; // Skip TIMER2 specific prescalers when not TIMER2
const uint16_t rft = (F_CPU) / (p * f_desired);
DEBUG_ECHOLNPGM("(Not Timer 2) F_CPU=", STRINGIFY(F_CPU), " prescaler=", p, " f_desired=", f_desired);
DEBUG_ECHOLNPGM("(Not Timer 2) F_CPU=" STRINGIFY(F_CPU), " prescaler=", p, " f_desired=", f_desired);
res_fast_temp = rft - 1;
res_pc_temp = rft / 2;
}
+3
View File
@@ -28,6 +28,9 @@
* Port : E0 E1 E4 E5 G5 E3 H3 H4 H5 H6 B4 B5 B6 B7 J1 J0 H1 H0 D3 D2 D1 D0 A0 A1 A2 A3 A4 A5 A6 A7 C7 C6 C5 C4 C3 C2 C1 C0 D7 G2 G1 G0 L7 L6 L5 L4 L3 L2 L1 L0 B3 B2 B1 B0 F0 F1 F2 F3 F4 F5 F6 F7 K0 K1 K2 K3 K4 K5 K6 K7 | E2 E6 E7 xx xx H2 H7 G3 G4 xx xx xx xx xx D4 D5 D6 xx xx J2 J3 J4 J5 J6 J7 xx xx xx xx xx
* Logical Pin : 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 | 78 79 80 xx xx 84 85 71 70 xx xx xx xx xx 81 82 83 xx xx 72 73 75 76 77 74 xx xx xx xx xx
* Analog Input : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
*
* Arduino Pin Layout video: https://youtu.be/rIqeVCX09FA
* AVR alternate pin function overview video: https://youtu.be/1yd8wuI5Plg
*/
#include "../fastio.h"
+3
View File
@@ -26,6 +26,9 @@
*
* Logical Pin: 38 39 40 41 42 43 44 45 16 10 11 12 06 07 08 09 30 31 32 33 34 35 36 37 17 18 19 20 21 22 23 24 00 01 13 05 02 03 14 15 46 47 48 49 50 51 52 53 25 26 27 28 29 04
* Port: A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 G0 G1 G2 G3 G4 G5
*
* Arduino Pin Layout video: https://youtu.be/rIqeVCX09FA
* AVR alternate pin function overview video: https://youtu.be/1yd8wuI5Plg
*/
#include "../fastio.h"
+3
View File
@@ -26,6 +26,9 @@
*
* Logical Pin: 08 09 10 11 12 13 14 15 16 17 18 19 20 21 00 01 02 03 04 05 06 07
* Port: B0 B1 B2 B3 B4 B5 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7
*
* Arduino Pin Layout video: https://youtu.be/rIqeVCX09FA
* AVR alternate pin function overview video: https://youtu.be/1yd8wuI5Plg
*/
#include "../fastio.h"
+3
View File
@@ -26,6 +26,9 @@
*
* Logical Pin: 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
* Port: B0 B1 B2 B3 B4 B5 B6 B7 D0 D1 D2 D3 D4 D5 D6 D7 C0 C1 C2 C3 C4 C5 C6 C7 A7 A6 A5 A4 A3 A2 A1 A0
*
* Arduino Pin Layout video: https://youtu.be/rIqeVCX09FA
* AVR alternate pin function overview video: https://youtu.be/1yd8wuI5Plg
*/
/** ATMega644
+4 -1
View File
@@ -26,7 +26,10 @@
*
* Logical Pin: 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 08 09(46*47)36 37 18 19 38 39 40 41 42 43 44 45
* Port: A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7
* Logical pins 46-47 aren't supported by Teensyduino, but are supported below as E2 and E3
* The logical pins 46 and 47 are not supported by Teensyduino, but are supported below as E2 and E3
*
* Arduino Pin Layout video: https://youtu.be/rIqeVCX09FA
* AVR alternate pin function overview video: https://youtu.be/1yd8wuI5Plg
*/
#include "../fastio.h"
+29 -45
View File
@@ -22,23 +22,7 @@
#pragma once
/**
* Pins Debugging for Atmel 8 bit AVR CPUs
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
* PWM print routines for Atmel 8 bit AVR CPUs
*/
#include "../../inc/MarlinConfig.h"
@@ -55,44 +39,44 @@
#include "pinsDebug_Teensyduino.h"
// Can't use the "digitalPinToPort" function from the Teensyduino type IDEs
// portModeRegister takes a different argument
#define digitalPinToTimer_DEBUG(P) digitalPinToTimer(P)
#define digitalPinToBitMask_DEBUG(P) digitalPinToBitMask(P)
#define digitalPinToPort_DEBUG(P) digitalPinToPort(P)
#define getValidPinMode(P) (*portModeRegister(P) & digitalPinToBitMask_DEBUG(P))
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort(p)
#define GET_PINMODE(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin))
#elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70
#include "pinsDebug_plus_70.h"
#define digitalPinToTimer_DEBUG(P) digitalPinToTimer_plus_70(P)
#define digitalPinToBitMask_DEBUG(P) digitalPinToBitMask_plus_70(P)
#define digitalPinToPort_DEBUG(P) digitalPinToPort_plus_70(P)
bool getValidPinMode(pin_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer_plus_70(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask_plus_70(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort_plus_70(p)
bool GET_PINMODE(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#else
#define digitalPinToTimer_DEBUG(P) digitalPinToTimer(P)
#define digitalPinToBitMask_DEBUG(P) digitalPinToBitMask(P)
#define digitalPinToPort_DEBUG(P) digitalPinToPort(P)
bool getValidPinMode(pin_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#define getPinByIndex(x) pgm_read_byte(&pin_array[x].pin)
#define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p)
#define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p)
#define digitalPinToPort_DEBUG(p) digitalPinToPort(p)
bool GET_PINMODE(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); }
#define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin)
#endif
#define isValidPin(P) (P >= 0 && P < NUMBER_PINS_TOTAL)
#define VALID_PIN(pin) (pin >= 0 && pin < NUM_DIGITAL_PINS ? 1 : 0)
#if AVR_ATmega1284_FAMILY
#define isAnalogPin(P) WITHIN(P, analogInputToDigitalPin(7), analogInputToDigitalPin(0))
#define digitalPinToAnalogIndex(P) int(isAnalogPin(P) ? (P) - analogInputToDigitalPin(7) : -1)
#define IS_ANALOG(P) WITHIN(P, analogInputToDigitalPin(7), analogInputToDigitalPin(0))
#define DIGITAL_PIN_TO_ANALOG_PIN(P) int(IS_ANALOG(P) ? (P) - analogInputToDigitalPin(7) : -1)
#else
#define _ANALOG1(P) WITHIN(P, analogInputToDigitalPin(0), analogInputToDigitalPin(7))
#define _ANALOG2(P) WITHIN(P, analogInputToDigitalPin(8), analogInputToDigitalPin(15))
#define isAnalogPin(P) (_ANALOG1(P) || _ANALOG2(P))
#define digitalPinToAnalogIndex(P) int(_ANALOG1(P) ? (P) - analogInputToDigitalPin(0) : _ANALOG2(P) ? (P) - analogInputToDigitalPin(8) + 8 : -1)
#define IS_ANALOG(P) (_ANALOG1(P) || _ANALOG2(P))
#define DIGITAL_PIN_TO_ANALOG_PIN(P) int(_ANALOG1(P) ? (P) - analogInputToDigitalPin(0) : _ANALOG2(P) ? (P) - analogInputToDigitalPin(8) + 8 : -1)
#endif
#define getPinByIndex(x) pgm_read_byte(&pin_array[x].pin)
#define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin)
#define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin
void printPinNameByIndex(const uint8_t index) {
PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[index].name);
void PRINT_ARRAY_NAME(uint8_t x) {
PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name);
for (uint8_t y = 0; y < MAX_NAME_LENGTH; ++y) {
char temp_char = pgm_read_byte(name_mem_pointer + y);
if (temp_char != 0)
@@ -104,7 +88,7 @@ void printPinNameByIndex(const uint8_t index) {
}
}
#define getPinIsDigitalByIndex(x) pgm_read_byte(&pin_array[x].is_digital)
#define GET_ARRAY_IS_DIGITAL(x) pgm_read_byte(&pin_array[x].is_digital)
#if defined(__AVR_ATmega1284P__) // 1284 IDE extensions set this to the number of
#undef NUM_DIGITAL_PINS // digital only pins while all other CPUs have it
@@ -125,7 +109,7 @@ void printPinNameByIndex(const uint8_t index) {
* Print a pin's PWM status.
* Return true if it's currently a PWM pin.
*/
bool pwm_status(const uint8_t pin) {
bool pwm_status(uint8_t pin) {
char buffer[20]; // for the sprintf statements
switch (digitalPinToTimer_DEBUG(pin)) {
@@ -292,7 +276,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N -
if (TEST(*TMSK, TOIE)) err_prob_interrupt();
}
void printPinPWM(const uint8_t pin) {
void pwm_details(uint8_t pin) {
switch (digitalPinToTimer_DEBUG(pin)) {
#if ABTEST(0)
@@ -363,7 +347,7 @@ void printPinPWM(const uint8_t pin) {
#else
UNUSED(print_is_also_tied);
#endif
} // printPinPWM
} // pwm_details
#ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs
int digitalRead_mod(const pin_t pin) { // same as digitalRead except the PWM stop section has been removed
@@ -372,7 +356,7 @@ void printPinPWM(const uint8_t pin) {
}
#endif
void printPinPort(const pin_t pin) { // print port number
void print_port(const pin_t pin) { // print port number
#ifdef digitalPinToPort_DEBUG
uint8_t x;
SERIAL_ECHOPGM(" Port: ");
@@ -402,7 +386,7 @@ void printPinPort(const pin_t pin) { // print port number
#endif
}
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#undef ABTEST
+1 -1
View File
@@ -102,7 +102,7 @@ const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
// digitalPinToBitMask(pin) is OK
#define digitalRead_mod(P) extDigitalRead(P) // Teensyduino's version of digitalRead doesn't
#define digitalRead_mod(p) extDigitalRead(p) // Teensyduino's version of digitalRead doesn't
// disable the PWMs so we can use it as is
// portModeRegister(pin) is OK
+26 -24
View File
@@ -23,41 +23,43 @@
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
* Platform pins have parentheses, e.g., "(53)", so we cannot use them.
*/
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__)
#define _PIN_SPI_SCK 13
#define _PIN_SPI_MISO 12
#define _PIN_SPI_MOSI 11
#define _PIN_SPI_SS 10
#define AVR_SCK_PIN 13
#define AVR_MISO_PIN 12
#define AVR_MOSI_PIN 11
#define AVR_SS_PIN 10
#elif defined(__AVR_ATmega644__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega644PA__) || defined(__AVR_ATmega1284P__)
#define _PIN_SPI_SCK 7
#define _PIN_SPI_MISO 6
#define _PIN_SPI_MOSI 5
#define _PIN_SPI_SS 4
#define AVR_SCK_PIN 7
#define AVR_MISO_PIN 6
#define AVR_MOSI_PIN 5
#define AVR_SS_PIN 4
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define _PIN_SPI_SCK 52
#define _PIN_SPI_MISO 50
#define _PIN_SPI_MOSI 51
#define _PIN_SPI_SS 53
#define AVR_SCK_PIN 52
#define AVR_MISO_PIN 50
#define AVR_MOSI_PIN 51
#define AVR_SS_PIN 53
#elif defined(__AVR_AT90USB1287__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__)
#define _PIN_SPI_SCK 21
#define _PIN_SPI_MISO 23
#define _PIN_SPI_MOSI 22
#define _PIN_SPI_SS 20
#define AVR_SCK_PIN 21
#define AVR_MISO_PIN 23
#define AVR_MOSI_PIN 22
#define AVR_SS_PIN 20
#elif defined(__AVR_ATmega1281__) || defined(__AVR_ATmega2561__)
#define _PIN_SPI_SCK 10
#define _PIN_SPI_MISO 12
#define _PIN_SPI_MOSI 11
#define _PIN_SPI_SS 16
#define AVR_SCK_PIN 10
#define AVR_MISO_PIN 12
#define AVR_MOSI_PIN 11
#define AVR_SS_PIN 16
#endif
#ifndef SD_SCK_PIN
#define SD_SCK_PIN _PIN_SPI_SCK
#define SD_SCK_PIN AVR_SCK_PIN
#endif
#ifndef SD_MISO_PIN
#define SD_MISO_PIN _PIN_SPI_MISO
#define SD_MISO_PIN AVR_MISO_PIN
#endif
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN _PIN_SPI_MOSI
#define SD_MOSI_PIN AVR_MOSI_PIN
#endif
#ifndef SD_SS_PIN
#define SD_SS_PIN AVR_SS_PIN
#endif
@@ -120,7 +120,7 @@ void u8g_spiSend_sw_AVR_mode_3(uint8_t val) {
U8G_ATOMIC_END();
}
#if U8G_SPI_USE_MODE_3
#if ENABLED(FYSETC_MINI_12864)
#define SPISEND_SW_AVR u8g_spiSend_sw_AVR_mode_3
#else
#define SPISEND_SW_AVR u8g_spiSend_sw_AVR_mode_0
@@ -143,9 +143,9 @@ uint8_t u8g_com_HAL_AVR_sw_sp_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
break;
case U8G_COM_MSG_CHIP_SELECT:
#if U8G_SPI_USE_MODE_3 // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
#if ENABLED(FYSETC_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_com_arduino_digital_write(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
u8g_com_arduino_digital_write(u8g, U8G_PI_CS, LOW);
}
+1 -1
View File
@@ -48,7 +48,7 @@ uint16_t MarlinHAL::adc_result;
void MarlinHAL::init() {
#if HAS_MEDIA
OUT_WRITE(SD_SS_PIN, HIGH); // Try to set SDSS inactive before any other SPI users start up
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
usb_task_init(); // Initialize the USB stack
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
+62 -4
View File
@@ -35,9 +35,67 @@
#include <stdint.h>
//
// Serial Ports
//
#include "../../core/serial_hook.h"
// ------------------------
// Serial ports
// ------------------------
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
extern DefaultSerial1 MSerial0;
extern DefaultSerial2 MSerial1;
extern DefaultSerial3 MSerial2;
extern DefaultSerial4 MSerial3;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL1 customizedSerial1
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from 0 to 3, or -1 for USB Serial."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL2 customizedSerial2
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from 0 to 3, or -1 for USB Serial."
#endif
#endif
#ifdef SERIAL_PORT_3
#if SERIAL_PORT_3 == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL3 customizedSerial3
#elif WITHIN(SERIAL_PORT_3, 0, 3)
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
#else
#error "SERIAL_PORT_3 must be from 0 to 3, or -1 for USB Serial."
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from 0 to 3."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be from 0 to 3."
#endif
#endif
#include "MarlinSerial.h"
#include "MarlinSerialUSB.h"
@@ -69,7 +127,7 @@ typedef Servo hal_servo_t;
#define HAL_ADC_RESOLUTION 10
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) pin_t((p < 12U) ? (p) + 54U : -1)
#define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1)
#endif
//
+4 -3
View File
@@ -600,8 +600,9 @@
OUT_WRITE(SPI_EEPROM1_CS_PIN, HIGH);
OUT_WRITE(SPI_EEPROM2_CS_PIN, HIGH);
OUT_WRITE(SPI_FLASH_CS_PIN, HIGH);
OUT_WRITE(SD_SS_PIN, HIGH);
WRITE(SD_SS_PIN, LOW);
WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, LOW);
PIO_Configure(
g_APinDescription[SPI_PIN].pPort,
@@ -766,7 +767,7 @@
// Disable PIO on A26 and A27
REG_PIOA_PDR = 0x0C000000;
OUT_WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, HIGH);
// Reset SPI0 (from sam lib)
SPI0->SPI_CR = SPI_CR_SPIDIS;
-15
View File
@@ -33,21 +33,6 @@
#include "../../core/types.h"
#include "../../core/serial_hook.h"
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
extern DefaultSerial1 MSerial0;
extern DefaultSerial2 MSerial1;
extern DefaultSerial3 MSerial2;
extern DefaultSerial4 MSerial3;
#define SERIAL_INDEX_MIN 0
#define SERIAL_INDEX_MAX 3
#define EP_SERIAL_PORT(N) customizedSerial##N
#define USB_SERIAL_PORT(N) customizedSerial##N
#include "../shared/serial_ports.h"
// Define constants and variables for buffering incoming serial data. We're
// using a ring buffer (I think), in which rx_buffer_head is the index of the
// location to which to write the next incoming character and rx_buffer_tail
+1 -1
View File
@@ -50,7 +50,7 @@
static Flags<_Nbr_16timers> DisablePending; // ISR should disable the timer at the next timer reset
// ------------------------
// Interrupt handler for the TC0 channel 1.
/// Interrupt handler for the TC0 channel 1.
// ------------------------
void Servo_Handler(const timer16_Sequence_t, Tc*, const uint8_t);
+1 -1
View File
@@ -291,7 +291,7 @@ static bool ee_PageWrite(uint16_t page, const void *data) {
uint32_t *p1 = (uint32_t*)addrflash;
uint32_t *p2 = (uint32_t*)data;
int count = 0;
for (i = 0; i < PageSize >> 2; i++) {
for (i =0; i<PageSize >> 2; i++) {
if (p1[i] != p2[i]) {
uint32_t delta = p1[i] ^ p2[i];
while (delta) {
-1
View File
@@ -64,7 +64,6 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));
+7 -6
View File
@@ -68,15 +68,16 @@
* Usually the hardware SPI pins are only available to the LCD. This makes the DUE hard SPI used at the same time
* as the TMC2130 soft SPI the most common setup.
*/
#define _IS_HW_SPI(P) (defined(TMC_SPI_##P) && (TMC_SPI_##P == SD_MOSI_PIN || TMC_SPI_##P == SD_MISO_PIN || TMC_SPI_##P == SD_SCK_PIN))
#if HAS_MEDIA && HAS_DRIVER(TMC2130)
#define _IS_HW_SPI(P) (defined(TMC_SPI_##P) && (TMC_SPI_##P == SD_MOSI_PIN || TMC_SPI_##P == SD_MISO_PIN || TMC_SPI_##P == SD_SCK_PIN))
#if DISABLED(SOFTWARE_SPI) && ENABLED(TMC_USE_SW_SPI) && (_IS_HW_SPI(MOSI) || _IS_HW_SPI(MISO) || _IS_HW_SPI(SCK))
#error "DUE hardware SPI is required but is incompatible with TMC2130 software SPI. Either disable TMC_USE_SW_SPI or use separate pins for the two SPIs."
#endif
#if ENABLED(SOFTWARE_SPI) && DISABLED(TMC_USE_SW_SPI)
#if ENABLED(TMC_USE_SW_SPI)
#if DISABLED(SOFTWARE_SPI) && (_IS_HW_SPI(MOSI) || _IS_HW_SPI(MISO) || _IS_HW_SPI(SCK))
#error "DUE hardware SPI is required but is incompatible with TMC2130 software SPI. Either disable TMC_USE_SW_SPI or use separate pins for the two SPIs."
#endif
#elif ENABLED(SOFTWARE_SPI)
#error "DUE software SPI is required but is incompatible with TMC2130 hardware SPI. Enable TMC_USE_SW_SPI to fix."
#endif
#undef _IS_HW_SPI
#endif
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
+19 -32
View File
@@ -19,26 +19,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Pins Debugging for DUE
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
* Support routines for Due
*/
/**
* Translation of routines & variables used by pinsDebug.h
*/
#include "../shared/Marduino.h"
@@ -76,20 +63,20 @@
#define NUMBER_PINS_TOTAL PINS_COUNT
#define digitalRead_mod(P) extDigitalRead(P) // AVR digitalRead disabled PWM before it read the pin
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
#define getPinByIndex(x) pin_array[x].pin
#define getPinIsDigitalByIndex(x) pin_array[x].is_digital
#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL))
#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0))
#define isAnalogPin(P) WITHIN(P, pin_t(analogInputToDigitalPin(0)), pin_t(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
#define pwm_status(P) (((g_pinStatus[P] & 0xF) == PIN_STATUS_PWM) && \
((g_APinDescription[P].ulPinAttribute & PIN_ATTR_PWM) == PIN_ATTR_PWM))
#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital
#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL))
#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0))
#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \
((g_APinDescription[pin].ulPinAttribute & PIN_ATTR_PWM) == PIN_ATTR_PWM))
#define MULTI_NAME_PAD 14 // space needed to be pretty if not first name assigned to a pin
bool getValidPinMode(const pin_t pin) { // 1: output, 0: input
bool GET_PINMODE(int8_t pin) { // 1: output, 0: input
volatile Pio* port = g_APinDescription[pin].pPort;
uint32_t mask = g_APinDescription[pin].ulPin;
uint8_t pin_status = g_pinStatus[pin] & 0xF;
@@ -98,14 +85,14 @@ bool getValidPinMode(const pin_t pin) { // 1: output, 0: input
|| pwm_status(pin));
}
void printPinPWM(const int32_t pin) {
void pwm_details(int32_t pin) {
if (pwm_status(pin)) {
uint32_t chan = g_APinDescription[pin].ulPWMChannel;
SERIAL_ECHOPGM("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY);
}
}
void printPinPort(const pin_t) {}
void print_port(const pin_t) {}
/**
* DUE Board pin | PORT | Label
+28 -25
View File
@@ -24,38 +24,41 @@
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
*
* Available chip select pins for HW SPI are 4 10 52 77 87
* Available chip select pins for HW SPI are 4 10 52 77
*/
#if SD_SS_PIN == 4 || SD_SS_PIN == 10 || SD_SS_PIN == 52 || SD_SS_PIN == 77 || SD_SS_PIN == 87
#define SD_SCK_PIN 76
#define SD_MISO_PIN 74
#define SD_MOSI_PIN 75
#endif
#if SD_SS_PIN == 4
#define SPI_PIN 87
#define SPI_CHAN 1
#elif SD_SS_PIN == 10
#define SPI_PIN 77
#define SPI_CHAN 0
#elif SD_SS_PIN == 52
#define SPI_PIN 86
#define SPI_CHAN 2
#elif SD_SS_PIN == 77
#define SPI_PIN 77
#define SPI_CHAN 0
#elif SD_SS_PIN == 87
#define SPI_PIN 87
#define SPI_CHAN 1
#if SDSS == 4 || SDSS == 10 || SDSS == 52 || SDSS == 77 || SDSS == 87
#if SDSS == 4
#define SPI_PIN 87
#define SPI_CHAN 1
#elif SDSS == 10
#define SPI_PIN 77
#define SPI_CHAN 0
#elif SDSS == 52
#define SPI_PIN 86
#define SPI_CHAN 2
#elif SDSS == 77
#define SPI_PIN 77
#define SPI_CHAN 0
#else
#define SPI_PIN 87
#define SPI_CHAN 1
#endif
#define SD_SCK_PIN 76
#define SD_MISO_PIN 74
#define SD_MOSI_PIN 75
#else
// defaults
#define SOFTWARE_SPI
#ifndef SD_SCK_PIN
#define SD_SCK_PIN 52
#define SD_SCK_PIN 52
#endif
#ifndef SD_MISO_PIN
#define SD_MISO_PIN 50
#define SD_MISO_PIN 50
#endif
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN 51
#define SD_MOSI_PIN 51
#endif
#endif
/* A.28, A.29, B.21, C.26, C.29 */
#define SD_SS_PIN SDSS
@@ -66,7 +66,7 @@
#include <U8glib-HAL.h>
#if U8G_SPI_USE_MODE_3
#if ENABLED(FYSETC_MINI_12864)
#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_3
#else
#define SPISEND_SW_DUE u8g_spiSend_sw_DUE_mode_0
@@ -96,15 +96,15 @@ uint8_t u8g_com_HAL_DUE_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void
break;
case U8G_COM_MSG_CHIP_SELECT:
#if U8G_SPI_USE_MODE_3 // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
#if ENABLED(FYSETC_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 1); //set SCK to mode 3 idle state before CS goes active
u8g_SetPILevel_DUE(u8g, U8G_PI_CS, LOW);
}
else {
u8g_SetPILevel_DUE(u8g, U8G_PI_CS, HIGH);
u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive
u8g_SetPILevel_DUE(u8g, U8G_PI_SCK, 0); //set SCK to mode 0 idle state after CS goes inactive
}
#else
u8g_SetPILevel_DUE(u8g, U8G_PI_CS, !arg_val);
+1 -1
View File
@@ -11,7 +11,7 @@ if pioutil.is_pio_build():
if current_OS == 'Windows':
env = pioutil.env
Import("env")
# Use bossac.exe on Windows
env.Replace(
+5 -5
View File
@@ -19,7 +19,7 @@ void sd_mmc_spi_mem_init() {
}
inline bool media_ready() {
return IS_SD_MOUNTED() && IS_SD_INSERTED() && !IS_SD_FILE_OPEN() && !IS_SD_PRINTING();
return IS_SD_INSERTED() && !IS_SD_PRINTING() && !IS_SD_FILE_OPEN() && card.isMounted();
}
bool sd_mmc_spi_unload(bool) { return true; }
@@ -32,14 +32,14 @@ Ctrl_status sd_mmc_spi_test_unit_ready() {
#ifdef DISABLE_DUE_SD_MMC
return CTRL_NO_PRESENT;
#endif
if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT;
if (!media_ready()) return CTRL_NO_PRESENT;
return CTRL_GOOD;
}
// NOTE: This function is defined as returning the address of the last block
// in the card, which is cardSize() - 1
Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) {
if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT;
if (!media_ready()) return CTRL_NO_PRESENT;
*nb_sector = card.diskIODriver()->cardSize() - 1;
return CTRL_GOOD;
}
@@ -61,7 +61,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
#ifdef DISABLE_DUE_SD_MMC
return CTRL_NO_PRESENT;
#endif
if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT;
if (!media_ready()) return CTRL_NO_PRESENT;
#ifdef DEBUG_MMC
{
@@ -100,7 +100,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
#ifdef DISABLE_DUE_SD_MMC
return CTRL_NO_PRESENT;
#endif
if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT;
if (!media_ready()) return CTRL_NO_PRESENT;
#ifdef DEBUG_MMC
{
+8 -9
View File
@@ -209,17 +209,16 @@ int MarlinHAL::freeMemory() { return ESP.getFreeHeap(); }
// ADC
// ------------------------
// https://docs.espressif.com/projects/esp-idf/en/release-v4.4/esp32/api-reference/peripherals/adc.html
#define ADC1_CHANNEL(pin) ADC1_GPIO ## pin ## _CHANNEL
adc1_channel_t get_channel(int pin) {
switch (pin) {
case 39: return ADC1_CHANNEL_3;
case 36: return ADC1_CHANNEL_0;
case 35: return ADC1_CHANNEL_7;
case 34: return ADC1_CHANNEL_6;
case 33: return ADC1_CHANNEL_5;
case 32: return ADC1_CHANNEL_4;
case 37: return ADC1_CHANNEL_1;
case 38: return ADC1_CHANNEL_2;
case 39: return ADC1_CHANNEL(39);
case 36: return ADC1_CHANNEL(36);
case 35: return ADC1_CHANNEL(35);
case 34: return ADC1_CHANNEL(34);
case 33: return ADC1_CHANNEL(33);
case 32: return ADC1_CHANNEL(32);
}
return ADC1_CHANNEL_MAX;
}
@@ -59,7 +59,6 @@ void setup_endstop_interrupts() {
TERN_(USE_Z4_MAX, _ATTACH(Z4_MAX_PIN));
TERN_(USE_Z4_MIN, _ATTACH(Z4_MIN_PIN));
TERN_(USE_Z_MIN_PROBE, _ATTACH(Z_MIN_PROBE_PIN));
TERN_(USE_CALIBRATION, _ATTACH(CALIBRATION_PIN));
TERN_(USE_I_MAX, _ATTACH(I_MAX_PIN));
TERN_(USE_I_MIN, _ATTACH(I_MIN_PIN));
TERN_(USE_J_MAX, _ATTACH(J_MAX_PIN));
-7
View File
@@ -37,10 +37,6 @@
// Set pin as output
#define _SET_OUTPUT(IO) pinMode(IO, OUTPUT)
// TODO: Store set modes in an array and use those to get the mode
#define _IS_OUTPUT(IO) true
#define _IS_INPUT(IO) true
// Set pin as input with pullup mode
#define _PULLUP(IO, v) pinMode(IO, v ? INPUT_PULLUP : INPUT)
@@ -74,9 +70,6 @@
// Set pin as output and init
#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
#define IS_INPUT(IO) _IS_INPUT(IO)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
+1 -1
View File
@@ -152,7 +152,7 @@ void stepperTask(void *parameter) {
xQueueReceive(dma.queue, &dma.current, portMAX_DELAY);
dma.rw_pos = 0;
const bool using_ftMotion = TERN0(FT_MOTION, ftMotion.cfg.active);
const bool using_ftMotion = TERN0(FT_MOTION, ftMotion.cfg.mode);
while (dma.rw_pos < DMA_SAMPLE_COUNT) {
+1 -5
View File
@@ -22,15 +22,11 @@
#ifdef ARDUINO_ARCH_ESP32
#include <WiFi.h>
#undef ENABLED
#undef DISABLED
#include "../../inc/MarlinConfigPre.h"
#if ALL(WIFISUPPORT, OTASUPPORT)
#include <WiFi.h>
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
-71
View File
@@ -1,71 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#error "PINS_DEBUGGING is not yet supported for ESP32!"
/**
* Pins Debugging for ESP32
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
#define digitalRead_mod(P) extDigitalRead(P)
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
#define getPinByIndex(x) pin_array[x].pin
#define getPinIsDigitalByIndex(x) pin_array[x].is_digital
#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL))
#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0))
#define isAnalogPin(P) WITHIN(P, pin_t(analogInputToDigitalPin(0)), pin_t(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1)))
bool pwm_status(const pin_t) { return false; }
void printPinPort(const pin_t) {}
static bool getValidPinMode(const pin_t pin) {
return isValidPin(pin) && !IS_INPUT(pin);
}
void printPinPWM(const int32_t pin) {
if (pwm_status(pin)) {
//uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative;
//SERIAL_ECHOPGM("PWM = ", duty);
}
}
+4 -13
View File
@@ -21,16 +21,7 @@
*/
#pragma once
#define PIN_SPI_SCK 18
#define PIN_SPI_MISO 19
#define PIN_SPI_MOSI 23
#ifndef SD_SCK_PIN
#define SD_SCK_PIN PIN_SPI_SCK
#endif
#ifndef SD_MISO_PIN
#define SD_MISO_PIN PIN_SPI_MISO
#endif
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN PIN_SPI_MOSI
#endif
#define SD_SS_PIN SDSS
#define SD_SCK_PIN 18
#define SD_MISO_PIN 19
#define SD_MOSI_PIN 23
+1 -1
View File
@@ -90,7 +90,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
config.counter_en = TIMER_PAUSE;
config.alarm_en = TIMER_ALARM_EN;
config.intr_type = TIMER_INTR_LEVEL;
config.auto_reload = TIMER_AUTORELOAD_EN;
config.auto_reload = true;
// Select and initialize the timer
timer_init(timer.group, timer.idx, &config);
+1 -2
View File
@@ -21,12 +21,11 @@
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../core/serial.h"
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(WIFISUPPORT)
#include "../../core/serial.h"
#include <WiFi.h>
#include <ESPmDNS.h>
#include <ESPAsyncWebServer.h>
+65 -11
View File
@@ -30,18 +30,69 @@
#include "../../inc/MarlinConfig.h"
#include "../../core/macros.h"
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "timers.h"
#include "MarlinSerial.h"
#include <stdint.h>
//
// Serial Ports
//
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define NUM_UARTS 4
#include "MarlinSerial.h"
#if SERIAL_PORT == -1
#error "USB Serial is not supported on HC32F460"
#elif WITHIN(SERIAL_PORT, 1, NUM_UARTS)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#define MYSERIAL1 MSERIAL(1) // Dummy port
static_assert(false, "SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ".")
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#error "USB Serial is not supported on HC32F460"
#elif WITHIN(SERIAL_PORT_2, 1, NUM_UARTS)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#define MYSERIAL2 MSERIAL(1) // Dummy port
static_assert(false, "SERIAL_PORT_2 must be from 1 to " STRINGIFY(NUM_UARTS) ".")
#endif
#endif
#ifdef SERIAL_PORT_3
#if SERIAL_PORT_3 == -1
#error "USB Serial is not supported on HC32F460"
#elif WITHIN(SERIAL_PORT_3, 1, NUM_UARTS)
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
#else
#define MYSERIAL3 MSERIAL(1) // Dummy port
static_assert(false, "SERIAL_PORT_3 must be from 1 to " STRINGIFY(NUM_UARTS) ".")
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#error "USB Serial is not supported on HC32F460"
#elif WITHIN(LCD_SERIAL_PORT, 1, NUM_UARTS)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#define LCD_SERIAL MSERIAL(1) // Dummy port
static_assert(false, "LCD_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ".")
#endif
#if HAS_DGUS_LCD
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
#endif
#endif
//
// Emergency Parser
@@ -63,19 +114,22 @@
// Misc. Functions
//
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) pin_t(p)
#define analogInputToDigitalPin(p) (p)
#endif
#define CRITICAL_SECTION_START() \
const bool irqon = !__get_PRIMASK(); \
__disable_irq(); \
__DSB();
#define CRITICAL_SECTION_END() \
__DSB(); \
if (irqon) __enable_irq();
#define CRITICAL_SECTION_START \
uint32_t primask = __get_PRIMASK(); \
(void)__iCliRetVal()
#define cli() __disable_irq()
#define sei() __enable_irq()
#define CRITICAL_SECTION_END \
if (!primask) \
(void)__iSeiRetVal()
// Disable interrupts
#define cli() noInterrupts()
// Enable interrupts
#define sei() interrupts()
// bss_end alias
#define __bss_end __bss_end__
-8
View File
@@ -24,14 +24,6 @@
#include "../../core/serial_hook.h"
#include <drivers/usart/Usart.h>
#define SERIAL_INDEX_MIN 1
#define SERIAL_INDEX_MAX 4
#include "../shared/serial_ports.h"
#if defined(LCD_SERIAL_PORT) && ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
#endif
// Optionally set uart IRQ priority to reduce overflow errors
//#define UART_RX_IRQ_PRIO 1
//#define UART_TX_IRQ_PRIO 1
+1 -1
View File
@@ -11,7 +11,7 @@ The HC32F460 HAL is designed to be generic enough for any HC32F460-based board.
- Examine the board's main processor. (Refer the naming key in `hc32.ini`.)
- Extend the `HC32F460C_common` base env for 256K, or `HC32F460E_common` for 512K.
3. Determine your board's application start address (see [below](#finding-the-application-start-address))
4. Set `board_upload.offset_address` to the app start address once you've found it. If your board doesn't use a bootloader, you may be able to use the "ICSP" header or DFU. This document will be updated once we have more information about flashing without a bootloader.
4. Set `board_build.ld_args.flash_start` to the app start address once you've found it. If your board doesn't use a bootloader, you may be able to use the "ICSP" header or DFU. This document will be updated once we have more information about flashing without a bootloader.
### Finding the application start address
+7 -4
View File
@@ -8,7 +8,6 @@
#define _HC32_APP_CONFIG_H_
#include "../../inc/MarlinConfigPre.h"
#include "sysclock.h"
//
// dev mode
@@ -65,8 +64,12 @@
// redirect printf to host serial
#define REDIRECT_PRINTF_TO_SERIAL 1
// F_CPU is F_HCLK, as that's the main CPU core's clock.
// see 'sysclock.h' for more information.
#define F_CPU F_HCLK
// F_CPU must be known at compile time, but on HC32F460 it's not.
// Thus we assume HCLK to be 200MHz, as that's what is configured in
// 'core_hook_sysclock_init' in 'sysclock.cpp'.
// If you face issues with this assumption, please double-check with the values
// printed by 'MarlinHAL::HAL_clock_frequencies_dump'.
// see also: HAL_TIMER_RATE in timers.h
#define F_CPU 200000000 // 200MHz HCLK
#endif // _HC32_APP_CONFIG_H_
+1 -3
View File
@@ -101,14 +101,12 @@ void setup_endstop_interrupts() {
SETUP(Z_MIN_PROBE);
SETUP(CALIBRATION);
#undef SETUP
}
// Ensure 1 - 10 IRQs are registered
// Disable some endstops if you encounter this error
#define ENDSTOPS_INTERRUPTS_COUNT COUNT_ENABLED(USE_X_MAX, USE_X_MIN, USE_X2_MAX, USE_X2_MIN, USE_Y_MAX, USE_Y_MIN, USE_Y2_MAX, USE_Y2_MIN, USE_Z_MAX, USE_Z_MIN, USE_Z2_MAX, USE_Z2_MIN, USE_Z3_MAX, USE_Z3_MIN, USE_Z4_MAX, USE_Z4_MIN, USE_Z_MIN_PROBE, USE_CALIBRATION)
#define ENDSTOPS_INTERRUPTS_COUNT COUNT_ENABLED(USE_X_MAX, USE_X_MIN, USE_X2_MAX, USE_X2_MIN, USE_Y_MAX, USE_Y_MIN, USE_Y2_MAX, USE_Y2_MIN, USE_Z_MAX, USE_Z_MIN, USE_Z2_MAX, USE_Z2_MIN, USE_Z3_MAX, USE_Z3_MIN, USE_Z4_MAX, USE_Z4_MIN, USE_Z_MIN_PROBE)
#if ENDSTOPS_INTERRUPTS_COUNT > 10
#error "Too many endstop interrupts! HC32F460 only supports 10 endstop interrupts."
#elif ENDSTOPS_INTERRUPTS_COUNT == 0
+2 -4
View File
@@ -94,10 +94,8 @@
#error "SERIAL_DMA requires USART_RX_DMA_SUPPORT to be enabled in the arduino core."
#endif
// Before arduino core version 1.2.0, USART_RX_DMA_SUPPORT did not implement
// core_hook_usart_rx_irq, which is required for the emergency parser.
// With 1.2.0, this was fixed (see https://github.com/shadow578/framework-arduino-hc32f46x/pull/25).
#if ENABLED(EMERGENCY_PARSER) && ARDUINO_CORE_VERSION_INT < GET_VERSION_INT(1, 2, 0)
// USART_RX_DMA_SUPPORT does not implement core_hook_usart_rx_irq, which is required for the emergency parser
#if ENABLED(EMERGENCY_PARSER)
#error "EMERGENCY_PARSER is not supported with SERIAL_DMA. Please disable either SERIAL_DMA or EMERGENCY_PARSER."
#endif
+33 -39
View File
@@ -18,47 +18,41 @@
*/
#pragma once
/**
* Pins Debugging for HC32
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
*/
#include "../../inc/MarlinConfig.h"
#include "fastio.h"
#include <drivers/timera/timera_pwm.h>
//
// Translation of routines & variables used by pinsDebug.h
//
#ifndef BOARD_NR_GPIO_PINS
#error "Expected BOARD_NR_GPIO_PINS not found."
#endif
#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS
#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS
#define isValidPin(P) IS_GPIO_PIN(P)
#define VALID_PIN(pin) IS_GPIO_PIN(pin)
// Note: pin_array is defined in `Marlin/src/pins/pinsDebug.h`, and since this file is included
// after it, it is available in this file as well.
#define getPinByIndex(x) pin_t(pin_array[x].pin)
#define digitalRead_mod(P) extDigitalRead(P)
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(P)); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin)
#define digitalRead_mod(p) extDigitalRead(p)
#define PRINT_PIN(p) \
do { \
sprintf_P(buffer, PSTR("%3hd "), int16_t(p)); \
SERIAL_ECHO(buffer); \
} while (0)
#define PRINT_PIN_ANALOG(p) \
do { \
sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); \
SERIAL_ECHO(buffer); \
} while (0)
#define PRINT_PORT(p) print_port(p)
#define PRINT_ARRAY_NAME(x) \
do { \
sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); \
SERIAL_ECHO(buffer); \
} while (0)
#define MULTI_NAME_PAD 21 // Space needed to be pretty if not first name assigned to a pin
@@ -77,14 +71,14 @@
#define M43_NEVER_TOUCH(Q) (IS_HOST_USART_PIN(Q) || IS_OSC_PIN(Q))
#endif
int8_t digitalPinToAnalogIndex(const pin_t pin) {
if (!isValidPin(pin)) return -1;
static pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
if (!VALID_PIN(pin)) return -1;
const int8_t adc_channel = int8_t(PIN_MAP[pin].adc_info.channel);
return pin_t(adc_channel);
}
bool isAnalogPin(pin_t pin) {
if (!isValidPin(pin)) return false;
static bool IS_ANALOG(pin_t pin) {
if (!VALID_PIN(pin)) return false;
if (PIN_MAP[pin].adc_info.channel != ADC_PIN_INVALID)
return _GET_MODE(pin) == INPUT_ANALOG && !M43_NEVER_TOUCH(pin);
@@ -92,13 +86,13 @@ bool isAnalogPin(pin_t pin) {
return false;
}
bool getValidPinMode(const pin_t pin) {
return isValidPin(pin) && !IS_INPUT(pin);
static bool GET_PINMODE(const pin_t pin) {
return VALID_PIN(pin) && !IS_INPUT(pin);
}
bool getPinIsDigitalByIndex(const int16_t index) {
const pin_t pin = getPinByIndex(index);
return (!isAnalogPin(pin));
static bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
const pin_t pin = GET_ARRAY_PIN(array_pin);
return (!IS_ANALOG(pin));
}
/**
@@ -123,7 +117,7 @@ bool pwm_status(const pin_t pin) {
return timera_is_unit_initialized(unit) && timera_is_channel_active(unit, channel) && getPinMode(pin) == OUTPUT_PWM;
}
void printPinPWM(const pin_t pin) {
void pwm_details(const pin_t pin) {
// Get timer assignment for pin
timera_config_t *unit;
en_timera_channel_t channel;
@@ -167,7 +161,7 @@ void printPinPWM(const pin_t pin) {
}
}
void printPinPort(pin_t pin) {
void print_port(pin_t pin) {
const char port = 'A' + char(pin >> 4); // Pin div 16
const int16_t gbit = PIN_MAP[pin].bit_pos;
char buffer[8];
+67 -170
View File
@@ -26,144 +26,64 @@
#ifdef ARDUINO_ARCH_HC32
// Get BOARD_XTAL_FREQUENCY from configuration / pins
#include "../../inc/MarlinConfig.h"
#include "sysclock.h"
#include <core_hooks.h>
#include <drivers/sysclock/sysclock_util.h>
/***
* @brief Automatically calculate M, N, P values for the MPLL to reach a target frequency.
* @param input_frequency The input frequency.
* @param target_frequency The target frequency.
* @return The MPLL configuration structure. Q and R are not set.
*
* @note
* Simplified MPLL block diagram, with intermediary clocks (1) = VCO_in, (2) = VCO_out:
*
* INPUT -> [/ M] -(1)-> [* N] -(2)-|-> [/ P] -> MPLL-P
*/
constexpr stc_clk_mpll_cfg_t get_mpll_config(double input_frequency, double target_frequency) {
// PLL input clock divider: M in [1, 24]
for (uint32_t M = 1; M <= 24; M++) {
double f_vco_in = input_frequency / M;
// 1 <= VCO_in <= 25 MHz
if (f_vco_in < 1e6 || f_vco_in > 25e6) continue;
// VCO multiplier: N in [20, 480]
for (uint32_t N = 20; N <= 480; N++) {
double f_vco_out = f_vco_in * N;
// 240 <= VCO_out <= 480 MHz
if (f_vco_out < 240e6 || f_vco_out > 480e6) continue;
// Output "P" divider: P in [2, 16]
for (uint32_t P = 2; P <= 16; P++) {
double f_calculated_out = f_vco_out / P;
if (f_calculated_out == target_frequency) {
// Found a match, return it
return {
.PllpDiv = P,
.PllqDiv = P, // Don't care for Q and R
.PllrDiv = P, // "
.plln = N,
.pllmDiv = M
};
}
}
}
}
// If no valid M, N, P found, return invalid config
return { 0, 0, 0, 0, 0 };
}
/**
* @brief Get the division factor required to get the target frequency from the input frequency.
* @tparam input_freq The input frequency.
* @tparam target_freq The target frequency.
* @return The division factor.
*/
template <uint32_t input_freq, uint32_t target_freq>
constexpr en_clk_sysclk_div_factor_t get_division_factor() {
// Calculate the divider to get the target frequency
constexpr float fdivider = static_cast<float>(input_freq) / static_cast<float>(target_freq);
constexpr int divider = static_cast<int>(fdivider);
// divider must be an integer
static_assert(fdivider == divider, "Target frequency not achievable, divider must be an integer");
// divider must be between 1 and 64 (enum range), and must be a power of 2
static_assert(divider >= 1 && divider <= 64, "Invalid divider, out of range");
static_assert((divider & (divider - 1)) == 0, "Invalid divider, not a power of 2");
// return the divider
switch (divider) {
case 1: return ClkSysclkDiv1;
case 2: return ClkSysclkDiv2;
case 4: return ClkSysclkDiv4;
case 8: return ClkSysclkDiv8;
case 16: return ClkSysclkDiv16;
case 32: return ClkSysclkDiv32;
case 64: return ClkSysclkDiv64;
}
}
/**
* @brief Validate the runtime clocks match the expected values.
*/
void validate_system_clocks() {
#define CLOCK_ASSERT(expected, actual) \
if (expected != actual) { \
SERIAL_ECHOPGM( \
"Clock Mismatch for " #expected ": " \
"expected ", expected, \
", got ", actual \
); \
CORE_ASSERT_FAIL("Clock Mismatch: " #expected); \
}
update_system_clock_frequencies();
CLOCK_ASSERT(F_SYSTEM_CLOCK, SYSTEM_CLOCK_FREQUENCIES.system);
CLOCK_ASSERT(F_HCLK, SYSTEM_CLOCK_FREQUENCIES.hclk);
CLOCK_ASSERT(F_EXCLK, SYSTEM_CLOCK_FREQUENCIES.exclk);
CLOCK_ASSERT(F_PCLK0, SYSTEM_CLOCK_FREQUENCIES.pclk0);
CLOCK_ASSERT(F_PCLK1, SYSTEM_CLOCK_FREQUENCIES.pclk1);
CLOCK_ASSERT(F_PCLK2, SYSTEM_CLOCK_FREQUENCIES.pclk2);
CLOCK_ASSERT(F_PCLK3, SYSTEM_CLOCK_FREQUENCIES.pclk3);
CLOCK_ASSERT(F_PCLK4, SYSTEM_CLOCK_FREQUENCIES.pclk4);
}
/**
* @brief Configure HC32 system clocks.
*
* This function is called by the Arduino core early in the startup process, before setup() is called.
* It is used to configure the system clocks to the desired state.
*
* See https://github.com/MarlinFirmware/Marlin/pull/27099 for more information.
*/
void core_hook_sysclock_init() {
// Set wait cycles, as we are about to switch to 200 MHz HCLK
sysclock_configure_flash_wait_cycles();
sysclock_configure_sram_wait_cycles();
// Select MPLL input frequency based on clock availability
#if BOARD_XTAL_FREQUENCY == 8000000 || BOARD_XTAL_FREQUENCY == 16000000 // 8 MHz or 16 MHz XTAL
constexpr uint32_t mpll_input_clock = BOARD_XTAL_FREQUENCY;
// Configure MPLLp to 200 MHz output, with different settings depending on XTAL availability
#if BOARD_XTAL_FREQUENCY == 8000000 // 8 MHz XTAL
// - M = 1 => 8 MHz / 1 = 8 MHz
// - N = 50 => 8 MHz * 50 = 400 MHz
// - P = 2 => 400 MHz / 2 = 200 MHz (sysclk)
// - Q,R = 4 => 400 MHz / 4 = 100 MHz (dont care)
stc_clk_mpll_cfg_t pllConf = {
.PllpDiv = 2u, // P
.PllqDiv = 4u, // Q
.PllrDiv = 4u, // R
.plln = 50u, // N
.pllmDiv = 1u, // M
};
sysclock_configure_xtal();
sysclock_configure_mpll(ClkPllSrcXTAL, &pllConf);
#if BOARD_XTAL_FREQUENCY == 16000000
#warning "HC32F460 with 16 MHz XTAL has not been tested."
#endif
#elif BOARD_XTAL_FREQUENCY == 16000000 // 16 MHz XTAL
// - M = 1 => 16 MHz / 1 = 16 MHz
// - N = 50 => 16 MHz * 25 = 400 MHz
// - P = 2 => 400 MHz / 2 = 200 MHz (sysclk)
// - Q,R = 4 => 400 MHz / 4 = 100 MHz (dont care)
stc_clk_mpll_cfg_t pllConf = {
.PllpDiv = 2u, // P
.PllqDiv = 4u, // Q
.PllrDiv = 4u, // R
.plln = 50u, // N
.pllmDiv = 1u, // M
};
sysclock_configure_xtal();
sysclock_configure_mpll(ClkPllSrcXTAL, &pllConf);
#warning "HC32F460 with 16 MHz XTAL has not been tested."
#else // HRC (16 MHz)
constexpr uint32_t mpll_input_clock = 16000000;
// - M = 1 => 16 MHz / 1 = 16 MHz
// - N = 25 => 16 MHz * 25 = 400 MHz
// - P = 2 => 400 MHz / 2 = 200 MHz (sysclk)
// - Q,R = 4 => 400 MHz / 4 = 100 MHz (dont care)
stc_clk_mpll_cfg_t pllConf = {
.PllpDiv = 2u, // P
.PllqDiv = 4u, // Q
.PllrDiv = 4u, // R
.plln = 25u, // N
.pllmDiv = 1u, // M
};
sysclock_configure_hrc();
sysclock_configure_mpll(ClkPllSrcHRC, &pllConf);
// HRC could have been configured by ICG to 20 MHz
// TODO: handle gracefully if HRC is not 16 MHz
@@ -171,56 +91,29 @@ void core_hook_sysclock_init() {
panic("HRC is not 16 MHz");
}
#if defined(BOARD_XTAL_FREQUENCY)
#ifdef BOARD_XTAL_FREQUENCY
#warning "No valid XTAL frequency defined, falling back to HRC."
#endif
#endif
// Automagically calculate MPLL configuration
constexpr stc_clk_mpll_cfg_t pllConf = get_mpll_config(mpll_input_clock, F_SYSTEM_CLOCK);
static_assert(pllConf.pllmDiv != 0 && pllConf.plln != 0 && pllConf.PllpDiv != 0, "MPLL auto-configuration failed");
sysclock_configure_mpll(ClkPllSrcXTAL, &pllConf);
// sysclk is now configured according to F_CPU (i.e., 200MHz PLL output)
constexpr uint32_t sysclock = F_CPU;
// Setup clock divisors
// Setup clock divisors for sysclk = 200 MHz
// Note: PCLK1 is used for step+temp timers, and need to be kept at 50 MHz (until there is a better solution)
constexpr stc_clk_sysclk_cfg_t sysClkConf = {
.enHclkDiv = get_division_factor<F_SYSTEM_CLOCK, F_HCLK>(),
.enExclkDiv = get_division_factor<F_SYSTEM_CLOCK, F_EXCLK>(),
.enPclk0Div = get_division_factor<F_SYSTEM_CLOCK, F_PCLK0>(),
.enPclk1Div = get_division_factor<F_SYSTEM_CLOCK, F_PCLK1>(),
.enPclk2Div = get_division_factor<F_SYSTEM_CLOCK, F_PCLK2>(),
.enPclk3Div = get_division_factor<F_SYSTEM_CLOCK, F_PCLK3>(),
.enPclk4Div = get_division_factor<F_SYSTEM_CLOCK, F_PCLK4>(),
.enHclkDiv = ClkSysclkDiv1, // HCLK = 200 MHz (CPU)
.enExclkDiv = ClkSysclkDiv2, // EXCLK = 100 MHz (SDIO)
.enPclk0Div = ClkSysclkDiv2, // PCLK0 = 100 MHz (Timer6 (not used))
.enPclk1Div = ClkSysclkDiv4, // PCLK1 = 50 MHz (USART, SPI, I2S, Timer0 (step+temp), TimerA (Servo))
.enPclk2Div = ClkSysclkDiv8, // PCLK2 = 25 MHz (ADC)
.enPclk3Div = ClkSysclkDiv8, // PCLK3 = 25 MHz (I2C, WDT)
.enPclk4Div = ClkSysclkDiv2, // PCLK4 = 100 MHz (ADC ctl)
};
sysclock_set_clock_dividers(&sysClkConf);
// Set power mode, before switch
power_mode_update_pre(F_SYSTEM_CLOCK);
// Switch to MPLL-P as system clock source
CLK_SetSysClkSource(CLKSysSrcMPLL);
// Set power mode, after switch
power_mode_update_post(F_SYSTEM_CLOCK);
// Verify clocks match expected values (at runtime)
#if ENABLED(MARLIN_DEV_MODE) || ENABLED(ALWAYS_VALIDATE_CLOCKS)
validate_system_clocks();
#endif
// Verify clock configuration (at compile time)
#if ARDUINO_CORE_VERSION_INT >= GET_VERSION_INT(1, 2, 0)
assert_mpll_config_valid<
mpll_input_clock,
pllConf.pllmDiv,
pllConf.plln,
pllConf.PllpDiv,
pllConf.PllqDiv,
pllConf.PllrDiv
>();
assert_system_clocks_valid<
F_SYSTEM_CLOCK,
sysclock,
sysClkConf.enHclkDiv,
sysClkConf.enPclk0Div,
sysClkConf.enPclk1Div,
@@ -229,14 +122,18 @@ void core_hook_sysclock_init() {
sysClkConf.enPclk4Div,
sysClkConf.enExclkDiv
>();
static_assert(get_mpll_output_clock(
mpll_input_clock,
pllConf.pllmDiv,
pllConf.plln,
pllConf.PllpDiv
) == F_SYSTEM_CLOCK, "actual MPLL output clock does not match F_SYSTEM_CLOCK");
#endif
sysclock_set_clock_dividers(&sysClkConf);
// Set power mode
power_mode_update_pre(sysclock);
// Switch to MPLL as sysclk source
CLK_SetSysClkSource(CLKSysSrcMPLL);
// Set power mode
power_mode_update_post(sysclock);
}
#endif // ARDUINO_ARCH_HC32
-65
View File
@@ -1,65 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* HC32F460 system clock configuration.
*
* With the HC32 HAL, the various peripheral clocks (including the CPU clock) are derived
* from the main PLL (MPLL-P) output (referred to at F_SYSTEM_CLOCK).
*
* F_SYSTEM_CLOCK is the target frequency of the main PLL, and the PLL is automatically configured
* to achieve this frequency.
*
* The peripheral clocks are the result of integer division of F_SYSTEM_CLOCK.
* Their target frequencies are defined here, and the required division factors are calculated automatically.
* Note that the division factor must be a power of 2 between 1 and 64.
* If the target frequency is not achievable, a compile-time error will be generated.
*
* Additionally, there are interdependencies between the peripheral clocks, which are described in
* Section 4.4 "Working Clock Specifications" of the HC32F460 Reference Manual.
* With Arduino core >= 1.2.0, these interdependencies are checked at compile time.
* On earlier versions, you are on your own.
*
* For all clock frequencies, they can be checked at runtime by enabling the 'ALWAYS_VALIDATE_CLOCKS' define.
* In MARLIN_DEV_MODE, they will also be printed to the serial console by 'MarlinHAL::HAL_clock_frequencies_dump'.
*
* See https://github.com/MarlinFirmware/Marlin/pull/27099 for more information.
*/
// Target peripheral clock frequencies, must be integer divisors of F_SYSTEM_CLOCK.
// Changing the frequency here will automagically update everything else.
#define F_HCLK 200000000UL // 200 MHz; CPU
#define F_EXCLK (F_HCLK / 2) // 100 MHz; SDIO
#define F_PCLK0 (F_HCLK / 2) // 100 MHz; Timer6 (unused)
#define F_PCLK1 (F_HCLK / 4) // 50 MHz; USART, SPI, Timer0 (step + temp), TimerA (Servo)
#define F_PCLK2 (F_HCLK / 8) // 25 MHz; ADC Sampling
#define F_PCLK3 (F_HCLK / 8) // 25 MHz; I2C, WDT
#define F_PCLK4 (F_HCLK / 2) // 100 MHz; ADC Control
// MPLL-P clock target frequency. This must be >= the highest peripheral clock frequency.
// PLL config is automatically calculated based on this value.
#define F_SYSTEM_CLOCK F_HCLK
// The Peripheral clocks are only checked at runtime if this is enabled OR MARLIN_DEV_MODE is enabled.
// Compile time checks are always performed with Arduino core version >= 1.2.0.
#define ALWAYS_VALIDATE_CLOCKS 1
+8 -7
View File
@@ -20,7 +20,6 @@
#pragma once
#include <stdint.h>
#include <Timer0.h>
#include "sysclock.h"
//
// Timer Types
@@ -43,15 +42,17 @@ extern Timer0 step_timer;
* HAL_TIMER_RATE must be known at compile time since it's used to calculate
* STEPPER_TIMER_RATE, which is used in 'constexpr' calculations.
* On the HC32F460 the timer rate depends on PCLK1, which is derived from the
* system clock configured at runtime.
* Thus we use the 'F_PCLK1' constant defined in 'sysclock.h'.
* system clock configured at runtime. As a workaround, we use the existing
* assumption of a 200MHz clock, defining F_CPU as 200000000, then configure PCLK1
* as F_CPU with a divider of 4 in 'sysclock.cpp::core_hook_sysclock_init'.
*
* See https://github.com/MarlinFirmware/Marlin/pull/27099 for more information.
* If you face issues with this assumption, please double-check with the values
* printed by 'MarlinHAL::HAL_clock_frequencies_dump'.
*
* NOTE: If the 'constexpr' requirement is ever lifted, TIMER0_BASE_FREQUENCY could
* be used instead. Tho this would probably not make any noticable difference.
* TODO: If the 'constexpr' requirement is ever lifted, use TIMER0_BASE_FREQUENCY instead
*/
#define HAL_TIMER_RATE F_PCLK1
#define HAL_TIMER_RATE (F_CPU / 4) // i.e., 50MHz
//#define HAL_TIMER_RATE TIMER0_BASE_FREQUENCY
// Temperature timer
#define TEMP_TIMER_NUM (&temp_timer)
@@ -82,7 +82,7 @@ static inline uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, c
}
static void u8g_sw_spi_shift_out(uint8_t val) {
#if U8G_SPI_USE_MODE_3
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864)
swSpiTransfer_mode_3(val, SPI_speed);
#else
swSpiTransfer_mode_0(val, SPI_speed);
@@ -116,15 +116,15 @@ uint8_t u8g_com_HAL_HC32_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, voi
break;
case U8G_COM_MSG_CHIP_SELECT:
#if U8G_SPI_USE_MODE_3 // This LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
WRITE(DOGLCD_SCK, HIGH); // Set SCK to mode 3 idle state before CS goes active
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864) // This LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
WRITE(DOGLCD_SCK, HIGH); // Set SCK to mode 3 idle state before CS goes active
WRITE(DOGLCD_CS, LOW);
}
else {
WRITE(DOGLCD_CS, HIGH);
WRITE(DOGLCD_SCK, LOW); // Set SCK to mode 0 idle state after CS goes inactive
WRITE(DOGLCD_SCK, LOW); // Set SCK to mode 0 idle state after CS goes inactive
}
#else
WRITE(DOGLCD_CS, !arg_val);
+1 -1
View File
@@ -52,7 +52,7 @@ uint8_t MarlinHAL::active_ch = 0;
uint16_t MarlinHAL::adc_value() {
const pin_t pin = analogInputToDigitalPin(active_ch);
if (!isValidPin(pin)) return 0;
if (!VALID_PIN(pin)) return 0;
return uint16_t((Gpio::get(pin) >> 2) & 0x3FF); // return 10bit value as Marlin expects
}
+6 -6
View File
@@ -49,28 +49,28 @@ extern "C" void delay(const int msec) {
// IO functions
// As defined by Arduino INPUT(0x0), OUTPUT(0x1), INPUT_PULLUP(0x2)
void pinMode(const pin_t pin, const uint8_t mode) {
if (!isValidPin(pin)) return;
if (!VALID_PIN(pin)) return;
Gpio::setMode(pin, mode);
}
void digitalWrite(pin_t pin, uint8_t pin_status) {
if (!isValidPin(pin)) return;
if (!VALID_PIN(pin)) return;
Gpio::set(pin, pin_status);
}
bool digitalRead(pin_t pin) {
if (!isValidPin(pin)) return false;
if (!VALID_PIN(pin)) return false;
return Gpio::get(pin);
}
void analogWrite(pin_t pin, int pwm_value) { // 1 - 254: pwm_value, 0: LOW, 255: HIGH
if (!isValidPin(pin)) return;
if (!VALID_PIN(pin)) return;
Gpio::set(pin, pwm_value);
}
uint16_t analogRead(pin_t adc_pin) {
if (!isValidPin(digitalPinToAnalogIndex(adc_pin))) return 0;
return Gpio::get(digitalPinToAnalogIndex(adc_pin));
if (!VALID_PIN(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin))) return 0;
return Gpio::get(DIGITAL_PIN_TO_ANALOG_PIN(adc_pin));
}
char *dtostrf(double __val, signed char __width, unsigned char __prec, char *__s) {
+8 -8
View File
@@ -37,29 +37,29 @@ constexpr uint8_t NUM_ANALOG_INPUTS = 16;
constexpr uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS;
// Get the digital pin for an analog index
constexpr pin_t analogInputToDigitalPin(const int8_t a) {
return (WITHIN(a, 0, NUM_ANALOG_INPUTS - 1) ? analog_offset + a : P_NC);
constexpr pin_t analogInputToDigitalPin(const int8_t p) {
return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC);
}
// Get the analog index for a digital pin
constexpr int8_t digitalPinToAnalogIndex(const pin_t pin) {
return (WITHIN(pin, analog_offset, NUM_DIGITAL_PINS - 1) ? pin - analog_offset : P_NC);
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) {
return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC);
}
// Return the index of a pin number
constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { return pin; }
// Test whether the pin is valid
constexpr bool isValidPin(const pin_t pin) { return WITHIN(pin, 0, NUM_DIGITAL_PINS - 1); }
constexpr bool VALID_PIN(const pin_t p) { return WITHIN(p, 0, NUM_DIGITAL_PINS); }
// Test whether the pin is PWM
constexpr bool PWM_PIN(const pin_t) { return false; }
constexpr bool PWM_PIN(const pin_t p) { return false; }
// Test whether the pin is interruptible
constexpr bool INTERRUPT_PIN(const pin_t) { return false; }
constexpr bool INTERRUPT_PIN(const pin_t p) { return false; }
// Get the pin number at the given index
constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) { return pin_t(index); }
constexpr pin_t GET_PIN_MAP_PIN(const int16_t ind) { return ind; }
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
+20 -40
View File
@@ -19,50 +19,30 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Pins Debugging for Linux Native
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
* Support routines for X86_64
*/
/**
* Translation of routines & variables used by pinsDebug.h
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
#define digitalRead_mod(p) digitalRead(p)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin
#define getPinByIndex(x) pin_array[x].pin
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
// active ADC function/mode/code values for PINSEL registers
constexpr int8_t ADC_pin_mode(const pin_t) { return -1; }
constexpr int8_t ADC_pin_mode(pin_t pin) { return -1; }
// The pin and index are the same on this platform
bool getPinIsDigitalByIndex(const pin_t pin) {
return (!isAnalogPin(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
}
int8_t get_pin_mode(const pin_t pin) { return VALID_PIN(pin) ? 0 : -1; }
#define isAnalogPin(P) (digitalPinToAnalogIndex(P) >= 0)
#define digitalRead_mod(P) digitalRead(P)
int8_t get_pin_mode(const pin_t pin) { return isValidPin(pin) ? 0 : -1; }
bool getValidPinMode(const pin_t pin) {
bool GET_PINMODE(const pin_t pin) {
const int8_t pin_mode = get_pin_mode(pin);
if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // Invalid pin or active analog pin
return false;
@@ -70,11 +50,11 @@ bool getValidPinMode(const pin_t pin) {
return (Gpio::getMode(pin) != 0); // Input/output state
}
void printPinPWM(const pin_t) {}
bool GET_ARRAY_IS_DIGITAL(const pin_t pin) {
return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
}
void pwm_details(const pin_t pin) {}
bool pwm_status(const pin_t) { return false; }
void printPinPort(const pin_t) {}
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0)
void print_port(const pin_t) {}
+12
View File
@@ -28,6 +28,12 @@
// spiBeginTransaction.
#endif
// Onboard SD
//#define SD_SCK_PIN P0_07
//#define SD_MISO_PIN P0_08
//#define SD_MOSI_PIN P0_09
//#define SD_SS_PIN P0_06
// External SD
#ifndef SD_SCK_PIN
#define SD_SCK_PIN 50
@@ -38,3 +44,9 @@
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN 52
#endif
#ifndef SD_SS_PIN
#define SD_SS_PIN 53
#endif
#ifndef SDSS
#define SDSS SD_SS_PIN
#endif
+2
View File
@@ -35,6 +35,8 @@
#include <CDCSerial.h>
#include <usb/mscuser.h>
DefaultSerial1 USBSerial(false, UsbSerial);
uint32_t MarlinHAL::adc_result = 0;
pin_t MarlinHAL::adc_pin = 0;
+64 -7
View File
@@ -38,15 +38,72 @@ extern "C" volatile uint32_t _millis;
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "MarlinSerial.h"
#include <adc.h>
#include <pinmapping.h>
#include <CDCSerial.h>
//
// Serial Ports
//
// ------------------------
// Serial ports
// ------------------------
#include "MarlinSerial.h"
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
extern DefaultSerial1 USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#ifdef SERIAL_PORT_3
#if SERIAL_PORT_3 == -1
#define MYSERIAL3 USBSerial
#elif WITHIN(SERIAL_PORT_3, 0, 3)
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
#else
#error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL USBSerial
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL USBSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#if HAS_DGUS_LCD
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.available()
#endif
#endif
//
// Interrupts
@@ -80,12 +137,12 @@ extern "C" volatile uint32_t _millis;
//
// Test whether the pin is valid
constexpr bool isValidPin(const pin_t pin) {
constexpr bool VALID_PIN(const pin_t pin) {
return LPC176x::pin_is_valid(pin);
}
// Get the analog index for a digital pin
constexpr int8_t digitalPinToAnalogIndex(const pin_t pin) {
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) {
return (LPC176x::pin_is_valid(pin) && LPC176x::pin_has_adc(pin)) ? pin : -1;
}
@@ -102,7 +159,7 @@ constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
// P0.6 thru P0.9 are for the onboard SD card
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09,
// ------------------------
// Defines
-2
View File
@@ -25,8 +25,6 @@
#include "../../inc/MarlinConfig.h"
DefaultSerial1 USBSerial(false, UsbSerial);
#if USING_HW_SERIAL0
MarlinSerial _MSerial0(LPC_UART0);
MSerialT MSerial0(true, _MSerial0);
-13
View File
@@ -21,7 +21,6 @@
*/
#pragma once
#include <CDCSerial.h>
#include <HardwareSerial.h>
#include <WString.h>
@@ -31,18 +30,6 @@
#endif
#include "../../core/serial_hook.h"
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
extern DefaultSerial1 USBSerial;
#define SERIAL_INDEX_MIN 0
#define SERIAL_INDEX_MAX 3
#define USB_SERIAL_PORT(...) USBSerial
#include "../shared/serial_ports.h"
#if defined(LCD_SERIAL_PORT) && ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.available()
#endif
class MarlinSerial : public HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE> {
public:
MarlinSerial(LPC_UART_TypeDef *UARTx) : HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE>(UARTx) { }
@@ -146,12 +146,6 @@ void setup_endstop_interrupts() {
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
#if USE_CALIBRATION
#if !LPC1768_PIN_INTERRUPT_M(CALIBRATION_PIN)
#error "CALIBRATION_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(CALIBRATION_PIN);
#endif
#if USE_I_MAX
#if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN)
#error "I_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
+2 -4
View File
@@ -26,10 +26,8 @@
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
if (!LPC176x::pin_is_valid(pin)) return;
if (LPC176x::pwm_attach_pin(pin)) {
const uint32_t duty = map(invert ? v_size - v : v, 0, v_size, 0, LPC176x::pwm_get_period(pin));
LPC176x::pwm_write(pin, duty);
}
if (LPC176x::pwm_attach_pin(pin))
LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range
}
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
+1 -1
View File
@@ -66,7 +66,7 @@
#define _WRITE(IO,V) WRITE_PIN(IO,V)
/// toggle a pin
#define _TOGGLE(IO) LPC176x::gpio_toggle(IO)
#define _TOGGLE(IO) _WRITE(IO, !READ(IO))
/// set pin as input
#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
+3 -3
View File
@@ -121,7 +121,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
#elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \
|| ANY_RX(1, LCD_SDSS_PIN, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
|| ANY_RX(1, LCD_SDSS, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
#error "Serial port pins (1) conflict with LCD pins!"
#endif
#endif
@@ -211,8 +211,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "SCL0 overlaps with Encoder Button!"
#elif IS_SCL0(SD_SS_PIN)
#error "SCL0 overlaps with SD_SS_PIN!"
#elif IS_SCL0(LCD_SDSS_PIN)
#error "SCL0 overlaps with LCD_SDSS_PIN!"
#elif IS_SCL0(LCD_SDSS)
#error "SCL0 overlaps with LCD_SDSS!"
#endif
#undef PIN_IS_SDA0
#undef IS_SCL0
+15 -28
View File
@@ -19,35 +19,22 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Pins Debugging for LPC1768/9
*
* - NUMBER_PINS_TOTAL
* - MULTI_NAME_PAD
* - getPinByIndex(index)
* - printPinNameByIndex(index)
* - getPinIsDigitalByIndex(index)
* - digitalPinToAnalogIndex(pin)
* - getValidPinMode(pin)
* - isValidPin(pin)
* - isAnalogPin(pin)
* - digitalRead_mod(pin)
* - pwm_status(pin)
* - printPinPWM(pin)
* - printPinPort(pin)
* - printPinNumber(pin)
* - printPinAnalog(pin)
* Support routines for LPC1768
*/
/**
* Translation of routines & variables used by pinsDebug.h
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define isAnalogPin(P) (digitalPinToAnalogIndex(P) >= 0)
#define digitalRead_mod(P) extDigitalRead(P)
#define getPinByIndex(x) pin_array[x].pin
#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("P%d_%02d"), LPC176x::pin_port(P), LPC176x::pin_bit(P)); SERIAL_ECHO(buffer); }while(0)
#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(P)); SERIAL_ECHO(buffer); }while(0)
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
#define digitalRead_mod(p) extDigitalRead(p)
#define GET_ARRAY_PIN(p) pin_array[p].pin
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
@@ -55,15 +42,15 @@
#define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins
#endif
bool getValidPinMode(const pin_t pin) {
bool GET_PINMODE(const pin_t pin) {
if (!LPC176x::pin_is_valid(pin) || LPC176x::pin_adc_enabled(pin)) // Invalid pin or active analog pin
return false;
return LPC176x::gpio_direction(pin);
}
#define getPinIsDigitalByIndex(x) ((bool) pin_array[x].is_digital)
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
void printPinPort(const pin_t) {}
void printPinPWM(const pin_t) {}
void print_port(const pin_t) {}
void pwm_details(const pin_t) {}
bool pwm_status(const pin_t) { return false; }
+13 -6
View File
@@ -28,12 +28,12 @@
// spiBeginTransaction.
#endif
// Onboard SD
//#define SD_SCK_PIN P0_07
//#define SD_MISO_PIN P0_08
//#define SD_MOSI_PIN P0_09
// External SD
/** onboard SD card */
//#define SD_SCK_PIN P0_07
//#define SD_MISO_PIN P0_08
//#define SD_MOSI_PIN P0_09
//#define SD_SS_PIN P0_06
/** external */
#ifndef SD_SCK_PIN
#define SD_SCK_PIN P0_15
#endif
@@ -43,3 +43,10 @@
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN P0_18
#endif
#ifndef SD_SS_PIN
#define SD_SS_PIN P1_23
#endif
#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h
#undef SDSS
#define SDSS SD_SS_PIN
#endif
@@ -132,7 +132,7 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck
static uint8_t SPI_speed = 0;
static void u8g_sw_spi_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
#if U8G_SPI_USE_MODE_3
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864)
swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin);
#else
swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin);
@@ -160,15 +160,15 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
break;
case U8G_COM_MSG_CHIP_SELECT:
#if U8G_SPI_USE_MODE_3 // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
u8g_SetPILevel(u8g, U8G_PI_CS, LOW);
}
else {
u8g_SetPILevel(u8g, U8G_PI_CS, HIGH);
u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive
u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive
}
#else
u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val);
@@ -13,9 +13,9 @@ if pioutil.is_pio_build():
target_drive = "REARM"
import platform
current_OS = platform.system()
env = pioutil.env
current_OS = platform.system()
Import("env")
def print_error(e):
print('\nUnable to find destination disk (%s)\n' \
@@ -37,7 +37,7 @@ if pioutil.is_pio_build():
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess, string
import subprocess,string
from ctypes import windll
from pathlib import PureWindowsPath
+125
View File
@@ -0,0 +1,125 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC4078
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
#include "../../../gcode/parser.h"
DefaultSerial1 USBSerial(false, MCDCSerial0);
uint32_t MarlinHAL::adc_result = 0;
// U8glib required functions
extern "C" {
void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); }
void u8g_MicroDelay() { u8g_xMicroDelay(1); }
void u8g_10MicroDelay() { u8g_xMicroDelay(10); }
void u8g_Delay(uint16_t val) { delay(val); }
}
// return free heap space
int freeMemory() {
char stack_end;
void *heap_start = malloc(sizeof(uint32_t));
if (heap_start == 0) return 0;
uint32_t result = (uint32_t)&stack_end - (uint32_t)heap_start;
free(heap_start);
return result;
}
void MarlinHAL::reboot() { MCUCore::nvic_system_reset(); }
uint8_t MarlinHAL::get_reset_source() {
#if ENABLED(USE_WATCHDOG)
if (watchdog_timed_out()) return RST_WATCHDOG;
#endif
return RST_POWER_ON;
}
void MarlinHAL::clear_reset_source() { watchdog_clear_timeout_flag(); }
void flashFirmware(const int16_t) {
delay(500); // Give OS time to disconnect
//USB_Connect(false); // USB clear connection
delay(1000); // Give OS time to notice
hal.reboot();
}
#if ENABLED(USE_WATCHDOG)
#define WDT_TIMEOUT TERN(WATCHDOG_DURATION_8S, 8.0f, 4.0f) // 4 or 8 second timeout
void MarlinHAL::watchdog_init() {
#if ENABLED(WATCHDOG_RESET_MANUAL)
// We enable the watchdog timer, but only for the interrupt.
// Configure WDT to only trigger an interrupt
// Disable WDT interrupt (just in case, to avoid triggering it!)
NVIC_DisableIRQ(WDT_IRQn);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
__DSB();
__ISB();
// WDT defaults to trigger an interrupt
// Configure and enable WDT interrupt.
NVIC_ClearPendingIRQ(WDT_IRQn);
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
NVIC_EnableIRQ(WDT_IRQn);
#else
MCUI::watchdog_set_timeout_triggers_reset();
#endif
MCUI::watchdog_set_timeout_in_seconds(WDT_TIMEOUT);
MCUI::watchdog_enable();
}
void MarlinHAL::watchdog_refresh() {
MCUI::watchdog_feed();
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
static millis_t next_flash = millis();
if (ELAPSED(millis(), next_flash)) {
next_flash = millis() + 200;
TOGGLE(LED_PIN); // heartbeat indicator
}
#endif
}
// Timeout state
bool MarlinHAL::watchdog_timed_out() { return MCUI::watchdog_has_triggered(); }
void MarlinHAL::watchdog_clear_timeout_flag() { MCUI::watchdog_clear_timeout_flag(); }
#endif // USE_WATCHDOG
// For M42/M43, scan command line for pin code
// return index into pin map array if found and the pin is valid.
// return dval if not found or not a valid pin.
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
const uint16_t val = (uint16_t)parser.intval(code, -1), port = val / 100, pin = val % 100;
const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2;
return ind > -1 ? ind : dval;
}
#endif // TARGET_LPC4078
+276
View File
@@ -0,0 +1,276 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* HAL_LPC1768/HAL.h
* Hardware Abstraction Layer for NXP LPC1768
*/
#define CPU_32_BIT
#include <stdint.h>
#include <stdarg.h>
#include <algorithm>
#include "../shared/Marduino.h"
#include "../shared/Delay.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "MarlinSerial.h"
#include <mcu_interface.h>
// ------------------------
// Serial ports
// ------------------------
typedef ForwardSerial1Class< decltype(MCDCSerial0) > DefaultSerial1;
extern DefaultSerial1 USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#ifdef SERIAL_PORT_3
#if SERIAL_PORT_3 == -1
#define MYSERIAL3 USBSerial
#elif WITHIN(SERIAL_PORT_3, 0, 3)
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
#else
#error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL USBSerial
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL USBSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
#endif
#if HAS_DGUS_LCD
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.available()
#endif
#endif
//
// Interrupts
//
#define CRITICAL_SECTION_START() const bool irqon = !MCUCore::primask(); MCUCore::nvic_interrupts_disable()
#define CRITICAL_SECTION_END() if (irqon) MCUCore::nvic_interrupts_enable()
#define cli() noInterrupts()
#define sei() interrupts()
//
// ADC
//
#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
// (ADC_MEDIAN_FILTER_SIZE + 1) / 2 sample step delay (12 samples @ 500Hz: 24ms phase shift)
// Memory usage per ADC channel (bytes): (6 * ADC_MEDIAN_FILTER_SIZE) + 16
// 8 * ((6 * 23) + 16 ) = 1232 Bytes for 8 channels
#define ADC_LOWPASS_K_VALUE (2) // Higher values increase rise time
// Rise time sample delays for 100% signal convergence on full range step
// (1 : 13, 2 : 32, 3 : 67, 4 : 139, 5 : 281, 6 : 565, 7 : 1135, 8 : 2273)
// K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step
// Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels)
#define HAL_ADC_VREF 3.3 // ADC voltage reference
#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t
#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
//
// Pin Mapping for M42, M43, M226
//
// Test whether the pin is valid
constexpr bool VALID_PIN(const pin_t pin) {
return MCUI::pin_is_valid(pin);
}
// Get the analog index for a digital pin
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) {
return (MCUI::pin_is_valid(pin) && MCUI::pin_has_adc(pin)) ? pin : -1;
}
//
// Misc. Functions
//
#ifndef analogInputToDigitalPin
#define analogInputToDigitalPin(p) (p)
#endif
// Return the index of a pin number
constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
return MCUI::pin_index(pin);
}
// Get the pin number at the given index
constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
return MCUI::pin_index(index);
}
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
// P0.6 thru P0.9 are for the onboard SD card
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09,
// ------------------------
// Defines
// ------------------------
void flashFirmware(const int16_t);
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
// Default graphical display delays
#define CPU_ST7920_DELAY_1 600
#define CPU_ST7920_DELAY_2 750
#define CPU_ST7920_DELAY_3 750
// ------------------------
// Free Memory Accessor
// ------------------------
#pragma GCC diagnostic push
#if GCC_VERSION <= 50000
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#pragma GCC diagnostic pop
// ------------------------
// MarlinHAL Class
// ------------------------
class MarlinHAL {
public:
// Earliest possible init, before setup()
MarlinHAL() {}
static void init(); // Called early in setup()
static void init_board() {} // Called less early in setup()
static void reboot(); // Restart the firmware from 0x0
// Interrupts
static bool isr_state() { return MCUCore::primask(); }
static void isr_on() { MCUCore::nvic_interrupts_enable(); }
static void isr_off() { MCUCore::nvic_interrupts_disable(); }
static void delay_ms(const int ms) { DELAY_US(ms * 1000); }
// Watchdog
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; });
static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {});
// Tasks, called from idle()
static void idletask();
// Reset
static uint8_t get_reset_source();
static void clear_reset_source();
// Free SRAM
static int freeMemory() { return ::freeMemory(); }
//
// ADC Methods
//
using FilteredADC = MCUI::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
// Called by Temperature::init once at startup
static void adc_init() {
// Turn on and initialise ADC in burst mode
MCUI::adc_hardware.init();
MCUI::adc_hardware.burst_start();
}
// Called by Temperature::init for each sensor at startup
static void adc_enable(const pin_t pin) {
FilteredADC::enable_channel(pin);
}
// Begin ADC sampling on the given pin. Called from Temperature::isr!
static uint32_t adc_result;
static void adc_start(const pin_t pin) {
adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
}
// Is the ADC ready for reading?
static bool adc_ready() { return true; }
// The current value of the ADC register
static uint16_t adc_value() { return uint16_t(adc_result); }
/**
* Set the PWM duty cycle for the pin to the given value.
* Optionally invert the duty cycle [default = false]
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
*/
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
/**
* Set the frequency of the timer corresponding to the provided pin
* All Hardware PWM pins will run at the same frequency and
* All Software PWM pins will run at the same frequency
*/
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
};
+376
View File
@@ -0,0 +1,376 @@
// /**
// * Marlin 3D Printer Firmware
// * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
// *
// * Based on Sprinter and grbl.
// * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
// *
// * This program is free software: you can redistribute it and/or modify
// * it under the terms of the GNU General Public License as published by
// * the Free Software Foundation, either version 3 of the License, or
// * (at your option) any later version.
// *
// * This program is distributed in the hope that it will be useful,
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// * GNU General Public License for more details.
// *
// * You should have received a copy of the GNU General Public License
// * along with this program. If not, see <https://www.gnu.org/licenses/>.
// *
// */
// /**
// * Software SPI functions originally from Arduino Sd2Card Library
// * Copyright (c) 2009 by William Greiman
// */
// /**
// * For TARGET_LPC4078
// */
// /**
// * Hardware SPI and Software SPI implementations are included in this file.
// * The hardware SPI runs faster and has higher throughput but is not compatible
// * with some LCD interfaces/adapters.
// *
// * Control of the slave select pin(s) is handled by the calling routines.
// *
// * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card
// * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with
// * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is
// * active. If any of these pins are shared then the software SPI must be used.
// *
// * A more sophisticated hardware SPI can be found at the following link.
// * This implementation has not been fully debugged.
// * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
// */
#ifdef TARGET_LPC4078
#include "../../inc/MarlinConfig.h"
#include <SPI.h>
// Hardware SPI and SPIClass
#include "../shared/HAL_SPI.h"
#define LPC_SOFTWARE_SPI
// ------------------------
// Public functions
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
#include "SoftwareSPI.h"
// Software SPI
static uint8_t SPI_speed = SPI_FULL_SPEED;
static uint8_t spiTransfer(uint8_t b) {
return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiBegin() {
swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiInit(uint8_t spiRate) {
SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN);
}
uint8_t spiRec() { return spiTransfer(0xFF); }
void spiRead(uint8_t*buf, uint16_t nbyte) {
for (int i = 0; i < nbyte; i++)
buf[i] = spiTransfer(0xFF);
}
void spiSend(uint8_t b) { (void)spiTransfer(b); }
void spiSend(const uint8_t *buf, size_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++)
(void)spiTransfer(buf[i]);
}
void spiSendBlock(uint8_t token, const uint8_t *buf) {
(void)spiTransfer(token);
for (uint16_t i = 0; i < 512; i++)
(void)spiTransfer(buf[i]);
}
#else
#ifdef SD_SPI_SPEED
#define INIT_SPI_SPEED SD_SPI_SPEED
#else
#define INIT_SPI_SPEED SPI_FULL_SPEED
#endif
void spiBegin() { spiInit(INIT_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0
void spiInit(uint8_t spiRate) {
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPI.setModule(1);
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPI.setModule(2);
#endif
SPI.setDataSize(DATA_SIZE_8BIT);
SPI.setDataMode(SPI_MODE0);
SPI.setClock(SPISettings::spiRate2Clock(spiRate));
SPI.begin();
}
static uint8_t doio(uint8_t b) {
return SPI.transfer(b & 0x00FF) & 0x00FF;
}
void spiSend(uint8_t b) { doio(b); }
void spiSend(const uint8_t *buf, size_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
}
void spiSend(uint32_t chan, byte b) {}
void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {}
// Read single byte from SPI
uint8_t spiRec() { return doio(0xFF); }
uint8_t spiRec(uint32_t chan) { return 0; }
// Read from SPI into buffer
void spiRead(uint8_t *buf, uint16_t nbyte) {
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
}
uint8_t spiTransfer(uint8_t b) { return doio(b); }
// Write from buffer to SPI
void spiSendBlock(uint8_t token, const uint8_t *buf) {
(void)spiTransfer(token);
for (uint16_t i = 0; i < 512; i++)
(void)spiTransfer(buf[i]);
}
// Begin SPI transaction, set clock, bit order, data mode
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
// TODO: Implement this method
}
#endif // LPC_SOFTWARE_SPI
// /**
// * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
// */
static inline void waitSpiTxEnd(void *spi_d) {
// while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1
// while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0
}
// // Retain the pin init state of the SPI, to avoid init more than once,
// // even if more instances of SPIClass exist
static bool spiInitialised[BOARD_NR_SPI] = {};
SPIClass::SPIClass(uint8_t device) {
// // Init things specific to each SPI device
// // clock divider setup is a bit of hack, and needs to be improved at a later date.
#if BOARD_NR_SPI >= 1
_settings[0].device_id = 0;
_settings[0].m_config.pin_miso = BOARD_SPI1_MISO_PIN;
_settings[0].m_config.pin_mosi = BOARD_SPI1_MOSI_PIN;
_settings[0].m_config.pin_sck = BOARD_SPI1_SCK_PIN;
_settings[0].m_config.pin_ssel = BOARD_SPI1_NSS_PIN;
_settings[0].m_config.frequency = 100000;
_settings[0].m_config.data_bits = 8;
_settings[0].m_config.mode = 0;
_settings[0].m_config.format = MCUI::SSP::Config::Format::SPI;
// _settings[0].dataMode = SPI_MODE0;
// _settings[0].dataSize = DATA_SIZE_8BIT;
// _settings[0].clock = SPI_CLOCK_MAX;
// //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
#endif
#if BOARD_NR_SPI >= 2
_settings[1].device_id = 2;
_settings[1].m_config.pin_miso = BOARD_SPI2_MISO_PIN;
_settings[1].m_config.pin_mosi = BOARD_SPI2_MOSI_PIN;
_settings[1].m_config.pin_sck = BOARD_SPI2_SCK_PIN;
_settings[1].m_config.pin_ssel = BOARD_SPI2_NSS_PIN;
// _settings[1].dataMode = SPI_MODE0;
// _settings[1].dataSize = DATA_SIZE_8BIT;
// _settings[1].clock = SPI_CLOCK_MAX;
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
#endif
#if BOARD_NR_SPI >= 3
_settings[2].device_id = 1;
_settings[2].m_config.pin_miso = BOARD_SPI3_MISO_PIN;
_settings[2].m_config.pin_mosi = BOARD_SPI3_MOSI_PIN;
_settings[2].m_config.pin_sck = BOARD_SPI3_SCK_PIN;
_settings[2].m_config.pin_ssel = BOARD_SPI3_NSS_PIN;
// _settings[1].dataMode = SPI_MODE0;
// _settings[1].dataSize = DATA_SIZE_8BIT;
// _settings[1].clock = SPI_CLOCK_MAX;
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
#endif
setModule(device);
// // Init the GPDMA controller
// // TODO: call once in the constructor? or each time?
// GPDMA_Init();
}
SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) {
#if BOARD_NR_SPI >= 1
if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1);
#endif
#if BOARD_NR_SPI >= 2
if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
#endif
#if BOARD_NR_SPI >= 3
if (mosi == BOARD_SPI3_MOSI_PIN) SPIClass(3);
#endif
}
void SPIClass::begin() {
// // Init the SPI pins in the first begin call
if ((_currentSetting->device_id == 0 && spiInitialised[0] == false) ||
(_currentSetting->device_id == 1 && spiInitialised[1] == false) ||
(_currentSetting->device_id == 2 && spiInitialised[2] == false)) {
MCUI::SSP::init(_currentSetting->device_id, _currentSetting->m_config);
spiInitialised[_currentSetting->device_id] = true;
}
updateSettings();
}
void SPIClass::beginTransaction(const SPISettings &cfg) {
setBitOrder(cfg.bitOrder);
setDataMode(cfg.dataMode);
setDataSize(cfg.dataSize);
//setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
begin();
}
uint8_t SPIClass::transfer(const uint16_t b) {
uint16_t rx_word = 0;
// clear rx fifo
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) == 1);
MCUI::SSP::write(_currentSetting->device_id, b);
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) != 1);
return rx_word;
}
uint16_t SPIClass::transfer16(const uint16_t data) {
return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF);
}
void SPIClass::end() {
// // Neither is needed for Marlin
// //SSP_Cmd(_currentSetting->spi_d, DISABLE);
// //SSP_DeInit(_currentSetting->spi_d);
}
void SPIClass::send(uint8_t data) {
MCUI::SSP::write(_currentSetting->device_id, data);
}
void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
// //TODO: LPC dma can only write 0xFFF bytes at once.
// GPDMA_Channel_CFG_Type GPDMACfg;
// /* Configure GPDMA channel 0 -------------------------------------------------------------*/
// /* DMA Channel 0 */
// GPDMACfg.ChannelNum = 0;
// // Source memory
// GPDMACfg.SrcMemAddr = (uint32_t)buf;
// // Destination memory - Not used
// GPDMACfg.DstMemAddr = 0;
// // Transfer size
// GPDMACfg.TransferSize = length;
// // Transfer width
// GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
// // Transfer type
// GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
// // Source connection - unused
// GPDMACfg.SrcConn = 0;
// // Destination connection
// GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx;
// GPDMACfg.DMALLI = 0;
// // Enable dma on SPI
// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
// // Only increase memory if minc is true
// GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
// // Setup channel with given parameter
// GPDMA_Setup(&GPDMACfg);
// // Enable DMA
// GPDMA_ChannelCmd(0, ENABLE);
// // Wait for data transfer
// while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { }
// // Clear err and int
// GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
// GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
// // Disable DMA
// GPDMA_ChannelCmd(0, DISABLE);
// waitSpiTxEnd(_currentSetting->spi_d);
// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE);
}
uint16_t SPIClass::read() {
uint16_t rx_word = 0;
MCUI::SSP::read(_currentSetting->device_id, &rx_word);
return rx_word;
}
void SPIClass::read(uint8_t *buf, uint32_t len) {
uint16_t rx_word = 0;
// clear rx fifo
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) == 1);
for (uint16_t i = 0; i < len; i++) {
MCUI::SSP::write(_currentSetting->device_id, 0xFF);
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) != 1);
buf[i] = rx_word;
}
}
void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; }
void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed
void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
// /**
// * Set up/tear down
// */
void SPIClass::updateSettings() {
MCUI::SSP::configure(_currentSetting->device_id, _currentSetting->m_config);
}
SPIClass SPI(1);
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPIClass SPI(1);
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIClass SPI(2);
#endif
#endif // TARGET_LPC4078
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -21,27 +21,25 @@
*/
#pragma once
#include <SPI.h>
/**
* XTLW MFF V2.0 pin assignments
* Marlin currently requires 3 SPI classes:
*
* SPIClass:
* This class is normally provided by frameworks and has a semi-default interface.
* This is needed because some libraries reference it globally.
*
* SPISettings:
* Container for SPI configs for SPIClass. As above, libraries may reference it globally.
*
* These two classes are often provided by frameworks so we cannot extend them to add
* useful methods for Marlin.
*
* MarlinSPI:
* Provides the default SPIClass interface plus some Marlin goodies such as a simplified
* interface for SPI DMA transfer.
*
*/
#include "env_validate.h"
#ifndef BOARD_INFO_NAME
#define BOARD_INFO_NAME "XTLW MFF V2.0"
#endif
//
// Steppers
//
#define E2_STEP_PIN 40
#define E2_DIR_PIN 42
#define E2_ENABLE_PIN 63
//
// Heaters / Fans
//
#define FAN1_PIN 65
#define FAN2_PIN 66
#include "pins_XTLW_MFF_V1.h"
using MarlinSPI = SPIClass;
+78
View File
@@ -0,0 +1,78 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC4078
#include "MarlinSerial.h"
#include "../../inc/MarlinConfig.h"
MarlinCDCSerial MCDCSerial0;
#define MarlinSerial(ID) \
MarlinSerial _MSerial##ID(ID); \
MSerialT MSerial##ID(true, _MSerial##ID)
#if USING_HW_SERIAL0
MarlinSerial(0);
#endif
#if USING_HW_SERIAL1
MarlinSerial(1);
#endif
#if USING_HW_SERIAL2
MarlinSerial(2);
#endif
#if USING_HW_SERIAL3
MarlinSerial(3);
#endif
#if ENABLED(EMERGENCY_PARSER)
bool MarlinSerial::recv_callback(const char c) {
// Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro)
if (false) {}
#if USING_HW_SERIAL0
else if (this == &_MSerial0) emergency_parser.update(MSerial0.emergency_state, c);
#endif
#if USING_HW_SERIAL1
else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c);
#endif
#if USING_HW_SERIAL2
else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c);
#endif
#if USING_HW_SERIAL3
else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c);
#endif
return true;
}
#include "../../feature/e_parser.h"
EmergencyParser::State emergency_state;
bool CDC_RecvCallback(const char c) {
emergency_parser.update(emergency_state, c);
return true;
}
#endif
#endif // TARGET_LPC4078
+108
View File
@@ -0,0 +1,108 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <mcu_interface.h>
#include <interface/uart.h>
#include <driver/usb_cdc.h>
#include <UART.h>
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
#endif
#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
#endif
#ifndef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128
#endif
#ifndef TX_BUFFER_SIZE
#define TX_BUFFER_SIZE 32
#endif
class MarlinCDCSerial : public HardwareSerial {
public:
MarlinCDCSerial() {}
void begin(unsigned long baudrate) override {}
void begin(unsigned long baudrate, uint16_t config) override { }
void end() override { }
int available() override {
return MCUI::CDCSerial0::available();
}
int peek() override { char c = 0; return MCUI::CDCSerial0::peek((uint8_t*)&c)? c : -1; }
int read() override { char c = 0; return MCUI::CDCSerial0::read((uint8_t*)&c, 1)? c : -1; }
void flush() override {};
size_t write(uint8_t c) override { return write(&c, 1); }
size_t write(const uint8_t *buffer, size_t size) override { return MCUI::CDCSerial0::connected() ? MCUI::CDCSerial0::write(buffer, size) : 0; }
using Print::write;
operator bool() override { return true; }
};
extern MarlinCDCSerial MCDCSerial0;
class MarlinSerial : public HardwareSerial {
public:
MarlinSerial(const uint32_t uart_id) : uart_device(uart_id) {}
void begin(unsigned long baudrate) override {
uart_device.configure_pins(P0_02, P0_03);
uart_device.init({ .baud = baudrate });
#if ENABLED(EMERGENCY_PARSER)
uart_device.set_rx_callback([this](char rx_value){ return this->recv_callback(rx_value); } );
#endif
}
void begin(unsigned long baudrate, uint16_t config) override {
begin(baudrate);
}
void end() override { }
int available() override {
return uart_device.rx_available();
}
int peek() override { char c = 0; return uart_device.peek(&c)? c : -1; }
int read() override { char c = 0; return uart_device.read(&c)? c : -1; }
void flush() override {};
size_t write(uint8_t c) override { return write(&c, 1); }
size_t write(const uint8_t *buffer, size_t size) override { return uart_device.write((const char *)buffer, size); }
using Print::write; // pull in write(str) and write(buf, size) from Print
operator bool() override { return true; }
bool recv_callback(char value);
private:
MCUI::BufferedUARTC uart_device;
};
// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads
// of 'available' and 'read' method are not used in this multiple inheritance scenario.
// Instead, use a ForwardSerial here that adapts the interface.
typedef ForwardSerial1Class<MarlinSerial> MSerialT;
extern MSerialT MSerial0;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
// Consequently, we can't use a RuntimeSerial either. The workaround would be to use
// a RuntimeSerial<ForwardSerial<MarlinSerial>> type here. Ignore for now until it's actually required.
#if ENABLED(SERIAL_RUNTIME_HOOK)
#error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x."
#endif
+51
View File
@@ -0,0 +1,51 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC4078
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/MinSerial.h"
#include <debug_frmwrk.h>
static void TX(char c) { _DBC(c); }
void install_min_serial() { HAL_min_serial_out = &TX; }
#if DISABLED(DYNAMIC_VECTORTABLE)
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // TARGET_LPC4078
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -21,41 +21,35 @@
*/
#pragma once
/**
* servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
* Copyright (c) 2009 Michael Margolis. All right reserved.
*
* This library 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 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#pragma once
/**
* Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers -
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
*
* The only modification was to update/delete macros to match the LPC176x.
*/
#include <Servo.h>
#if 1
#include "../../core/millis_t.h"
// Inherit and expand on the official library
class libServo {
public:
libServo();
int8_t attach(const int pin = 0); // pin == 0 uses value from previous call
int8_t attach(const int pin, const int min, const int max);
void detach() { pico_servo.detach(); }
int read() { return pico_servo.read(); }
void move(const int value);
void pause();
void resume();
static void pause_all_servos();
static void resume_all_servos();
static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority);
private:
Servo pico_servo;
int servo_pin = 0;
millis_t delay = 0;
bool was_attached_before_pause;
int value_before_pause;
};
#else
class libServo: public Servo {
public:
void move(const int value) {
@@ -73,5 +67,3 @@ class libServo: public Servo {
class libServo;
typedef libServo hal_servo_t;
#endif
+47
View File
@@ -0,0 +1,47 @@
#ifdef TARGET_LPC4078
#include <Arduino.h>
#include "SoftwareSPI.h"
#include <mcu_interface.h>
uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
for (uint8_t i = 0; i < 8; i++) {
if (spi_speed == 0) {
MCUI::gpio_set(mosi_pin, !!(b & 0x80));
MCUI::gpio_set(sck_pin, HIGH);
b <<= 1;
if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1;
MCUI::gpio_set(sck_pin, LOW);
}
else {
const uint8_t state = (b & 0x80) ? HIGH : LOW;
for (uint8_t j = 0; j < spi_speed; j++)
MCUI::gpio_set(mosi_pin, state);
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
MCUI::gpio_set(sck_pin, HIGH);
b <<= 1;
if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1;
for (uint8_t j = 0; j < spi_speed; j++)
MCUI::gpio_set(sck_pin, LOW);
}
}
return b;
}
void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
pinMode(sck_pin, OUTPUT);
if (MCUI::pin_is_valid(miso_pin)) pinMode(miso_pin, INPUT);
pinMode(mosi_pin, OUTPUT);
}
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) {
MCUI::gpio_set(mosi_pin, HIGH);
MCUI::gpio_set(sck_pin, LOW);
return (SystemCoreClock == 120000000 ? 44 : 38) / std::pow(2, 6 - std::min(spiRate, (uint8_t)6));
}
#endif // TARGET_LPC4078
+5
View File
@@ -0,0 +1,5 @@
#include <mcu_interface.h>
uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin);
void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin);
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin);
+116
View File
@@ -0,0 +1,116 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC4078
/**
* Emulate EEPROM storage using Flash Memory
*
* Use a single 32K flash sector to store EEPROM data. To reduce the
* number of erase operations a simple "leveling" scheme is used that
* maintains a number of EEPROM "slots" within the larger flash sector.
* Each slot is used in turn and the entire sector is only erased when all
* slots have been used.
*
* A simple RAM image is used to hold the EEPROM data during I/O operations
* and this is flushed to the next available slot when an update is complete.
* If RAM usage becomes an issue we could store this image in one of the two
* 16Kb I/O buffers (intended to hold DMA USB and Ethernet data, but currently
* unused).
*/
#include "../../inc/MarlinConfig.h"
#include "../shared/eeprom_api.h"
//#include <cstdio>
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 4032 // 4KB
#endif
size_t PersistentStore::capacity() { return 4032; }
constexpr uint32_t page_size = MCUI::EEPROM::page_size;
uint32_t buffered_page = 0;
uint8_t page_buffer[page_size];
bool buffered_page_dirty = false;
bool PersistentStore::access_start() {
MCUI::EEPROM::init();
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
return true;
}
bool PersistentStore::access_finish() {
if (buffered_page_dirty) {
MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
}
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
uint32_t address = pos;
//printf("Marlin::eeprom::write(pos = %d, size = %d)\n", pos, size);
uint32_t value_index = 0;
for (uint32_t addr = address; addr < address + size; ++addr) {
uint32_t page_address = addr & 0xFFFFFFC0;
if (page_address != buffered_page) {
//printf("Marlin::eeprom::write(@%ld):: page change new(%ld) != current(%d)\n",addr, page_address, buffered_page);
if (buffered_page_dirty == true) MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
buffered_page = page_address;
buffered_page_dirty = false;
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
}
page_buffer[addr & ~0xFFFFFFC0] = value[value_index++];
buffered_page_dirty = true;
}
pos += size;
crc16(crc, value, size);
return false; // return true for any error
}
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
uint32_t address = pos;
//printf("Marlin::eeprom::read(pos = %d, size = %d, writing = %d)\n", pos, size, writing);
uint32_t value_index = 0;
for (uint32_t addr = address; addr < address + size; ++addr) {
uint32_t page_address = addr & 0xFFFFFFC0;
if (page_address != buffered_page) {
if (buffered_page_dirty) {
MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
buffered_page_dirty = false;
}
buffered_page = page_address;
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
}
if (writing) value[value_index++] = page_buffer[addr & ~0xFFFFFFC0];
else crc16(crc, &page_buffer[addr & ~0xFFFFFFC0], 1);
}
if (writing) crc16(crc, value, size);
pos += size;
return false; // return true for any error
}
#endif // TARGET_LPC4078
+191
View File
@@ -0,0 +1,191 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/**
* Endstop Interrupts
*
* Without endstop interrupts the endstop pins must be polled continually in
* the temperature-ISR via endstops.update(), most of the time finding no change.
* With this feature endstops.update() is called only when we know that at
* least one endstop has changed state, saving valuable CPU cycles.
*
* This feature only works when all used endstop pins can generate an 'external interrupt'.
*
* Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'.
* (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino)
*/
#include "../../module/endstops.h"
// One ISR for all EXT-Interrupts
void endstop_ISR() { endstops.update(); }
void setup_endstop_interrupts() {
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
#define LPC1768_PIN_INTERRUPT_M(pin) ((pin >> 0x5 & 0x7) == 0 || (pin >> 0x5 & 0x7) == 2)
#if HAS_X_MAX
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
#error "X_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(X_MAX_PIN);
#endif
#if HAS_X_MIN
#if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN)
#error "X_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(X_MIN_PIN);
#endif
#if HAS_Y_MAX
#if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN)
#error "Y_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Y_MAX_PIN);
#endif
#if HAS_Y_MIN
#if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN)
#error "Y_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Y_MIN_PIN);
#endif
#if HAS_Z_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN)
#error "Z_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MAX_PIN);
#endif
#if HAS_Z_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN)
#error "Z_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MIN_PIN);
#endif
#if HAS_Z2_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN)
#error "Z2_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z2_MAX_PIN);
#endif
#if HAS_Z2_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN)
#error "Z2_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z2_MIN_PIN);
#endif
#if HAS_Z3_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z3_MAX_PIN)
#error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z3_MAX_PIN);
#endif
#if HAS_Z3_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z3_MIN_PIN)
#error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z3_MIN_PIN);
#endif
#if HAS_Z4_MAX
#if !LPC1768_PIN_INTERRUPT_M(Z4_MAX_PIN)
#error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z4_MAX_PIN);
#endif
#if HAS_Z4_MIN
#if !LPC1768_PIN_INTERRUPT_M(Z4_MIN_PIN)
#error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z4_MIN_PIN);
#endif
#if HAS_Z_MIN_PROBE_PIN
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN)
#error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
#if HAS_I_MAX
#if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN)
#error "I_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(I_MAX_PIN);
#elif HAS_I_MIN
#if !LPC1768_PIN_INTERRUPT_M(I_MIN_PIN)
#error "I_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(I_MIN_PIN);
#endif
#if HAS_J_MAX
#if !LPC1768_PIN_INTERRUPT_M(J_MAX_PIN)
#error "J_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(J_MAX_PIN);
#elif HAS_J_MIN
#if !LPC1768_PIN_INTERRUPT_M(J_MIN_PIN)
#error "J_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(J_MIN_PIN);
#endif
#if HAS_K_MAX
#if !LPC1768_PIN_INTERRUPT_M(K_MAX_PIN)
#error "K_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(K_MAX_PIN);
#elif HAS_K_MIN
#if !LPC1768_PIN_INTERRUPT_M(K_MIN_PIN)
#error "K_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(K_MIN_PIN);
#endif
#if HAS_U_MAX
#if !LPC1768_PIN_INTERRUPT_M(U_MAX_PIN)
#error "U_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(U_MAX_PIN);
#elif HAS_U_MIN
#if !LPC1768_PIN_INTERRUPT_M(U_MIN_PIN)
#error "U_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(U_MIN_PIN);
#endif
#if HAS_V_MAX
#if !LPC1768_PIN_INTERRUPT_M(V_MAX_PIN)
#error "V_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(V_MAX_PIN);
#elif HAS_V_MIN
#if !LPC1768_PIN_INTERRUPT_M(V_MIN_PIN)
#error "V_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(V_MIN_PIN);
#endif
#if HAS_W_MAX
#if !LPC1768_PIN_INTERRUPT_M(W_MAX_PIN)
#error "W_MAX_PIN is not INTERRUPT-capable."
#endif
_ATTACH(W_MAX_PIN);
#elif HAS_W_MIN
#if !LPC1768_PIN_INTERRUPT_M(W_MIN_PIN)
#error "W_MIN_PIN is not INTERRUPT-capable."
#endif
_ATTACH(W_MIN_PIN);
#endif
}
@@ -1,6 +1,6 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
@@ -19,25 +19,19 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../platforms.h"
#ifdef TARGET_LPC4078
#ifdef __PLAT_RP2040__
#include "../../inc/MarlinConfigPre.h"
#include "HAL.h"
#include "pinDefinitions.h"
#include "../../inc/MarlinConfig.h"
#include <mcu_interface.h>
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
analogWrite(pin, v);
if (!MCUI::pin_is_valid(pin)) return;
if (MCUI::pwm_attach_pin(pin))
MCUI::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range
}
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
mbed::PwmOut* pwm = digitalPinToPwm(pin);
if (pwm != NULL) delete pwm;
pwm = new mbed::PwmOut(digitalPinToPinName(pin));
digitalPinToPwm(pin) = pwm;
pwm->period_ms(1000 / f_desired);
MCUI::pwm_set_frequency(pin, f_desired);
}
#endif // __PLAT_RP2040__
#endif // TARGET_LPC4078

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