Merge branch 'bugfix-2.0.x' into CrealityDwin2.0_Bleeding

This commit is contained in:
InsanityAutomation
2021-01-31 13:27:55 -05:00
1017 changed files with 31771 additions and 20047 deletions
+13 -17
View File
@@ -48,13 +48,13 @@ jobs:
# Extended AVR Environments
- FYSETC_F6_13
- FYSETC_F6
- mega1280
- rambo
- sanguino1284p
- sanguino644p
# Extended STM32 Environments
# STM32F1 (Maple) Environments
- STM32F103RC_btt
- STM32F103RC_btt_USB
@@ -64,37 +64,37 @@ jobs:
- STM32F103RC_meeb
- jgaurora_a5s_a1
- STM32F103VE_longer
- mks_robin
- mks_robin_lite
- mks_robin_pro
- STM32F103RET6_creality
- mks_robin_nano35
# STM32 (ST) Environments
- STM32F407VE_black
- STM32F401VE_STEVAL
- BIGTREE_BTT002
- BIGTREE_SKR_PRO
- BIGTREE_GTR_V1_0
- mks_robin
- mks_robin_stm32
- ARMED
- FYSETC_S6
- STM32F070CB_malyan
- STM32F070RB_malyan
- malyan_M300
- mks_robin_lite
- FLYF407ZG
- rumba32
- mks_robin_pro
- STM32F103RET6_creality
- LERDGEX
- mks_robin_nano35
- mks_robin_nano35_stm32
- NUCLEO_F767ZI
- REMRAM_V1
# Put lengthy tests last
- LPC1768
- LPC1769
# STM32 with non-STM framework. both broken for now. they should use HAL_STM32 which is working.
#- STM32F4
#- STM32F7
# Non-working environment tests
#- at90usb1286_cdc
#- STM32F103CB_malyan
@@ -118,8 +118,4 @@ jobs:
- name: Run ${{ matrix.test-platform }} Tests
run: |
# Inline tests script
chmod +x buildroot/bin/*
chmod +x buildroot/tests/*
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH}
run_tests . ${{ matrix.test-platform }}
make tests-single-ci TEST_TARGET=${{ matrix.test-platform }}
+15 -8
View File
@@ -19,9 +19,9 @@
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
# Our automatic versioning scheme generates the following file
# NEVER put it in the repository
# Generated files
_Version.h
bdf2u8g
#
# OS
@@ -148,7 +148,7 @@ Marlin/*/*/*/*/readme.txt
# Secure Credentials
Configuration_Secure.h
#Visual Studio
# Visual Studio
*.sln
*.vcxproj
*.vcxproj.user
@@ -159,27 +159,34 @@ __vm/
.vs/
vc-fileutils.settings
#Visual Studio Code
# Visual Studio Code
.vscode
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.vscode/*.db
#cmake
# cmake
CMakeLists.txt
src/CMakeLists.txt
CMakeListsPrivate.txt
#CLion
# CLion
cmake-build-*
#Eclipse
# Eclipse
.project
.cproject
.pydevproject
.settings
.classpath
#Python
# Python
__pycache__
# IOLogger logs
*_log.csv
# Simulation / Native
eeprom.dat
imgui.ini
+52
View File
@@ -0,0 +1,52 @@
help:
@echo "Tasks for local development:"
@echo "* tests-single-ci: Run a single test from inside the CI"
@echo "* tests-single-local: Run a single test locally"
@echo "* tests-single-local-docker: Run a single test locally, using docker-compose"
@echo "* tests-all-local: Run all tests locally"
@echo "* tests-all-local-docker: Run all tests locally, using docker-compose"
@echo "* setup-local-docker: Setup local docker-compose"
@echo ""
@echo "Options for testing:"
@echo " TEST_TARGET Set when running tests-single-*, to select the"
@echo " test. If you set it to ALL it will run all "
@echo " tests, but some of them are broken: use "
@echo " tests-all-* instead to run only the ones that "
@echo " run on GitHub CI"
@echo " ONLY_TEST Limit tests to only those that contain this, or"
@echo " the index of the test (1-based)"
@echo " VERBOSE_PLATFORMIO If you want the full PIO output, set any value"
@echo " GIT_RESET_HARD Used by CI: reset all local changes. WARNING:"
@echo " THIS WILL UNDO ANY CHANGES YOU'VE MADE!"
.PHONY: help
tests-single-ci:
export GIT_RESET_HARD=true
$(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET)
.PHONY: tests-single-ci
tests-single-local:
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local" ; return 1; fi
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& run_tests . $(TEST_TARGET) "$(ONLY_TEST)"
.PHONY: tests-single-local
tests-single-local-docker:
@if ! test -n "$(TEST_TARGET)" ; then echo "***ERROR*** Set TEST_TARGET=<your-module> or use make tests-all-local-docker" ; return 1; fi
docker-compose run --rm marlin $(MAKE) tests-single-local TEST_TARGET=$(TEST_TARGET) VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD) ONLY_TEST="$(ONLY_TEST)"
.PHONY: tests-single-local-docker
tests-all-local:
export PATH=./buildroot/bin/:./buildroot/tests/:${PATH} \
&& export VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) \
&& for TEST_TARGET in $$(./get_test_targets.py) ; do echo "Running tests for $$TEST_TARGET" ; run_tests . $$TEST_TARGET ; done
.PHONY: tests-all-local
tests-all-local-docker:
docker-compose run --rm marlin $(MAKE) tests-all-local VERBOSE_PLATFORMIO=$(VERBOSE_PLATFORMIO) GIT_RESET_HARD=$(GIT_RESET_HARD)
.PHONY: tests-all-local-docker
setup-local-docker:
docker-compose build
.PHONY: setup-local-docker
+202 -74
View File
@@ -151,6 +151,8 @@
//#define MachineCR10Orig // Forces Melzi board
//#define Melzi_To_SBoardUpgrade // Upgrade Melzi board to 10S board
//#define CrealitySilentBoard // Creality board with TMC2208 Standalone drivers. Disables Linear Advance
//#define Creality422
#define Creality427
//#define SKR13 // 32 bit board - assumes 2208 drivers
//#define SKR14
@@ -272,15 +274,15 @@
//===========================================================================
//============================= DELTA Printer ===============================
//===========================================================================
// For a Delta printer start with one of the configuration files in the
// config/examples/delta directory and customize for your machine.
// For a Delta printer, start with one of the configuration files in the config/examples/delta directory
// from https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
//
//===========================================================================
//============================= SCARA Printer ===============================
//===========================================================================
// For a SCARA printer start with the configuration files in
// config/examples/SCARA and customize for your machine.
// For a SCARA printer, start with one of the configuration files in the config/examples/SCARA directory
// from https://github.com/MarlinFirmware/Configurations/branches/all and customize for your machine.
//
// @section info
@@ -448,6 +450,10 @@
#define RET6_12864_LCD
#endif
#if ANY(Creality422, Creality427) && DISABLED(MachineEnder3V2)
#define RET6_12864_LCD
#endif
#if NONE(HotendStock, HotendE3D)
#define HotendStock
#endif
@@ -534,7 +540,7 @@
#define SERIAL_PORT_2 2
#elif ANY(SKR13, SKR14, SKR14Turbo)
#define DGUS_SERIAL_PORT 0
#elif ANY(MachineEnder3V2, MachineEnder3Pro422, MachineEnder3Pro427)
#elif ANY(MachineEnder3Pro422, MachineEnder3Pro427)&& DISABLED(MachineEnder3V2)
#define SERIAL_PORT_2 3
#endif
@@ -568,9 +574,9 @@
#define MOTHERBOARD BOARD_BTT_SKR_PRO_V1_1
#elif ENABLED(SKRMiniE3V2)
#define MOTHERBOARD BOARD_BTT_SKR_MINI_E3_V2_0
#elif ANY(MachineEnder3V2, MachineEnder3Pro422)
#elif ANY(MachineEnder3V2, MachineEnder3Pro422, Creality422) && DISABLED(Creality427)
#define MOTHERBOARD BOARD_CREALITY_V4
#elif ENABLED(MachineEnder3Pro427)
#elif ANY(MachineEnder3Pro427, Creality427)
#define MOTHERBOARD BOARD_CREALITY_V427
#elif (ENABLED(MachineCR10Orig) && DISABLED(Melzi_To_SBoardUpgrade))
#define MOTHERBOARD BOARD_MELZI_CREALITY
@@ -611,33 +617,19 @@
#endif
/**
* Průša MK2 Single Nozzle Multi-Material Multiplexer, and variants.
* Multi-Material Unit
* Set to one of these predefined models:
*
* This device allows one stepper driver on a control board to drive
* two to eight stepper motors, one at a time, in a manner suitable
* for extruders.
*
* This option only allows the multiplexer to switch on tool-change.
* Additional options to configure custom E moves are pending.
*/
//#define MK2_MULTIPLEXER
#if ENABLED(MK2_MULTIPLEXER)
// Override the default DIO selector pins here, if needed.
// Some pins files may provide defaults for these pins.
//#define E_MUX0_PIN 40 // Always Required
//#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs
//#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs
#endif
/**
* Průša Multi-Material Unit v2
* PRUSA_MMU1 : Průša MMU1 (The "multiplexer" version)
* PRUSA_MMU2 : Průša MMU2
* PRUSA_MMU2S : Průša MMU2S (Requires MK3S extruder with motion sensor, EXTRUDERS = 5)
* SMUFF_EMU_MMU2 : Technik Gegg SMUFF (Průša MMU2 emulation mode)
* SMUFF_EMU_MMU2S : Technik Gegg SMUFF (Průša MMU2S emulation mode)
*
* Requires NOZZLE_PARK_FEATURE to park print head in case MMU unit fails.
* Requires EXTRUDERS = 5
*
* For additional configuration see Configuration_adv.h
* See additional options in Configuration_adv.h.
*/
//#define PRUSA_MMU2
//#define MMU_MODEL PRUSA_MMU2
// A dual extruder that uses a single stepper motor
//#define SWITCHING_EXTRUDER
@@ -806,9 +798,10 @@
#define AUTO_POWER_E_FANS
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
//#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU over this temperature
#define POWER_TIMEOUT 30
//#define AUTO_POWER_E_TEMP 50 // (°C) Turn on PSU if any extruder is over this temperature
//#define AUTO_POWER_CHAMBER_TEMP 30 // (°C) Turn on PSU if the chamber is over this temperature
#define POWER_TIMEOUT 30 // (s) Turn off power if the machine is idle for this duration
//#define POWER_OFF_DELAY 60 // (s) Delay of poweroff after M81 command. Useful to let fans run for extra time.
#endif
#endif
@@ -850,8 +843,10 @@
* 13 : 100k Hisens 3950 1% up to 300°C for hotend "Simple ONE " & "Hotend "All In ONE"
* 15 : 100k thermistor calibration for JGAurora A5 hotend
* 18 : ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327
* 20 : Pt100 with circuit in the Ultimainboard V2.x with 5v excitation (AVR)
* 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v excitation (STM32 \ LPC176x....)
* 20 : Pt100 with circuit in the Ultimainboard V2.x with mainboard ADC reference voltage = INA826 amplifier-board supply voltage.
* NOTES: (1) Must use an ADC input with no pullup. (2) Some INA826 amplifiers are unreliable at 3.3V so consider using sensor 147, 110, or 21.
* 21 : Pt100 with circuit in the Ultimainboard V2.x with 3.3v ADC reference voltage (STM32, LPC176x....) and 5V INA826 amplifier board supply.
* NOTE: ADC pins are not 5V tolerant. Not recommended because it's possible to damage the CPU by going over 500°C.
* 22 : 100k (hotend) with 4.7k pullup to 3.3V and 220R to analog input (as in GTM32 Pro vB)
* 23 : 100k (bed) with 4.7k pullup to 3.3v and 220R to analog input (as in GTM32 Pro vB)
* 30 : Kis3d Silicone heating mat 200W/300W with 6mm precision cast plate (EN AW 5083) NTC100K / B3950 (4.7k pullup)
@@ -921,14 +916,14 @@
#endif
// Dummy thermistor constant temperature readings, for use with 998 and 999
#define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_998_VALUE 25
#define DUMMY_THERMISTOR_999_VALUE 100
// Resistor values when using a MAX31865 (sensor -5)
// Sensor value is typically 100 (PT100) or 1000 (PT1000)
// Calibration value is typically 430 ohm for AdaFruit PT100 modules and 4300 ohm for AdaFruit PT1000 modules.
//#define MAX31865_SENSOR_OHMS 100
//#define MAX31865_CALIBRATION_OHMS 430
// Resistor values when using MAX31865 sensors (-5) on TEMP_SENSOR_0 / 1
//#define MAX31865_SENSOR_OHMS_0 100 // (Ω) Typically 100 or 1000 (PT100 or PT1000)
//#define MAX31865_CALIBRATION_OHMS_0 430 // (Ω) Typically 430 for AdaFruit PT100; 4300 for AdaFruit PT1000
//#define MAX31865_SENSOR_OHMS_1 100
//#define MAX31865_CALIBRATION_OHMS_1 430
// Use temp sensor 1 as a redundant sensor with sensor 0. If the readings
// from the two sensors differ too much the print will be aborted.
@@ -1636,11 +1631,6 @@
#define BLTOUCH
#endif
/**
* Pressure sensor with a BLTouch-like interface
*/
//#define CREALITY_TOUCH
/**
* Touch-MI Probe by hotends.fr
*
@@ -1704,7 +1694,20 @@
/**
* Z Probe to nozzle (X,Y) offset, relative to (0, 0).
*
* In the following example the X and Y offsets are both positive:
* X and Y offset
* Use a caliper or ruler to measure the distance from the tip of
* the Nozzle to the center-point of the Probe in the X and Y axes.
*
* Z offset
* - For the Z offset use your best known value and adjust at runtime.
* - Common probes trigger below the nozzle and have negative values for Z offset.
* - Probes triggering above the nozzle height are uncommon but do exist. When using
* probes such as this, carefully set Z_CLEARANCE_DEPLOY_PROBE and Z_CLEARANCE_BETWEEN_PROBES
* to avoid collisions during probing.
*
* Tune and Adjust
* - Probe Offsets can be tuned at runtime with 'M851', LCD menus, babystepping, etc.
* - PROBE_OFFSET_WIZARD (configuration_adv.h) can be used for setting the Z offset.
*
* #define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
*
@@ -1774,11 +1777,38 @@
#define XY_PROBE_SPEED 10000
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
#define Z_PROBE_SPEED_FAST HOMING_FEEDRATE_Z
#define Z_PROBE_SPEED_FAST (4*60)
// Feedrate (mm/min) for the "accurate" probe of each point
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST)
/**
* Probe Activation Switch
* A switch indicating proper deployment, or an optical
* switch triggered when the carriage is near the bed.
*/
//#define PROBE_ACTIVATION_SWITCH
#if ENABLED(PROBE_ACTIVATION_SWITCH)
#define PROBE_ACTIVATION_SWITCH_STATE LOW // State indicating probe is active
//#define PROBE_ACTIVATION_SWITCH_PIN PC6 // Override default pin
#endif
/**
* Tare Probe (determine zero-point) prior to each probe.
* Useful for a strain gauge or piezo sensor that needs to factor out
* elements such as cables pulling on the carriage.
*/
//#define PROBE_TARE
#if ENABLED(PROBE_TARE)
#define PROBE_TARE_TIME 200 // (ms) Time to hold tare pin
#define PROBE_TARE_DELAY 200 // (ms) Delay after tare before
#define PROBE_TARE_STATE HIGH // State to write pin for tare
//#define PROBE_TARE_PIN PA5 // Override default pin
#if ENABLED(PROBE_ACTIVATION_SWITCH)
//#define PROBE_TARE_ONLY_WHILE_INACTIVE // Fail to tare/probe if PROBE_ACTIVATION_SWITCH is active
#endif
#endif
/**
* Multiple Probing
*
@@ -1852,6 +1882,13 @@
//#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing
//#define DELAY_BEFORE_PROBING 200 // (ms) To prevent vibrations from triggering piezo sensors
// Require minimum nozzle and/or bed temperature for probing
//#define PREHEAT_BEFORE_PROBING
#if ENABLED(PREHEAT_BEFORE_PROBING)
#define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
#define PROBING_BED_TEMP 50
#endif
// For Inverting Stepper Enable Pins (Active Low) use 0, Non Inverting (Active High) use 1
// :{ 0:'Low', 1:'High' }
#define X_ENABLE_ON 0
@@ -1933,7 +1970,9 @@
// @section homing
//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed
//#define NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed. Also enable HOME_AFTER_DEACTIVATE for extra safety.
//#define HOME_AFTER_DEACTIVATE // Require rehoming after steppers are deactivated. Also enable NO_MOTION_BEFORE_HOMING for extra safety.
//#define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off.
//#define UNKNOWN_Z_NO_RAISE // Don't raise Z (lower the bed) if Z is "unknown." For beds that fall when Z is powered off.
#if ANY(MachineEnder5)
@@ -2155,6 +2194,39 @@
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
// Override individually if the runout sensors vary
//#define FIL_RUNOUT1_STATE LOW
//#define FIL_RUNOUT1_PULLUP
//#define FIL_RUNOUT1_PULLDOWN
//#define FIL_RUNOUT2_STATE LOW
//#define FIL_RUNOUT2_PULLUP
//#define FIL_RUNOUT2_PULLDOWN
//#define FIL_RUNOUT3_STATE LOW
//#define FIL_RUNOUT3_PULLUP
//#define FIL_RUNOUT3_PULLDOWN
//#define FIL_RUNOUT4_STATE LOW
//#define FIL_RUNOUT4_PULLUP
//#define FIL_RUNOUT4_PULLDOWN
//#define FIL_RUNOUT5_STATE LOW
//#define FIL_RUNOUT5_PULLUP
//#define FIL_RUNOUT5_PULLDOWN
//#define FIL_RUNOUT6_STATE LOW
//#define FIL_RUNOUT6_PULLUP
//#define FIL_RUNOUT6_PULLDOWN
//#define FIL_RUNOUT7_STATE LOW
//#define FIL_RUNOUT7_PULLUP
//#define FIL_RUNOUT7_PULLDOWN
//#define FIL_RUNOUT8_STATE LOW
//#define FIL_RUNOUT8_PULLUP
//#define FIL_RUNOUT8_PULLDOWN
// Set one or more commands to execute on filament runout.
// (After 'M412 H' Marlin will ask the host to handle the process.)
#define FILAMENT_RUNOUT_SCRIPT "M600"
@@ -2230,10 +2302,21 @@
#define MESH_BED_LEVELING
#endif
/**
* Normally G28 leaves leveling disabled on completion. Enable
* this option to have G28 restore the prior leveling state.
* Normally G28 leaves leveling disabled on completion. Enable one of
* these options to restore the prior leveling state or to always enable
* leveling immediately after G28.
*/
#define RESTORE_LEVELING_AFTER_G28
//#define ENABLE_LEVELING_AFTER_G28
/**
* Auto-leveling needs preheating
*/
//#define PREHEAT_BEFORE_LEVELING
#if ENABLED(PREHEAT_BEFORE_LEVELING)
#define LEVELING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
#define LEVELING_BED_TEMP 50
#endif
/**
* Enable detailed logging of G28, G29, M48, etc.
@@ -2248,6 +2331,9 @@
// The height can be set with M420 Z<height>
#if NONE(MachineCR10Orig, SKRMiniE3V2)
#define ENABLE_LEVELING_FADE_HEIGHT
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
#define DEFAULT_LEVELING_FADE_HEIGHT 0.0 // (mm) Default fade height.
#endif
#endif
// For Cartesian machines, instead of dividing moves on mesh boundaries,
@@ -2266,10 +2352,11 @@
#endif
#if ENABLED(G26_MESH_VALIDATION)
#define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle.
#define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for the G26 Mesh Validation Tool.
#define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for the G26 Mesh Validation Tool.
#define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for the G26 Mesh Validation Tool.
#define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for XY Moves for the G26 Mesh Validation Tool.
#define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26.
#define MESH_TEST_HOTEND_TEMP 205 // (°C) Default nozzle temperature for G26.
#define MESH_TEST_BED_TEMP 60 // (°C) Default bed temperature for G26.
#define G26_XY_FEEDRATE 20 // (mm/s) Feedrate for G26 XY moves.
#define G26_XY_FEEDRATE_TRAVEL 100 // (mm/s) Feedrate for G26 XY travel moves.
#define G26_RETRACT_MULTIPLIER 1.0 // G26 Q (retraction) used by default between mesh test elements.
#endif
@@ -2377,6 +2464,31 @@
#define LEVEL_CORNERS_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
#define LEVEL_CORNERS_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
#define LEVEL_CENTER_TOO // Move to the center after the last corner
//#define LEVEL_CORNERS_USE_PROBE
#if ENABLED(LEVEL_CORNERS_USE_PROBE)
#define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
#define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
//#define LEVEL_CORNERS_AUDIO_FEEDBACK
#endif
/**
* Corner Leveling Order
*
* Set 2 or 4 points. When 2 points are given, the 3rd is the center of the opposite edge.
*
* LF Left-Front RF Right-Front
* LB Left-Back RB Right-Back
*
* Examples:
*
* Default {LF,RB,LB,RF} {LF,RF} {LB,LF}
* LB --------- RB LB --------- RB LB --------- RB LB --------- RB
* | 4 3 | | 3 2 | | <3> | | 1 |
* | | | | | | | <3>|
* | 1 2 | | 1 4 | | 1 2 | | 2 |
* LF --------- RF LF --------- RF LF --------- RF LF --------- RF
*/
#define LEVEL_CORNERS_LEVELING_ORDER { LF, RF, RB, LB }
#endif
/**
@@ -2415,8 +2527,7 @@
#endif
// Homing speeds (mm/min)
#define HOMING_FEEDRATE_XY (50*60)
#define HOMING_FEEDRATE_Z (4*60)
#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) }
// Validate that endstops are triggered on homing moves
#define VALIDATE_HOMING_ENDSTOPS
@@ -2635,6 +2746,10 @@
// For a purge/clean station mounted on the X axis
//#define NOZZLE_CLEAN_NO_Y
// Require a minimum hotend temperature for cleaning
#define NOZZLE_CLEAN_MIN_TEMP 170
//#define NOZZLE_CLEAN_HEATUP // Heat up the nozzle instead of skipping wipe
// Explicit wipe G-code script applies to a G12 with no arguments.
//#define WIPE_SEQUENCE_COMMANDS "G1 X-17 Y25 Z10 F4000\nG1 Z1\nM114\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 X-17 Y25\nG1 X-17 Y95\nG1 Z15\nM400\nG0 X-10.0 Y-9.0"
@@ -2672,6 +2787,9 @@
*/
#if NONE(MachineCR10Orig, LowMemoryBoard, SKRMiniE3V2)
#define PRINTCOUNTER
#if ENABLED(PRINTCOUNTER)
#define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print
#endif
#endif
/**
@@ -2749,9 +2867,9 @@
* Select the language to display on the LCD. These languages are available:
*
* en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, hu, it,
* jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
* jp_kana, ko_KR, nl, pl, pt, pt_br, ro, ru, sk, sv, tr, uk, vi, zh_CN, zh_TW
*
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'hu':'Hungarian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ro':'Romanian', 'ru':'Russian', 'sk':'Slovak', 'sv':'Swedish', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)' }
*/
#define LCD_LANGUAGE en
@@ -2799,16 +2917,6 @@
#define SDIO_SUPPORT
#endif
/**
* SD CARD: SPI SPEED
*
* Enable one of the following items for a slower SPI transfer speed.
* This may be required to resolve "volume init" errors.
*/
//#define SPI_SPEED SPI_HALF_SPEED
//#define SPI_SPEED SPI_QUARTER_SPEED
//#define SPI_SPEED SPI_EIGHTH_SPEED
/**
* SD CARD: ENABLE CRC
*
@@ -3174,9 +3282,10 @@
//
// Anet 128x64 full graphics lcd with rotary encoder as used on Anet A6
// A clone of the RepRapDiscount full graphics display but with
// different pins/wiring (see pins_ANET_10.h).
// different pins/wiring (see pins_ANET_10.h). Enable one of these.
//
//#define ANET_FULL_GRAPHICS_LCD
//#define ANET_FULL_GRAPHICS_LCD_ALT_WIRING
//
// AZSMZ 12864 LCD with SD
@@ -3358,6 +3467,16 @@
//
//#define LONGER_LK_TFT28
//
// 320x240, 2.8", FSMC Stock Display from ET4
//
//#define ANET_ET4_TFT28
//
// 480x320, 3.5", FSMC Stock Display from ET5
//
//#define ANET_ET5_TFT35
//
// Generic TFT with detailed options
//
@@ -3390,6 +3509,10 @@
//#define TFT_COLOR_UI
//#define TFT_LVGL_UI
#if ENABLED(TFT_LVGL_UI)
//#define MKS_WIFI_MODULE // MKS WiFi module
#endif
/**
* TFT Rotation. Set to one of the following values:
*
@@ -3419,10 +3542,15 @@
#define TOUCH_SCREEN_CALIBRATION
//#define XPT2046_X_CALIBRATION 12316
//#define XPT2046_Y_CALIBRATION -8981
//#define XPT2046_X_OFFSET -43
//#define XPT2046_Y_OFFSET 257
//#define TOUCH_CALIBRATION_X 12316
//#define TOUCH_CALIBRATION_Y -8981
//#define TOUCH_OFFSET_X -43
//#define TOUCH_OFFSET_Y 257
//#define TOUCH_ORIENTATION TOUCH_LANDSCAPE
#if ENABLED(TFT_COLOR_UI)
//#define SINGLE_TOUCH_NAVIGATION
#endif
#endif
//
+173 -83
View File
@@ -163,7 +163,7 @@
#if ENABLED(CHAMBER_VENT)
#define CHAMBER_VENT_SERVO_NR 1 // Index of the vent servo
#define HIGH_EXCESS_HEAT_LIMIT 5 // How much above target temp to consider there is excess heat in the chamber
#define LOW_EXCESS_HEAT_LIMIT 3
#define LOW_EXCESS_HEAT_LIMIT 3
#define MIN_COOLING_SLOPE_TIME_CHAMBER_VENT 20
#define MIN_COOLING_SLOPE_DEG_CHAMBER_VENT 1.5
#endif
@@ -305,8 +305,8 @@
// DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly.
#define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf
#define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
#define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
#define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
#define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
#define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED)
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
@@ -582,7 +582,7 @@
//#define X_DUAL_STEPPER_DRIVERS
#if ENABLED(X_DUAL_STEPPER_DRIVERS)
#define INVERT_X2_VS_X_DIR true // Set 'true' if X motors should rotate in opposite directions
//#define INVERT_X2_VS_X_DIR // Enable if X2 direction signal is opposite to X
//#define X_DUAL_ENDSTOPS
#if ENABLED(X_DUAL_ENDSTOPS)
#define X2_USE_ENDSTOP _XMAX_
@@ -592,7 +592,7 @@
//#define Y_DUAL_STEPPER_DRIVERS
#if ENABLED(Y_DUAL_STEPPER_DRIVERS)
#define INVERT_Y2_VS_Y_DIR true // Set 'true' if Y motors should rotate in opposite directions
//#define INVERT_Y2_VS_Y_DIR // Enable if Y2 direction signal is opposite to Y
//#define Y_DUAL_ENDSTOPS
#if ENABLED(Y_DUAL_ENDSTOPS)
#define Y2_USE_ENDSTOP _YMAX_
@@ -609,6 +609,11 @@
#define NUM_Z_STEPPER_DRIVERS 1 // (1-4) Z options change based on how many
#endif
#if NUM_Z_STEPPER_DRIVERS > 1
// Enable if Z motor direction signals are the opposite of Z1
//#define INVERT_Z2_VS_Z_DIR
//#define INVERT_Z3_VS_Z_DIR
//#define INVERT_Z4_VS_Z_DIR
//#define Z_MULTI_ENDSTOPS
#if ENABLED(Z_MULTI_ENDSTOPS)
#define Z2_USE_ENDSTOP _XMAX_
@@ -670,6 +675,9 @@
// Default x offset in duplication mode (typically set to half print bed width)
#define DEFAULT_DUPLICATION_X_OFFSET 100
// Default action to execute following M605 mode change commands. Typically G28X to apply new mode.
//#define EVENT_GCODE_IDEX_AFTER_MODECHANGE "G28X"
#endif
// Activate a solenoid on the active extruder with M380. Disable all with M381.
@@ -694,6 +702,7 @@
#define QUICK_HOME // If G28 contains XY do a diagonal move first
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
//#define HOME_Z_FIRST // Home Z first. Requires a Z-MIN endstop (not a probe).
//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first
// @section bltouch
@@ -836,10 +845,10 @@
//#define ASSISTED_TRAMMING
#if ENABLED(ASSISTED_TRAMMING)
// Define positions for probing points, use the hotend as reference not the sensor.
#define TRAMMING_POINT_XY { { 20, 20 }, { 200, 20 }, { 200, 200 }, { 20, 200 } }
// Define positions for probe points.
#define TRAMMING_POINT_XY { { 20, 20 }, { 180, 20 }, { 180, 180 }, { 20, 180 } }
// Define positions names for probing points.
// Define position names for probe points.
#define TRAMMING_POINT_NAME_1 "Front-Left"
#define TRAMMING_POINT_NAME_2 "Front-Right"
#define TRAMMING_POINT_NAME_3 "Back-Right"
@@ -847,7 +856,10 @@
#define RESTORE_LEVELING_AFTER_G35 // Enable to restore leveling setup after operation
//#define REPORT_TRAMMING_MM // Report Z deviation (mm) for each point relative to the first
//#define ASSISTED_TRAMMING_MENU_ITEM // Add a menu item for Assisted Tramming
//#define ASSISTED_TRAMMING_WIZARD // Add a Tramming Wizard to the LCD menu
//#define ASSISTED_TRAMMING_WAIT_POSITION { X_CENTER, Y_CENTER, 30 } // Move the nozzle out of the way for adjustment
/**
* Screw thread:
@@ -1066,7 +1078,7 @@
/**
* I2C-based DIGIPOTs (e.g., Azteeg X3 Pro)
*/
//#define DIGIPOT_MCP4018 // Requires https://github.com/stawel/SlowSoftI2CMaster
//#define DIGIPOT_MCP4018 // Requires https://github.com/felias-fogg/SlowSoftI2CMaster
//#define DIGIPOT_MCP4451
#if EITHER(DIGIPOT_MCP4018, DIGIPOT_MCP4451)
#define DIGIPOT_I2C_NUM_CHANNELS 8 // 5DPRINT:4 AZTEEG_X3_PRO:8 MKS_SBASE:5 MIGHTYBOARD_REVE:5
@@ -1099,7 +1111,7 @@
#if EITHER(IS_ULTIPANEL, EXTENSIBLE_UI)
#define MANUAL_FEEDRATE { 50*60, 50*60, 4*60, 2*60 } // (mm/min) Feedrates for manual moves along X, Y, Z, E from panel
#define SHORT_MANUAL_Z_MOVE 0.025 // (mm) Smallest manual Z move (< 0.1mm)
#define FINE_MANUAL_MOVE 0.025 // (mm) Smallest manual move (< 0.1mm) applying to Z on most machines
#if IS_ULTIPANEL
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen
@@ -1127,7 +1139,15 @@
#if HAS_BED_PROBE
//#define PROBE_OFFSET_WIZARD
#if ENABLED(PROBE_OFFSET_WIZARD)
#define PROBE_OFFSET_START -4.0 // Estimated nozzle-to-probe Z offset, plus a little extra
//
// Enable to init the Probe Z-Offset when starting the Wizard.
// Use a height slightly above the estimated nozzle-to-probe Z offset.
// For example, with an offset of -5, consider a starting height of -4.
//
//#define PROBE_OFFSET_WIZARD_START_Z -4.0
// Set a convenient position to do the calibration (probing point and nozzle/bed-distance)
//#define PROBE_OFFSET_WIZARD_XY_POS { X_CENTER, Y_CENTER }
#endif
#endif
@@ -1173,36 +1193,40 @@
#endif // HAS_LCD_MENU
// Scroll a longer status message into view
#if NONE(MachineCR10Orig, LowMemoryBoard, SKRMiniE3V2)
#define STATUS_MESSAGE_SCROLLING
// On the Info Screen, display XY with one decimal place when possible
#define LCD_DECIMAL_SMALL_XY
#if HAS_DISPLAY
// The timeout (in ms) to return to the status screen from sub-menus
#define LCD_TIMEOUT_TO_STATUS 15000
// Add an 'M73' G-code to set the current percentage
#if NONE(MachineEnder4, MachineEnder3V2) || ENABLED(GraphicLCD)
#define LCD_SET_PROGRESS_MANUALLY
#if ENABLED(SHOW_BOOTSCREEN)
#define BOOTSCREEN_TIMEOUT 4000 // (ms) Total Duration to display the boot screen(s)
#if EITHER(HAS_MARLINUI_U8GLIB, TFT_COLOR_UI)
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
#endif
#endif
#endif
// Show the E position (filament used) during printing
//#define LCD_SHOW_E_TOTAL
#if ENABLED(SHOW_BOOTSCREEN)
#define BOOTSCREEN_TIMEOUT 2000 // (ms) Total Duration to display the boot screen(s)
#if NONE(MachineCR10Orig, LowMemoryBoard, SKRMiniE3V2)
// Scroll a longer status message into view
#define STATUS_MESSAGE_SCROLLING
#endif
// On the Info Screen, display XY with one decimal place when possible
//#define LCD_DECIMAL_SMALL_XY
// Add an 'M73' G-code to set the current percentage
#define LCD_SET_PROGRESS_MANUALLY
// Show the E position (filament used) during printing
//#define LCD_SHOW_E_TOTAL
#endif
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL)
#if EITHER(SDSUPPORT, LCD_SET_PROGRESS_MANUALLY) && ANY(HAS_MARLINUI_U8GLIB, HAS_MARLINUI_HD44780, IS_TFTGLCD_PANEL, EXTENSIBLE_UI)
//#define SHOW_REMAINING_TIME // Display estimated time to completion
#if ENABLED(SHOW_REMAINING_TIME)
//#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
//#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
#endif
#if HAS_MARLINUI_U8GLIB
#if EITHER(HAS_MARLINUI_U8GLIB, EXTENSIBLE_UI)
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
#endif
@@ -1219,6 +1243,16 @@
#endif
#if ENABLED(SDSUPPORT)
/**
* SD Card SPI Speed
* May be required to resolve "volume init" errors.
*
* Enable and set to SPI_HALF_SPEED, SPI_QUARTER_SPEED, or SPI_EIGHTH_SPEED
* otherwise full speed will be applied.
*
* :['SPI_HALF_SPEED', 'SPI_QUARTER_SPEED', 'SPI_EIGHTH_SPEED']
*/
//#define SD_SPI_SPEED SPI_HALF_SPEED
// The standard SD detect circuit reads LOW when media is inserted and HIGH when empty.
// Enable this option and set to HIGH if your SD cards are incorrectly detected.
@@ -1226,8 +1260,11 @@
#define SD_DETECT_STATE HIGH
#endif
//#define SD_IGNORE_AT_STARTUP // Don't mount the SD card when starting up
//#define SDCARD_READONLY // Read-only SD card (to save over 2K of flash)
//#define GCODE_REPEAT_MARKERS // Enable G-code M808 to set repeat markers and do looping
#define SD_PROCEDURE_DEPTH 1 // Increase if you need more nested M32 calls
#define SD_FINISHED_STEPPERRELEASE true // Disable steppers when SD Print is finished
@@ -1238,11 +1275,15 @@
#if NONE(MachineCR10Orig, LowMemoryBoard, SKRMiniE3V2)
#define SDCARD_RATHERRECENTFIRST
#define SD_MENU_CONFIRM_START // Confirm the selected SD file before printing
#endif
//#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files
#define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on Stop Print (e.g., "G28XY" or "G27")
#endif
//#define NO_SD_AUTOSTART // Remove auto#.g file support completely to save some Flash, SRAM
//#define MENU_ADDAUTOSTART // Add a menu option to run auto#.g files
//#define BROWSE_MEDIA_ON_INSERT // Open the file browser when media is inserted
#define EVENT_GCODE_SD_ABORT "G28XY" // G-code to run on SD Abort Print (e.g., "G28XY" or "G27")
#if ENABLED(PRINTER_EVENT_LEDS)
#define PE_LEDS_COMPLETED_TIME (30*60) // (seconds) Time to keep the LED "done" color before restoring normal illumination
@@ -1267,7 +1308,8 @@
#endif
//#define POWER_LOSS_PIN 44 // Pin to detect power loss
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
//#define POWER_LOSS_PULL // Set pullup / pulldown as appropriate
//#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor
//#define POWER_LOSS_PULLDOWN
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power.
@@ -1314,6 +1356,13 @@
// Note: Only affects SCROLL_LONG_FILENAMES with SDSORT_CACHE_NAMES but not SDSORT_DYNAMIC_RAM.
#endif
// Allow international symbols in long filenames. To display correctly, the
// LCD's font must contain the characters. Check your selected LCD language.
//#define UTF_FILENAME_SUPPORT
// This allows hosts to request long names for files and folders with M33
//#define LONG_FILENAME_HOST_SUPPORT
// Enable this option to scroll long filenames in the SD card menu
#if NONE(MachineCR10Orig, LowMemoryBoard, SKRMiniE3V2)
// This allows hosts to request long names for files and folders with M33
@@ -1361,9 +1410,6 @@
*/
//#define USB_FLASH_DRIVE_SUPPORT
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
/**
* USB Host Shield Library
*
@@ -1374,7 +1420,18 @@
* is less tested and is known to interfere with Servos.
* [1] This requires USB_INTR_PIN to be interrupt-capable.
*/
//#define USE_UHS2_USB
//#define USE_UHS3_USB
/**
* Native USB Host supported by some boards (USB OTG)
*/
//#define USE_OTG_USB_HOST
#if DISABLED(USE_OTG_USB_HOST)
#define USB_CS_PIN SDSS
#define USB_INTR_PIN SD_DETECT_PIN
#endif
#endif
/**
@@ -1400,7 +1457,7 @@
* Set this option to one of the following (or the board's defaults apply):
*
* LCD - Use the SD drive in the external LCD controller.
* ONBOARD - Use the SD drive on the control board. (No SD_DETECT_PIN. M21 to init.)
* ONBOARD - Use the SD drive on the control board.
* CUSTOM_CABLE - Use a custom cable to access the SD (as defined in a pins file).
*
* :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ]
@@ -1409,6 +1466,9 @@
#define SDCARD_CONNECTION ONBOARD
#endif
// Enable if SD detect is rendered useless (e.g., by using an SD extender)
//#define NO_SD_DETECT
#endif // SDSUPPORT
/**
@@ -1549,6 +1609,19 @@
#endif
#endif // HAS_DGUS_LCD
//
// Specify additional languages for the UI. Default specified by LCD_LANGUAGE.
//
#if EITHER(DOGLCD, TOUCH_UI_FTDI_EVE)
//#define LCD_LANGUAGE_2 fr
//#define LCD_LANGUAGE_3 de
//#define LCD_LANGUAGE_4 es
//#define LCD_LANGUAGE_5 it
#ifdef LCD_LANGUAGE_2
//#define LCD_LANGUAGE_AUTO_SAVE // Automatically save language to EEPROM on change
#endif
#endif
//
// Touch UI for the FTDI Embedded Video Engine (EVE)
//
@@ -1616,18 +1689,14 @@
//#define TOUCH_UI_UTF8_FRACTIONS // ¼ ½ ¾
//#define TOUCH_UI_UTF8_SYMBOLS // µ ¶ ¦ § ¬
#endif
// Cyrillic character set, costs about 27KiB of flash
//#define TOUCH_UI_UTF8_CYRILLIC_CHARSET
#endif
// Use a smaller font when labels don't fit buttons
#define TOUCH_UI_FIT_TEXT
// Allow language selection from menu at run-time (otherwise use LCD_LANGUAGE)
//#define LCD_LANGUAGE_1 en
//#define LCD_LANGUAGE_2 fr
//#define LCD_LANGUAGE_3 de
//#define LCD_LANGUAGE_4 es
//#define LCD_LANGUAGE_5 it
// Use a numeric passcode for "Screen lock" keypad.
// (recommended for smaller displays)
//#define TOUCH_UI_PASSCODE
@@ -1795,6 +1864,10 @@
//#define MESH_MAX_Y Y_BED_SIZE - (MESH_INSET)
#endif
#if BOTH(AUTO_BED_LEVELING_UBL, EEPROM_SETTINGS)
//#define OPTIMIZED_MESH_STORAGE // Store mesh with less precision to save EEPROM space
#endif
/**
* Repeatedly attempt G29 leveling until it succeeds.
* Stop after G29_MAX_RETRIES attempts.
@@ -2096,21 +2169,21 @@
#define FWRETRACT
#endif
#if ENABLED(FWRETRACT)
#define FWRETRACT_AUTORETRACT // Override slicer retractions
#define FWRETRACT_AUTORETRACT // Override slicer retractions
#if ENABLED(FWRETRACT_AUTORETRACT)
#define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length
#define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length
#define MIN_AUTORETRACT 0.1 // (mm) Don't convert E moves under this length
#define MAX_AUTORETRACT 10.0 // (mm) Don't convert E moves over this length
#endif
#define RETRACT_LENGTH 3 // (mm) Default retract length (positive value)
#define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value)
#define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting
#define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise
#define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover)
#define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange)
#define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction
#define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction
#define RETRACT_LENGTH 3 // (mm) Default retract length (positive value)
#define RETRACT_LENGTH_SWAP 13 // (mm) Default swap retract length (positive value)
#define RETRACT_FEEDRATE 45 // (mm/s) Default feedrate for retracting
#define RETRACT_ZRAISE 0 // (mm) Default retract Z-raise
#define RETRACT_RECOVER_LENGTH 0 // (mm) Default additional recover length (added to retract length on recover)
#define RETRACT_RECOVER_LENGTH_SWAP 0 // (mm) Default additional swap recover length (added to retract length on recover from toolchange)
#define RETRACT_RECOVER_FEEDRATE 8 // (mm/s) Default feedrate for recovering from retraction
#define RETRACT_RECOVER_FEEDRATE_SWAP 8 // (mm/s) Default feedrate for recovering from swap retraction
#if ENABLED(MIXING_EXTRUDER)
//#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously
//#define RETRACT_SYNC_MIXING // Retract and restore all mixing steppers simultaneously
#endif
#endif
@@ -3139,6 +3212,10 @@
#define SPEED_POWER_MAX 100 // (%) 0-100
#define SPEED_POWER_STARTUP 80 // (%) M3/M4 speed/power default (with no arguments)
// Define the minimum and maximum test pulse time values for a laser test fire function
#define LASER_TEST_PULSE_MIN 1 // Used with Laser Control Menu
#define LASER_TEST_PULSE_MAX 999 // Caution: Menu may not show more than 3 characters
/**
* Enable inline laser power to be handled in the planner / stepper routines.
* Inline power is specified by the I (inline) flag in an M3 command (e.g., M3 S20 I)
@@ -3377,6 +3454,8 @@
//#define GCODE_QUOTED_STRINGS // Support for quoted string parameters
#endif
//#define MEATPACK // Support for MeatPack G-code compression (https://github.com/scottmudge/OctoPrint-MeatPack)
//#define GCODE_CASE_INSENSITIVE // Accept G-code sent to the firmware in lowercase
//#define REPETIER_GCODE_M360 // Add commands originally from Repetier FW
@@ -3607,7 +3686,7 @@
#define GANTRY_CALIBRATION_FEEDRATE 500 // Feedrate for correction move
//#define GANTRY_CALIBRATION_TO_MIN // Enable to calibrate Z in the MIN direction
//#define GANTRY_CALIBRATION_SAFE_POSITION { X_CENTER, Y_CENTER } // Safe position for nozzle
//#define GANTRY_CALIBRATION_SAFE_POSITION XY_CENTER // Safe position for nozzle
//#define GANTRY_CALIBRATION_XY_PARK_FEEDRATE 3000 // XY Park Feedrate - MMM
//#define GANTRY_CALIBRATION_COMMANDS_PRE ""
#define GANTRY_CALIBRATION_COMMANDS_POST "G28" // G28 highly recommended to ensure an accurate position
@@ -3689,16 +3768,26 @@
#endif
/**
* Průša Multi-Material Unit v2
* Průša Multi-Material Unit (MMU)
* Enable in Configuration.h
*
* These devices allow a single stepper driver on the board to drive
* multi-material feeders with any number of stepper motors.
*/
#if ENABLED(PRUSA_MMU2)
#if HAS_PRUSA_MMU1
/**
* This option only allows the multiplexer to switch on tool-change.
* Additional options to configure custom E moves are pending.
*
* Override the default DIO selector pins here, if needed.
* Some pins files may provide defaults for these pins.
*/
//#define E_MUX0_PIN 40 // Always Required
//#define E_MUX1_PIN 42 // Needed for 3 to 8 inputs
//#define E_MUX2_PIN 44 // Needed for 5 to 8 inputs
#elif HAS_PRUSA_MMU2
// Serial port used for communication with MMU2.
// For AVR enable the UART port used for the MMU. (e.g., mmuSerial)
// For 32-bit boards check your HAL for available serial ports. (e.g., Serial2)
#define MMU2_SERIAL_PORT 2
#define MMU2_SERIAL mmuSerial
// Use hardware reset for MMU if a pin is defined for it
//#define MMU2_RST_PIN 23
@@ -3711,7 +3800,7 @@
// Add an LCD menu for MMU2
//#define MMU2_MENUS
#if ENABLED(MMU2_MENUS)
#if EITHER(MMU2_MENUS, HAS_PRUSA_MMU2S)
// Settings for filament load / unload from the LCD menu.
// This is for Průša MK3-style extruders. Customize for your hardware.
#define MMU2_FILAMENTCHANGE_EJECT_FEED 80.0
@@ -3736,29 +3825,12 @@
{ -50.0, 2000 }
#endif
/**
* MMU Extruder Sensor
*
* Support for a Průša (or other) IR Sensor to detect filament near the extruder
* and make loading more reliable. Suitable for an extruder equipped with a filament
* sensor less than 38mm from the gears.
*
* During loading the extruder will stop when the sensor is triggered, then do a last
* move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
* If all attempts fail, a filament runout will be triggered.
*/
//#define MMU_EXTRUDER_SENSOR
#if ENABLED(MMU_EXTRUDER_SENSOR)
#define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
#endif
/**
* Using a sensor like the MMU2S
* This mode requires a MK3S extruder with a sensor at the extruder idler, like the MMU2S.
* See https://help.prusa3d.com/en/guide/3b-mk3s-mk2-5s-extruder-upgrade_41560, step 11
*/
//#define PRUSA_MMU2_S_MODE
#if ENABLED(PRUSA_MMU2_S_MODE)
#if HAS_PRUSA_MMU2S
#define MMU2_C0_RETRY 5 // Number of retries (total time = timeout*retries)
#define MMU2_CAN_LOAD_FEEDRATE 800 // (mm/min)
@@ -3774,11 +3846,29 @@
#define MMU2_CAN_LOAD_INCREMENT_SEQUENCE \
{ -MMU2_CAN_LOAD_INCREMENT, MMU2_CAN_LOAD_FEEDRATE }
#else
/**
* MMU1 Extruder Sensor
*
* Support for a Průša (or other) IR Sensor to detect filament near the extruder
* and make loading more reliable. Suitable for an extruder equipped with a filament
* sensor less than 38mm from the gears.
*
* During loading the extruder will stop when the sensor is triggered, then do a last
* move up to the gears. If no filament is detected, the MMU2 can make some more attempts.
* If all attempts fail, a filament runout will be triggered.
*/
//#define MMU_EXTRUDER_SENSOR
#if ENABLED(MMU_EXTRUDER_SENSOR)
#define MMU_LOADING_ATTEMPTS_NR 5 // max. number of attempts to load filament if first load fail
#endif
#endif
//#define MMU2_DEBUG // Write debug info to serial output
#endif // PRUSA_MMU2
#endif // HAS_PRUSA_MMU2
/**
* Advanced Print Counter settings
+7
View File
@@ -24,6 +24,13 @@
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#ifdef USBCON
DefaultSerial MSerial(false, Serial);
#ifdef BLUETOOTH
BTSerial btSerial(false, bluetoothSerial);
#endif
#endif
// ------------------------
// Public Variables
// ------------------------
+26 -7
View File
@@ -82,7 +82,15 @@ typedef int8_t pin_t;
// Serial ports
#ifdef USBCON
#define MYSERIAL0 TERN(BLUETOOTH, bluetoothSerial, Serial)
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
#ifdef BLUETOOTH
typedef ForwardSerial0Type< decltype(bluetoothSerial) > BTSerial;
extern BTSerial btSerial;
#endif
#define MYSERIAL0 TERN(BLUETOOTH, btSerial, MSerial)
#else
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
@@ -97,6 +105,13 @@ typedef int8_t pin_t;
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if !WITHIN(MMU2_SERIAL_PORT, -1, 3)
#error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#define MMU2_SERIAL mmuSerial
#endif
#ifdef LCD_SERIAL_PORT
#if !WITHIN(LCD_SERIAL_PORT, -1, 3)
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
@@ -122,12 +137,16 @@ inline uint8_t HAL_get_reset_source() { return MCUSR; }
inline void HAL_reboot() {} // reboot the board or restart the bootloader
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
extern "C" {
int freeMemory();
}
#pragma GCC diagnostic pop
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
extern "C" int freeMemory();
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
// ADC
#ifdef DIDR2
+14 -14
View File
@@ -34,17 +34,17 @@
#include "../../inc/MarlinConfig.h"
void spiBegin() {
OUT_WRITE(SS_PIN, HIGH);
SET_OUTPUT(SCK_PIN);
SET_INPUT(MISO_PIN);
SET_OUTPUT(MOSI_PIN);
OUT_WRITE(SD_SS_PIN, HIGH);
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
#if DISABLED(SOFTWARE_SPI)
// SS must be in output mode even it is not chip select
//SET_OUTPUT(SS_PIN);
//SET_OUTPUT(SD_SS_PIN);
// set SS high - may be chip select for another SPI device
//#if SET_SPI_SS_HIGH
//WRITE(SS_PIN, HIGH);
//WRITE(SD_SS_PIN, HIGH);
//#endif
// set a default rate
spiInit(1);
@@ -195,19 +195,19 @@ void spiBegin() {
// no interrupts during byte receive - about 8µs
cli();
// output pin high - like sending 0xFF
WRITE(MOSI_PIN, HIGH);
WRITE(SD_MOSI_PIN, HIGH);
LOOP_L_N(i, 8) {
WRITE(SCK_PIN, HIGH);
WRITE(SD_SCK_PIN, HIGH);
nop; // adjust so SCK is nice
nop;
data <<= 1;
if (READ(MISO_PIN)) data |= 1;
if (READ(SD_MISO_PIN)) data |= 1;
WRITE(SCK_PIN, LOW);
WRITE(SD_SCK_PIN, LOW);
}
sei();
@@ -225,10 +225,10 @@ void spiBegin() {
// no interrupts during byte send - about 8µs
cli();
LOOP_L_N(i, 8) {
WRITE(SCK_PIN, LOW);
WRITE(MOSI_PIN, data & 0x80);
WRITE(SD_SCK_PIN, LOW);
WRITE(SD_MOSI_PIN, data & 0x80);
data <<= 1;
WRITE(SCK_PIN, HIGH);
WRITE(SD_SCK_PIN, HIGH);
}
nop; // hold SCK high for a few ns
@@ -236,7 +236,7 @@ void spiBegin() {
nop;
nop;
WRITE(SCK_PIN, LOW);
WRITE(SD_SCK_PIN, LOW);
sei();
}
+14 -181
View File
@@ -454,7 +454,7 @@ void MarlinSerial<Cfg>::flush() {
}
template<typename Cfg>
void MarlinSerial<Cfg>::write(const uint8_t c) {
size_t MarlinSerial<Cfg>::write(const uint8_t c) {
if (Cfg::TX_SIZE == 0) {
_written = true;
@@ -480,7 +480,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
// location". This makes sure flush() won't return until the bytes
// actually got written
B_TXC = 1;
return;
return 1;
}
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
@@ -510,6 +510,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
// Enable TX ISR - Non atomic, but it will eventually enable TX ISR
B_UDRIE = 1;
}
return 1;
}
template<typename Cfg>
@@ -556,161 +557,6 @@ void MarlinSerial<Cfg>::flushTX() {
}
}
/**
* Imports from print.h
*/
template<typename Cfg>
void MarlinSerial<Cfg>::print(char c, int base) {
print((long)c, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned char b, int base) {
print((unsigned long)b, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(int n, int base) {
print((long)n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned int n, int base) {
print((unsigned long)n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(long n, int base) {
if (base == 0) write(n);
else if (base == 10) {
if (n < 0) { print('-'); n = -n; }
printNumber(n, 10);
}
else
printNumber(n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned long n, int base) {
if (base == 0) write(n);
else printNumber(n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(double n, int digits) {
printFloat(n, digits);
}
template<typename Cfg>
void MarlinSerial<Cfg>::println() {
print('\r');
print('\n');
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(const String& s) {
print(s);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(const char c[]) {
print(c);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(char c, int base) {
print(c, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned char b, int base) {
print(b, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(int n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned int n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(long n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned long n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(double n, int digits) {
print(n, digits);
println();
}
// Private Methods
template<typename Cfg>
void MarlinSerial<Cfg>::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
template<typename Cfg>
void MarlinSerial<Cfg>::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) {
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
LOOP_L_N(i, digits) rounding *= 0.1;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
}
// Hookup ISR handlers
ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _RX_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::store_rxd_char();
@@ -720,11 +566,9 @@ ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>;
// Instantiate
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
// Because of the template definition above, it's required to instantiate the template to have all method generated
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT> >;
MSerialT customizedSerial1(MSerialT::HasEmergencyParser);
#ifdef SERIAL_PORT_2
@@ -737,12 +581,8 @@ MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>;
// Instantiate
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> >;
MSerialT2 customizedSerial2(MSerialT2::HasEmergencyParser);
#endif
#ifdef MMU2_SERIAL_PORT
@@ -755,12 +595,8 @@ MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>>;
// Instantiate
MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>> mmuSerial;
template class MarlinSerial< MarlinSerialCfg<MMU2_SERIAL_PORT> >;
MSerialT3 mmuSerial(MSerialT3::HasEmergencyParser);
#endif
#ifdef LCD_SERIAL_PORT
@@ -773,12 +609,9 @@ MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
MarlinSerial<LCDSerialCfg<LCD_SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Preinstantiate
template class MarlinSerial<LCDSerialCfg<LCD_SERIAL_PORT>>;
// Instantiate
MarlinSerial<LCDSerialCfg<LCD_SERIAL_PORT>> lcdSerial;
template class MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> >;
MSerialT4 lcdSerial(MSerialT4::HasEmergencyParser);
#if HAS_DGUS_LCD
template<typename Cfg>
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
@@ -796,7 +629,7 @@ MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
// For AT90USB targets use the UART for BT interfacing
#if defined(USBCON) && ENABLED(BLUETOOTH)
HardwareSerial bluetoothSerial;
MSerialT5 bluetoothSerial(false);
#endif
#endif // __AVR__
+31 -60
View File
@@ -34,6 +34,7 @@
#include <WString.h>
#include "../../inc/MarlinConfigPre.h"
#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
@@ -135,10 +136,6 @@
UART_DECL(3);
#endif
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#define BYTE 0
// Templated type selector
@@ -202,60 +199,30 @@
static FORCE_INLINE void atomic_set_rx_tail(ring_buffer_pos_t value);
static FORCE_INLINE ring_buffer_pos_t atomic_read_rx_tail();
public:
public:
FORCE_INLINE static void store_rxd_char();
FORCE_INLINE static void _tx_udr_empty_irq();
public:
MarlinSerial() {};
static void begin(const long);
static void end();
static int peek();
static int read();
static void flush();
static ring_buffer_pos_t available();
static void write(const uint8_t c);
static void flushTX();
#if HAS_DGUS_LCD
static ring_buffer_pos_t get_tx_buffer_free();
#endif
public:
static void begin(const long);
static void end();
static int peek();
static int read();
static void flush();
static ring_buffer_pos_t available();
static size_t write(const uint8_t c);
static void flushTX();
#if HAS_DGUS_LCD
static ring_buffer_pos_t get_tx_buffer_free();
#endif
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
enum { HasEmergencyParser = Cfg::EMERGENCYPARSER };
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE static void print(const char* str) { write(str); }
static void print(char, int = BYTE);
static void print(unsigned char, int = BYTE);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = BYTE);
static void println(unsigned char, int = BYTE);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println();
operator bool() { return true; }
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
FORCE_INLINE static uint8_t dropped() { return Cfg::DROPPED_RX ? rx_dropped_bytes : 0; }
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
};
template <uint8_t serial>
@@ -270,12 +237,13 @@
static constexpr bool RX_FRAMING_ERRORS = ENABLED(SERIAL_STATS_RX_FRAMING_ERRORS);
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
extern MSerialT customizedSerial1;
#ifdef SERIAL_PORT_2
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
extern MSerialT2 customizedSerial2;
#endif
#endif // !USBCON
@@ -294,7 +262,8 @@
static constexpr bool RX_OVERRUNS = false;
};
extern MarlinSerial<MMU2SerialCfg<MMU2_SERIAL_PORT>> mmuSerial;
typedef Serial0Type< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialT3;
extern MSerial3 mmuSerial;
#endif
#ifdef LCD_SERIAL_PORT
@@ -322,11 +291,13 @@
#endif
};
extern MarlinSerial<LCDSerialCfg<LCD_SERIAL_PORT>> lcdSerial;
typedef Serial0Type< MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> > > MSerialT4;
extern MSerialT4 lcdSerial;
#endif
// Use the UART for Bluetooth in AT90USB configurations
#if defined(USBCON) && ENABLED(BLUETOOTH)
extern HardwareSerial bluetoothSerial;
typedef Serial0Type<HardwareSerial> MSerialT5;
extern MSerialT5 bluetoothSerial;
#endif
+17 -17
View File
@@ -124,7 +124,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X_MAX_PIN);
#endif
#endif
@@ -132,7 +132,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X_MIN_PIN);
#endif
#endif
@@ -140,7 +140,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y_MAX_PIN);
#endif
#endif
@@ -148,7 +148,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y_MIN_PIN);
#endif
#endif
@@ -156,7 +156,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MAX_PIN);
#endif
#endif
@@ -164,7 +164,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MIN_PIN);
#endif
#endif
@@ -172,7 +172,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X2_MAX_PIN);
#endif
#endif
@@ -180,7 +180,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(X2_MIN_PIN);
#endif
#endif
@@ -188,7 +188,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y2_MAX_PIN);
#endif
#endif
@@ -196,7 +196,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Y2_MIN_PIN);
#endif
#endif
@@ -204,7 +204,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z2_MAX_PIN);
#endif
#endif
@@ -212,7 +212,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z2_MIN_PIN);
#endif
#endif
@@ -220,7 +220,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z3_MAX_PIN);
#endif
#endif
@@ -228,7 +228,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z3_MIN_PIN);
#endif
#endif
@@ -236,7 +236,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z4_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MAX_PIN);
#else
static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z4_MAX_PIN), "Z4_MAX_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z4_MAX_PIN);
#endif
#endif
@@ -244,7 +244,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z4_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z4_MIN_PIN);
#else
static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z4_MIN_PIN), "Z4_MIN_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z4_MIN_PIN);
#endif
#endif
@@ -252,7 +252,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PROBE_PIN);
#else
static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue.");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
+8 -8
View File
@@ -51,15 +51,15 @@
#define AVR_SS_PIN 16
#endif
#ifndef SCK_PIN
#define SCK_PIN AVR_SCK_PIN
#ifndef SD_SCK_PIN
#define SD_SCK_PIN AVR_SCK_PIN
#endif
#ifndef MISO_PIN
#define MISO_PIN AVR_MISO_PIN
#ifndef SD_MISO_PIN
#define SD_MISO_PIN AVR_MISO_PIN
#endif
#ifndef MOSI_PIN
#define MOSI_PIN AVR_MOSI_PIN
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN AVR_MOSI_PIN
#endif
#ifndef SS_PIN
#define SS_PIN AVR_SS_PIN
#ifndef SD_SS_PIN
#define SD_SS_PIN AVR_SS_PIN
#endif
+7
View File
@@ -102,4 +102,11 @@ uint16_t HAL_adc_get_result() {
return HAL_adc_result;
}
// Forward the default serial port
DefaultSerial MSerial(false, Serial);
DefaultSerial1 MSerial1(false, Serial1);
DefaultSerial2 MSerial2(false, Serial2);
DefaultSerial3 MSerial3(false, Serial3);
#endif // ARDUINO_ARCH_SAM
+30 -15
View File
@@ -36,9 +36,20 @@
#include <stdint.h>
#define _MSERIAL(X) Serial##X
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
typedef ForwardSerial0Type< decltype(Serial2) > DefaultSerial2;
typedef ForwardSerial0Type< decltype(Serial3) > DefaultSerial3;
extern DefaultSerial1 MSerial1;
extern DefaultSerial2 MSerial2;
extern DefaultSerial3 MSerial3;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define Serial0 Serial
#define MSerial0 MSerial
// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
@@ -59,6 +70,14 @@
#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. Please update your configuration."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL lcdSerial
@@ -75,16 +94,6 @@
// On AVR this is in math.h?
#define square(x) ((x)*(x))
#ifndef strncpy_P
#define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
#endif
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*((void**)(addr)))
#undef pgm_read_word
#define pgm_read_word(addr) (*((uint16_t*)(addr)))
typedef int8_t pin_t;
#define SHARED_SERVOS HAS_SERVOS
@@ -153,10 +162,16 @@ void HAL_init();
//
void _delay_ms(const int delay);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#pragma GCC diagnostic pop
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
extern "C" {
+44 -44
View File
@@ -69,10 +69,10 @@
// run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
static uint8_t spiTransferTx0(uint8_t bout) { // using Mode 0
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
uint32_t idx = 0;
/* Negate bout, as the assembler requires a negated value */
@@ -154,9 +154,9 @@
static uint8_t spiTransferRx0(uint8_t) { // using Mode 0
uint32_t bin = 0;
uint32_t work = 0;
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
/* The software SPI routine */
__asm__ __volatile__(
@@ -225,15 +225,15 @@
static uint8_t spiTransfer1(uint8_t b) { // using Mode 0
int bits = 8;
do {
WRITE(MOSI_PIN, b & 0x80);
WRITE(SD_MOSI_PIN, b & 0x80);
b <<= 1; // little setup time
WRITE(SCK_PIN, HIGH);
WRITE(SD_SCK_PIN, HIGH);
DELAY_NS(125); // 10 cycles @ 84mhz
b |= (READ(MISO_PIN) != 0);
b |= (READ(SD_MISO_PIN) != 0);
WRITE(SCK_PIN, LOW);
WRITE(SD_SCK_PIN, LOW);
DELAY_NS(125); // 10 cycles @ 84mhz
} while (--bits);
return b;
@@ -245,15 +245,15 @@
static uint8_t spiTransferX(uint8_t b) { // using Mode 0
int bits = 8;
do {
WRITE(MOSI_PIN, b & 0x80);
WRITE(SD_MOSI_PIN, b & 0x80);
b <<= 1; // little setup time
WRITE(SCK_PIN, HIGH);
WRITE(SD_SCK_PIN, HIGH);
__delay_4cycles(spiDelayCyclesX4);
b |= (READ(MISO_PIN) != 0);
b |= (READ(SD_MISO_PIN) != 0);
WRITE(SCK_PIN, LOW);
WRITE(SD_SCK_PIN, LOW);
__delay_4cycles(spiDelayCyclesX4);
} while (--bits);
return b;
@@ -271,10 +271,10 @@
// Block transfers run at ~8 .. ~10Mhz - Tx version (Rx data discarded)
static void spiTxBlock0(const uint8_t* ptr, uint32_t todo) {
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(MOSI_PIN)) + 0x30; /* SODR of port */
uint32_t MOSI_MASK = PIN_MASK(MOSI_PIN);
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
uint32_t MOSI_PORT_PLUS30 = ((uint32_t) PORT(SD_MOSI_PIN)) + 0x30; /* SODR of port */
uint32_t MOSI_MASK = PIN_MASK(SD_MOSI_PIN);
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
uint32_t work = 0;
uint32_t txval = 0;
@@ -352,9 +352,9 @@
static void spiRxBlock0(uint8_t* ptr, uint32_t todo) {
uint32_t bin = 0;
uint32_t work = 0;
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(MISO_PIN))+0x3C, PIN_SHIFT(MISO_PIN)); /* PDSR of port in bitband area */
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SCK_PIN);
uint32_t BITBAND_MISO_PORT = BITBAND_ADDRESS( ((uint32_t)PORT(SD_MISO_PIN))+0x3C, PIN_SHIFT(SD_MISO_PIN)); /* PDSR of port in bitband area */
uint32_t SCK_PORT_PLUS30 = ((uint32_t) PORT(SD_SCK_PIN)) + 0x30; /* SODR of port */
uint32_t SCK_MASK = PIN_MASK(SD_SCK_PIN);
/* The software SPI routine */
__asm__ __volatile__(
@@ -442,22 +442,22 @@
static pfnSpiRxBlock spiRxBlock = (pfnSpiRxBlock)spiRxBlockX;
#if MB(ALLIGATOR)
#define _SS_WRITE(S) WRITE(SS_PIN, S)
#define _SS_WRITE(S) WRITE(SD_SS_PIN, S)
#else
#define _SS_WRITE(S) NOOP
#endif
void spiBegin() {
SET_OUTPUT(SS_PIN);
SET_OUTPUT(SD_SS_PIN);
_SS_WRITE(HIGH);
SET_OUTPUT(SCK_PIN);
SET_INPUT(MISO_PIN);
SET_OUTPUT(MOSI_PIN);
SET_OUTPUT(SD_SCK_PIN);
SET_INPUT(SD_MISO_PIN);
SET_OUTPUT(SD_MOSI_PIN);
}
uint8_t spiRec() {
_SS_WRITE(LOW);
WRITE(MOSI_PIN, HIGH); // Output 1s 1
WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
uint8_t b = spiTransferRx(0xFF);
_SS_WRITE(HIGH);
return b;
@@ -466,7 +466,7 @@
void spiRead(uint8_t* buf, uint16_t nbyte) {
if (nbyte) {
_SS_WRITE(LOW);
WRITE(MOSI_PIN, HIGH); // Output 1s 1
WRITE(SD_MOSI_PIN, HIGH); // Output 1s 1
spiRxBlock(buf, nbyte);
_SS_WRITE(HIGH);
}
@@ -519,8 +519,8 @@
}
_SS_WRITE(HIGH);
WRITE(MOSI_PIN, HIGH);
WRITE(SCK_PIN, LOW);
WRITE(SD_MOSI_PIN, HIGH);
WRITE(SD_SCK_PIN, LOW);
}
/** Begin SPI transaction, set clock, bit order, data mode */
@@ -575,20 +575,20 @@
// Configure SPI pins
PIO_Configure(
g_APinDescription[SCK_PIN].pPort,
g_APinDescription[SCK_PIN].ulPinType,
g_APinDescription[SCK_PIN].ulPin,
g_APinDescription[SCK_PIN].ulPinConfiguration);
g_APinDescription[SD_SCK_PIN].pPort,
g_APinDescription[SD_SCK_PIN].ulPinType,
g_APinDescription[SD_SCK_PIN].ulPin,
g_APinDescription[SD_SCK_PIN].ulPinConfiguration);
PIO_Configure(
g_APinDescription[MOSI_PIN].pPort,
g_APinDescription[MOSI_PIN].ulPinType,
g_APinDescription[MOSI_PIN].ulPin,
g_APinDescription[MOSI_PIN].ulPinConfiguration);
g_APinDescription[SD_MOSI_PIN].pPort,
g_APinDescription[SD_MOSI_PIN].ulPinType,
g_APinDescription[SD_MOSI_PIN].ulPin,
g_APinDescription[SD_MOSI_PIN].ulPinConfiguration);
PIO_Configure(
g_APinDescription[MISO_PIN].pPort,
g_APinDescription[MISO_PIN].ulPinType,
g_APinDescription[MISO_PIN].ulPin,
g_APinDescription[MISO_PIN].ulPinConfiguration);
g_APinDescription[SD_MISO_PIN].pPort,
g_APinDescription[SD_MISO_PIN].ulPinType,
g_APinDescription[SD_MISO_PIN].ulPin,
g_APinDescription[SD_MISO_PIN].ulPinConfiguration);
// set master mode, peripheral select, fault detection
SPI_Configure(SPI0, ID_SPI0, SPI_MR_MSTR | SPI_MR_MODFDIS | SPI_MR_PS);
@@ -606,7 +606,7 @@
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM2_CS, HIGH);
WRITE(SPI_FLASH_CS, HIGH);
WRITE(SS_PIN, HIGH);
WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SDSS, LOW);
+7 -159
View File
@@ -382,7 +382,7 @@ void MarlinSerial<Cfg>::flush() {
}
template<typename Cfg>
void MarlinSerial<Cfg>::write(const uint8_t c) {
size_t MarlinSerial<Cfg>::write(const uint8_t c) {
_written = true;
if (Cfg::TX_SIZE == 0) {
@@ -400,7 +400,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
// XOFF char at the RX isr, but it is properly handled there
if (!(HWUART->UART_IMR & UART_IMR_TXRDY) && (HWUART->UART_SR & UART_SR_TXRDY)) {
HWUART->UART_THR = c;
return;
return 1;
}
const uint8_t i = (tx_buffer.head + 1) & (Cfg::TX_SIZE - 1);
@@ -428,6 +428,7 @@ void MarlinSerial<Cfg>::write(const uint8_t c) {
// Enable TX isr - Non atomic, but it will eventually enable TX isr
HWUART->UART_IER = UART_IER_TXRDY;
}
return 1;
}
template<typename Cfg>
@@ -473,169 +474,16 @@ void MarlinSerial<Cfg>::flushTX() {
}
}
/**
* Imports from print.h
*/
template<typename Cfg>
void MarlinSerial<Cfg>::print(char c, int base) {
print((long)c, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned char b, int base) {
print((unsigned long)b, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(int n, int base) {
print((long)n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned int n, int base) {
print((unsigned long)n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(long n, int base) {
if (base == 0) write(n);
else if (base == 10) {
if (n < 0) { print('-'); n = -n; }
printNumber(n, 10);
}
else
printNumber(n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(unsigned long n, int base) {
if (base == 0) write(n);
else printNumber(n, base);
}
template<typename Cfg>
void MarlinSerial<Cfg>::print(double n, int digits) {
printFloat(n, digits);
}
template<typename Cfg>
void MarlinSerial<Cfg>::println() {
print('\r');
print('\n');
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(const String& s) {
print(s);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(const char c[]) {
print(c);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(char c, int base) {
print(c, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned char b, int base) {
print(b, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(int n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned int n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(long n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(unsigned long n, int base) {
print(n, base);
println();
}
template<typename Cfg>
void MarlinSerial<Cfg>::println(double n, int digits) {
print(n, digits);
println();
}
// Private Methods
template<typename Cfg>
void MarlinSerial<Cfg>::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
template<typename Cfg>
void MarlinSerial<Cfg>::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) {
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
LOOP_L_N(i, digits) rounding *= 0.1;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
}
// If not using the USB port as serial port
#if SERIAL_PORT >= 0
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>; // Define
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1; // Instantiate
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT> >;
MSerialT customizedSerial1(MarlinSerialCfg<SERIAL_PORT>::EMERGENCYPARSER);
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
template class MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>>; // Define
MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2; // Instantiate
template class MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> >;
MSerialT2 customizedSerial2(MarlinSerialCfg<SERIAL_PORT_2>::EMERGENCYPARSER);
#endif
#endif // ARDUINO_ARCH_SAM
+6 -37
View File
@@ -30,11 +30,7 @@
#include <WString.h>
#include "../../inc/MarlinConfigPre.h"
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
#include "../../core/serial_hook.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
@@ -119,7 +115,7 @@ public:
static int read();
static void flush();
static ring_buffer_pos_t available();
static void write(const uint8_t c);
static size_t write(const uint8_t c);
static void flushTX();
static inline bool emergency_parser_enabled() { return Cfg::EMERGENCYPARSER; }
@@ -128,35 +124,6 @@ public:
FORCE_INLINE static uint8_t buffer_overruns() { return Cfg::RX_OVERRUNS ? rx_buffer_overruns : 0; }
FORCE_INLINE static uint8_t framing_errors() { return Cfg::RX_FRAMING_ERRORS ? rx_framing_errors : 0; }
FORCE_INLINE static ring_buffer_pos_t rxMaxEnqueued() { return Cfg::MAX_RX_QUEUED ? rx_max_enqueued : 0; }
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE static void print(const char* str) { write(str); }
static void print(char, int = 0);
static void print(unsigned char, int = 0);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = 0);
static void println(unsigned char, int = 0);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println();
operator bool() { return true; }
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
};
// Serial port configuration
@@ -174,9 +141,11 @@ struct MarlinSerialCfg {
};
#if SERIAL_PORT >= 0
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT>> customizedSerial1;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
extern MSerialT customizedSerial1;
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
extern MarlinSerial<MarlinSerialCfg<SERIAL_PORT_2>> customizedSerial2;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
extern MSerialT2 customizedSerial2;
#endif
+6 -151
View File
@@ -50,10 +50,6 @@ extern "C" {
// Pending character
static int pending_char = -1;
#if ENABLED(EMERGENCY_PARSER)
static EmergencyParser::State emergency_state; // = EP_RESET
#endif
// Public Methods
void MarlinSerialUSB::begin(const long) {}
@@ -111,13 +107,13 @@ bool MarlinSerialUSB::available() {
void MarlinSerialUSB::flush() { }
void MarlinSerialUSB::flushTX() { }
void MarlinSerialUSB::write(const uint8_t c) {
size_t MarlinSerialUSB::write(const uint8_t c) {
/* Do not even bother sending anything if USB CDC is not enumerated
or not configured on the PC side or there is no program on the PC
listening to our messages */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
return;
return 0;
/* Wait until the PC has read the pending to be sent data */
while (usb_task_cdc_isenabled() &&
@@ -129,161 +125,20 @@ void MarlinSerialUSB::write(const uint8_t c) {
or not configured on the PC side or there is no program on the PC
listening to our messages at this point */
if (!usb_task_cdc_isenabled() || !usb_task_cdc_dtr_active())
return;
return 0;
// Fifo full
// udi_cdc_signal_overrun();
udi_cdc_putc(c);
}
/**
* Imports from print.h
*/
void MarlinSerialUSB::print(char c, int base) {
print((long)c, base);
}
void MarlinSerialUSB::print(unsigned char b, int base) {
print((unsigned long)b, base);
}
void MarlinSerialUSB::print(int n, int base) {
print((long)n, base);
}
void MarlinSerialUSB::print(unsigned int n, int base) {
print((unsigned long)n, base);
}
void MarlinSerialUSB::print(long n, int base) {
if (base == 0)
write(n);
else if (base == 10) {
if (n < 0) {
print('-');
n = -n;
}
printNumber(n, 10);
}
else
printNumber(n, base);
}
void MarlinSerialUSB::print(unsigned long n, int base) {
if (base == 0) write(n);
else printNumber(n, base);
}
void MarlinSerialUSB::print(double n, int digits) {
printFloat(n, digits);
}
void MarlinSerialUSB::println() {
print('\r');
print('\n');
}
void MarlinSerialUSB::println(const String& s) {
print(s);
println();
}
void MarlinSerialUSB::println(const char c[]) {
print(c);
println();
}
void MarlinSerialUSB::println(char c, int base) {
print(c, base);
println();
}
void MarlinSerialUSB::println(unsigned char b, int base) {
print(b, base);
println();
}
void MarlinSerialUSB::println(int n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(unsigned int n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(long n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(unsigned long n, int base) {
print(n, base);
println();
}
void MarlinSerialUSB::println(double n, int digits) {
print(n, digits);
println();
}
// Private Methods
void MarlinSerialUSB::printNumber(unsigned long n, uint8_t base) {
if (n) {
unsigned char buf[8 * sizeof(long)]; // Enough space for base 2
int8_t i = 0;
while (n) {
buf[i++] = n % base;
n /= base;
}
while (i--)
print((char)(buf[i] + (buf[i] < 10 ? '0' : 'A' - 10)));
}
else
print('0');
}
void MarlinSerialUSB::printFloat(double number, uint8_t digits) {
// Handle negative numbers
if (number < 0.0) {
print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
LOOP_L_N(i, digits)
rounding *= 0.1;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits) {
print('.');
// Extract digits from the remainder one at a time
while (digits--) {
remainder *= 10.0;
int toPrint = int(remainder);
print(toPrint);
remainder -= toPrint;
}
}
return 1;
}
// Preinstantiate
#if SERIAL_PORT == -1
MarlinSerialUSB customizedSerial1;
MSerialT customizedSerial1(TERN0(EMERGENCY_PARSER, true));
#endif
#if SERIAL_PORT_2 == -1
MarlinSerialUSB customizedSerial2;
MSerialT customizedSerial2(TERN0(EMERGENCY_PARSER, true));
#endif
#endif // HAS_USB_SERIAL
+6 -41
View File
@@ -27,20 +27,13 @@
*/
#include "../../inc/MarlinConfig.h"
#if HAS_USB_SERIAL
#include <WString.h>
#include "../../core/serial_hook.h"
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
class MarlinSerialUSB {
public:
MarlinSerialUSB() {};
struct MarlinSerialUSB {
static void begin(const long);
static void end();
static int peek();
@@ -48,7 +41,7 @@ public:
static void flush();
static void flushTX();
static bool available();
static void write(const uint8_t c);
static size_t write(const uint8_t c);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE static uint32_t dropped() { return 0; }
@@ -57,43 +50,15 @@ public:
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
FORCE_INLINE static int rxMaxEnqueued() { return 0; }
#endif
FORCE_INLINE static void write(const char* str) { while (*str) write(*str++); }
FORCE_INLINE static void write(const uint8_t* buffer, size_t size) { while (size--) write(*buffer++); }
FORCE_INLINE static void print(const String& s) { for (int i = 0; i < (int)s.length(); i++) write(s[i]); }
FORCE_INLINE static void print(const char* str) { write(str); }
static void print(char, int = 0);
static void print(unsigned char, int = 0);
static void print(int, int = DEC);
static void print(unsigned int, int = DEC);
static void print(long, int = DEC);
static void print(unsigned long, int = DEC);
static void print(double, int = 2);
static void println(const String& s);
static void println(const char[]);
static void println(char, int = 0);
static void println(unsigned char, int = 0);
static void println(int, int = DEC);
static void println(unsigned int, int = DEC);
static void println(long, int = DEC);
static void println(unsigned long, int = DEC);
static void println(double, int = 2);
static void println();
operator bool() { return true; }
private:
static void printNumber(unsigned long, const uint8_t);
static void printFloat(double, uint8_t);
};
typedef Serial0Type<MarlinSerialUSB> MSerialT;
#if SERIAL_PORT == -1
extern MarlinSerialUSB customizedSerial1;
extern MSerialT customizedSerial1;
#endif
#if SERIAL_PORT_2 == -1
extern MarlinSerialUSB customizedSerial2;
extern MSerialT customizedSerial2;
#endif
#endif // HAS_USB_SERIAL
@@ -64,12 +64,11 @@
#include "../../../MarlinCore.h"
void spiBegin();
void spiInit(uint8_t spiRate);
void spiSend(uint8_t b);
void spiSend(const uint8_t* buf, size_t n);
#ifndef LCD_SPI_SPEED
#define LCD_SPI_SPEED SPI_QUARTER_SPEED
#endif
#include "../../shared/Marduino.h"
#include "../../shared/HAL_SPI.h"
#include "../fastio.h"
void u8g_SetPIOutput_DUE_hw_spi(u8g_t *u8g, uint8_t pin_index) {
@@ -100,11 +99,7 @@ uint8_t u8g_com_HAL_DUE_shared_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_va
spiBegin();
#ifndef SPI_SPEED
#define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
#endif
spiInit(2);
spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
@@ -59,9 +59,6 @@
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#undef SPI_SPEED
#define SPI_SPEED 2 // About 2 MHz
#include "u8g_com_HAL_DUE_sw_spi_shared.h"
#include "../../shared/Marduino.h"
+4 -1
View File
@@ -50,7 +50,7 @@
#define PWM_PIN(P) WITHIN(P, 2, 13)
#ifndef MASK
#define MASK(PIN) (1 << PIN)
#define MASK(PIN) _BV(PIN)
#endif
/**
@@ -163,6 +163,9 @@
#define SET_INPUT(IO) _SET_INPUT(IO)
// Set pin as input with pullup (wrapper)
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
// Set pin as input with pulldown (substitution)
#define SET_INPUT_PULLDOWN SET_INPUT
// Set pin as output (wrapper) - reads the pin and sets the output to that value
#define SET_OUTPUT(IO) _SET_OUTPUT(IO)
// Set pin as PWM
+1 -1
View File
@@ -40,7 +40,7 @@
* 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_SW_##P) && (TMC_SW_##P == MOSI_PIN || TMC_SW_##P == MISO_PIN || TMC_SW_##P == SCK_PIN))
#define _IS_HW_SPI(P) (defined(TMC_SW_##P) && (TMC_SW_##P == SD_MOSI_PIN || TMC_SW_##P == SD_MISO_PIN || TMC_SW_##P == SD_SCK_PIN))
#if ENABLED(SDSUPPORT) && HAS_DRIVER(TMC2130)
#if ENABLED(TMC_USE_SW_SPI)
+10 -10
View File
@@ -43,22 +43,22 @@
#define SPI_PIN 87
#define SPI_CHAN 1
#endif
#define SCK_PIN 76
#define MISO_PIN 74
#define MOSI_PIN 75
#define SD_SCK_PIN 76
#define SD_MISO_PIN 74
#define SD_MOSI_PIN 75
#else
// defaults
#define DUE_SOFTWARE_SPI
#ifndef SCK_PIN
#define SCK_PIN 52
#ifndef SD_SCK_PIN
#define SD_SCK_PIN 52
#endif
#ifndef MISO_PIN
#define MISO_PIN 50
#ifndef SD_MISO_PIN
#define SD_MISO_PIN 50
#endif
#ifndef MOSI_PIN
#define MOSI_PIN 51
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN 51
#endif
#endif
/* A.28, A.29, B.21, C.26, C.29 */
#define SS_PIN SDSS
#define SD_SS_PIN SDSS
+1 -1
View File
@@ -121,7 +121,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
+2 -2
View File
@@ -68,7 +68,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
{
char buffer[80];
sprintf_P(buffer, PSTR("SDRD: %d @ 0x%08x\n"), nb_sector, addr);
PORT_REDIRECT(0);
PORT_REDIRECT(SERIAL_PORTMASK(0));
SERIAL_ECHO(buffer);
}
#endif
@@ -108,7 +108,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
{
char buffer[80];
sprintf_P(buffer, PSTR("SDWR: %d @ 0x%08x\n"), nb_sector, addr);
PORT_REDIRECT(0);
PORT_REDIRECT(SERIAL_PORTMASK(0));
SERIAL_ECHO(buffer);
}
#endif
@@ -24,10 +24,7 @@
#ifdef ARDUINO_ARCH_ESP32
FlushableHardwareSerial::FlushableHardwareSerial(int uart_nr)
: HardwareSerial(uart_nr)
{}
FlushableHardwareSerial flushableSerial(0);
Serial0Type<FlushableHardwareSerial> flushableSerial(false, 0);
#endif // ARDUINO_ARCH_ESP32
@@ -24,14 +24,13 @@
#ifdef ARDUINO_ARCH_ESP32
#include <HardwareSerial.h>
#include "../../core/serial_hook.h"
class FlushableHardwareSerial : public HardwareSerial {
public:
FlushableHardwareSerial(int uart_nr);
inline void flushTX() { /* No need to flush the hardware serial, but defined here for compatibility. */ }
FlushableHardwareSerial(int uart_nr) : HardwareSerial(uart_nr) {}
};
extern FlushableHardwareSerial flushableSerial;
extern Serial0Type<FlushableHardwareSerial> flushableSerial;
#endif // ARDUINO_ARCH_ESP32
+4
View File
@@ -40,6 +40,10 @@
#endif
#endif
#if ENABLED(ESP3D_WIFISUPPORT)
DefaultSerial MSerial(false, Serial2Socket);
#endif
// ------------------------
// Externs
// ------------------------
+19 -8
View File
@@ -55,7 +55,9 @@ extern portMUX_TYPE spinlock;
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(ESP3D_WIFISUPPORT)
#define MYSERIAL1 Serial2Socket
typedef ForwardSerial0Type< decltype(Serial2Socket) > DefaultSerial;
extern DefaultSerial MSerial;
#define MYSERIAL1 MSerial
#else
#define MYSERIAL1 webSocketSerial
#endif
@@ -67,10 +69,6 @@ extern portMUX_TYPE spinlock;
#define ENABLE_ISRS() if (spinlock.owner != portMUX_FREE_VAL) portEXIT_CRITICAL(&spinlock)
#define DISABLE_ISRS() portENTER_CRITICAL(&spinlock)
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*(addr))
// ------------------------
// Types
// ------------------------
@@ -90,6 +88,13 @@ extern uint16_t HAL_adc_result;
// Public functions
// ------------------------
//
// Tone
//
void toneInit();
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration=0);
void noTone(const pin_t _pin);
// clear reset reason
void HAL_clear_reset_source();
@@ -100,10 +105,16 @@ inline void HAL_reboot() {} // reboot the board or restart the bootloader
void _delay_ms(int delay);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#pragma GCC diagnostic pop
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
void analogWrite(pin_t pin, int value);
+3 -3
View File
@@ -53,11 +53,11 @@ static SPISettings spiConfig;
// ------------------------
void spiBegin() {
#if !PIN_EXISTS(SS)
#error "SS_PIN not defined!"
#if !PIN_EXISTS(SD_SS)
#error "SD_SS_PIN not defined!"
#endif
OUT_WRITE(SS_PIN, HIGH);
OUT_WRITE(SD_SS_PIN, HIGH);
}
void spiInit(uint8_t spiRate) {
+1 -1
View File
@@ -30,7 +30,7 @@ class Servo {
MAX_PULSE_WIDTH = 2400, // Longest pulse sent to a servo
TAU_MSEC = 20,
TAU_USEC = (TAU_MSEC * 1000),
MAX_COMPARE = ((1 << 16) - 1), // 65535
MAX_COMPARE = _BV(16) - 1, // 65535
CHANNEL_MAX_NUM = 16;
public:
@@ -4,7 +4,8 @@
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2017 Victor Perez
*
* Copypaste of SAMD51 HAL developed by Giuliano Zaro (AKA GMagician)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -20,32 +21,39 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(STM32GENERIC) && (defined(STM32F4) || defined(STM32F7))
/**
* Description: Tone function for ESP32
* Derived from https://forum.arduino.cc/index.php?topic=136500.msg2903012#msg2903012
*/
#ifdef ARDUINO_ARCH_ESP32
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#if HAS_SERVOS
static pin_t tone_pin;
volatile static int32_t toggles;
#include "Servo.h"
int8_t libServo::attach(const int pin) {
if (servoIndex >= MAX_SERVOS) return -1;
return super::attach(pin);
void tone(const pin_t _pin, const unsigned int frequency, const unsigned long duration) {
tone_pin = _pin;
toggles = 2 * frequency * duration / 1000;
HAL_timer_start(TONE_TIMER_NUM, 2 * frequency);
}
int8_t libServo::attach(const int pin, const int min, const int max) {
return super::attach(pin, min, max);
void noTone(const pin_t _pin) {
HAL_timer_disable_interrupt(TONE_TIMER_NUM);
WRITE(_pin, LOW);
}
void libServo::move(const int value) {
constexpr uint16_t servo_delay[] = SERVO_DELAY;
static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
if (attach(0) >= 0) {
write(value);
safe_delay(servo_delay[servoIndex]);
TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach());
HAL_TONE_TIMER_ISR() {
HAL_timer_isr_prologue(TONE_TIMER_NUM);
if (toggles) {
toggles--;
TOGGLE(tone_pin);
}
else noTone(tone_pin); // turn off interrupt
}
#endif // HAS_SERVOS
#endif // STM32GENERIC && (STM32F4 || STM32F7)
#endif // ARDUINO_ARCH_ESP32
+1 -5
View File
@@ -29,7 +29,7 @@
#include "wifi.h"
#include <ESPAsyncWebServer.h>
WebSocketSerial webSocketSerial;
MSerialT webSocketSerial(false);
AsyncWebSocket ws("/ws"); // TODO Move inside the class.
// RingBuffer impl
@@ -144,9 +144,5 @@ size_t WebSocketSerial::write(const uint8_t* buffer, size_t size) {
return written;
}
void WebSocketSerial::flushTX() {
// No need to do anything as there's no benefit to sending partial lines over the websocket connection.
}
#endif // WIFISUPPORT
#endif // ARDUINO_ARCH_ESP32
+3 -4
View File
@@ -22,6 +22,7 @@
#pragma once
#include "../../inc/MarlinConfig.h"
#include "../../core/serial_hook.h"
#include <Stream.h>
@@ -68,12 +69,9 @@ public:
int peek();
int read();
void flush();
void flushTX();
size_t write(const uint8_t c);
size_t write(const uint8_t* buffer, size_t size);
operator bool() { return true; }
#if ENABLED(SERIAL_STATS_DROPPED_RX)
FORCE_INLINE uint32_t dropped() { return 0; }
#endif
@@ -83,4 +81,5 @@ public:
#endif
};
extern WebSocketSerial webSocketSerial;
typedef Serial0Type<WebSocketSerial> MSerialT;
extern MSerialT webSocketSerial;
+3
View File
@@ -52,6 +52,9 @@
// Set pin as input with pullup wrapper
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
// Set pin as input with pulldown (substitution)
#define SET_INPUT_PULLDOWN SET_INPUT
// Set pin as output wrapper
#define SET_OUTPUT(IO) do{ _SET_OUTPUT(IO); }while(0)
+4 -4
View File
@@ -18,7 +18,7 @@
*/
#pragma once
#define SS_PIN SDSS
#define SCK_PIN 18
#define MISO_PIN 19
#define MOSI_PIN 23
#define SD_SS_PIN SDSS
#define SD_SCK_PIN 18
#define SD_MISO_PIN 19
#define SD_MOSI_PIN 23
+1 -1
View File
@@ -45,7 +45,7 @@ const tTimerConfig TimerConfig [NUM_HARDWARE_TIMERS] = {
{ TIMER_GROUP_0, TIMER_0, STEPPER_TIMER_PRESCALE, stepTC_Handler }, // 0 - Stepper
{ TIMER_GROUP_0, TIMER_1, TEMP_TIMER_PRESCALE, tempTC_Handler }, // 1 - Temperature
{ TIMER_GROUP_1, TIMER_0, PWM_TIMER_PRESCALE, pwmTC_Handler }, // 2 - PWM
{ TIMER_GROUP_1, TIMER_1, 1, nullptr }, // 3
{ TIMER_GROUP_1, TIMER_1, TONE_TIMER_PRESCALE, toneTC_Handler }, // 3 - Tone
};
// ------------------------
+14 -3
View File
@@ -44,6 +44,9 @@ typedef uint64_t hal_timer_t;
#ifndef PWM_TIMER_NUM
#define PWM_TIMER_NUM 2 // index of timer to use for PWM outputs
#endif
#ifndef TONE_TIMER_NUM
#define TONE_TIMER_NUM 3 // index of timer for beeper tones
#endif
#define HAL_TIMER_RATE APB_CLK_FREQ // frequency of timer peripherals
@@ -59,6 +62,8 @@ typedef uint64_t hal_timer_t;
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
#define TONE_TIMER_PRESCALE 1000 // Arbitrary value, no idea what i'm doing here
#define TEMP_TIMER_PRESCALE 1000 // prescaler for setting Temp timer, 72Khz
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
@@ -90,10 +95,16 @@ typedef uint64_t hal_timer_t;
#ifndef HAL_PWM_TIMER_ISR
#define HAL_PWM_TIMER_ISR() extern "C" void pwmTC_Handler()
#endif
#ifndef HAL_TONE_TIMER_ISR
#define HAL_TONE_TIMER_ISR() extern "C" void toneTC_Handler()
#endif
extern "C" void tempTC_Handler();
extern "C" void stepTC_Handler();
extern "C" void pwmTC_Handler();
extern "C" {
void tempTC_Handler();
void stepTC_Handler();
void pwmTC_Handler();
void toneTC_Handler();
}
// ------------------------
// Types
+4
View File
@@ -23,6 +23,10 @@
#include "platforms.h"
#ifndef GCC_VERSION
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#include HAL_PATH(.,HAL.h)
#ifdef SERIAL_PORT_2
+7 -12
View File
@@ -24,21 +24,16 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
HalSerial usb_serial;
MSerialT usb_serial(TERN0(EMERGENCY_PARSER, true));
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
}
extern "C" void u8g_MicroDelay() {
u8g_xMicroDelay(1);
}
extern "C" void u8g_10MicroDelay() {
u8g_xMicroDelay(10);
}
extern "C" void u8g_Delay(uint16_t val) {
delay(val);
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
+10 -9
View File
@@ -60,7 +60,7 @@ uint8_t _getc();
#define SHARED_SERVOS HAS_SERVOS
extern HalSerial usb_serial;
extern MSerialT usb_serial;
#define MYSERIAL0 usb_serial
#define ST7920_DELAY_1 DELAY_NS(600)
@@ -79,10 +79,16 @@ extern HalSerial usb_serial;
inline void HAL_init() {}
// Utility functions
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#pragma GCC diagnostic pop
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
// ADC
#define HAL_ADC_VREF 5.0
@@ -107,8 +113,3 @@ inline void HAL_reboot() {} // reboot the board or restart the bootloader
FORCE_INLINE static void DELAY_CYCLES(uint64_t x) {
Clock::delayCycles(x);
}
// Add strcmp_P if missing
#ifndef strcmp_P
#define strcmp_P(a, b) strcmp((a), (b))
#endif
+5 -25
View File
@@ -67,34 +67,14 @@ void cli(); // Disable
void sei(); // Enable
void attachInterrupt(uint32_t pin, void (*callback)(), uint32_t mode);
void detachInterrupt(uint32_t pin);
extern "C" void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
extern "C" void GpioDisableInt(uint32_t port, uint32_t pin);
// Program Memory
#define pgm_read_ptr(addr) (*((void**)(addr)))
#define pgm_read_byte_near(addr) (*((uint8_t*)(addr)))
#define pgm_read_float_near(addr) (*((float*)(addr)))
#define pgm_read_word_near(addr) (*((uint16_t*)(addr)))
#define pgm_read_dword_near(addr) (*((uint32_t*)(addr)))
#define pgm_read_byte(addr) pgm_read_byte_near(addr)
#define pgm_read_float(addr) pgm_read_float_near(addr)
#define pgm_read_word(addr) pgm_read_word_near(addr)
#define pgm_read_dword(addr) pgm_read_dword_near(addr)
using std::memcpy;
#define memcpy_P memcpy
#define sprintf_P sprintf
#define strstr_P strstr
#define strncpy_P strncpy
#define vsnprintf_P vsnprintf
#define strcpy_P strcpy
#define snprintf_P snprintf
#define strlen_P strlen
extern "C" {
void GpioEnableInt(uint32_t port, uint32_t pin, uint32_t mode);
void GpioDisableInt(uint32_t port, uint32_t pin);
}
// Time functions
extern "C" {
void delay(const int milis);
}
extern "C" void delay(const int milis);
void _delay_ms(const int delay);
void delayMicroseconds(unsigned long);
uint32_t millis();
+6 -96
View File
@@ -25,6 +25,7 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../../feature/e_parser.h"
#endif
#include "../../../core/serial_hook.h"
#include <stdarg.h>
#include <stdio.h>
@@ -73,19 +74,11 @@ private:
volatile uint32_t index_read;
};
class HalSerial {
public:
#if ENABLED(EMERGENCY_PARSER)
EmergencyParser::State emergency_state;
static inline bool emergency_parser_enabled() { return true; }
#endif
struct HalSerial {
HalSerial() { host_connected = true; }
void begin(int32_t) {}
void end() {}
void end() {}
int peek() {
uint8_t value;
@@ -100,7 +93,7 @@ public:
return transmit_buffer.write(c);
}
operator bool() { return host_connected; }
bool connected() { return host_connected; }
uint16_t available() {
return (uint16_t)receive_buffer.available();
@@ -117,92 +110,9 @@ public:
while (transmit_buffer.available()) { /* nada */ }
}
void printf(const char *format, ...) {
static char buffer[256];
va_list vArgs;
va_start(vArgs, format);
int length = vsnprintf((char *) buffer, 256, (char const *) format, vArgs);
va_end(vArgs);
if (length > 0 && length < 256) {
if (host_connected) {
for (int i = 0; i < length;) {
if (transmit_buffer.write(buffer[i])) {
++i;
}
}
}
}
}
#define DEC 10
#define HEX 16
#define OCT 8
#define BIN 2
void print_bin(uint32_t value, uint8_t num_digits) {
uint32_t mask = 1 << (num_digits -1);
for (uint8_t i = 0; i < num_digits; i++) {
if (!(i % 4) && i) write(' ');
if (!(i % 16) && i) write(' ');
if (value & mask) write('1');
else write('0');
value <<= 1;
}
}
void print(const char value[]) { printf("%s" , value); }
void print(char value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 8);
else if (nbase == OCT) printf("%3o", value);
else if (nbase == HEX) printf("%2X", value);
else if (nbase == DEC ) printf("%d", value);
else printf("%c" , value);
}
void print(unsigned char value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 8);
else if (nbase == OCT) printf("%3o", value);
else if (nbase == HEX) printf("%2X", value);
else printf("%u" , value);
}
void print(int value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 16);
else if (nbase == OCT) printf("%6o", value);
else if (nbase == HEX) printf("%4X", value);
else printf("%d", value);
}
void print(unsigned int value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 16);
else if (nbase == OCT) printf("%6o", value);
else if (nbase == HEX) printf("%4X", value);
else printf("%u" , value);
}
void print(long value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 32);
else if (nbase == OCT) printf("%11o", value);
else if (nbase == HEX) printf("%8X", value);
else printf("%ld" , value);
}
void print(unsigned long value, int nbase = 0) {
if (nbase == BIN) print_bin(value, 32);
else if (nbase == OCT) printf("%11o", value);
else if (nbase == HEX) printf("%8X", value);
else printf("%lu" , value);
}
void print(float value, int round = 6) { printf("%f" , value); }
void print(double value, int round = 6) { printf("%f" , value); }
void println(const char value[]) { printf("%s\n" , value); }
void println(char value, int nbase = 0) { print(value, nbase); println(); }
void println(unsigned char value, int nbase = 0) { print(value, nbase); println(); }
void println(int value, int nbase = 0) { print(value, nbase); println(); }
void println(unsigned int value, int nbase = 0) { print(value, nbase); println(); }
void println(long value, int nbase = 0) { print(value, nbase); println(); }
void println(unsigned long value, int nbase = 0) { print(value, nbase); println(); }
void println(float value, int round = 6) { printf("%f\n" , value); }
void println(double value, int round = 6) { printf("%f\n" , value); }
void println() { print('\n'); }
volatile RingBuffer<uint8_t, 128> receive_buffer;
volatile RingBuffer<uint8_t, 128> transmit_buffer;
volatile bool host_connected;
};
typedef Serial0Type<HalSerial> MSerialT;
+11 -13
View File
@@ -1,6 +1,5 @@
/**
* Marlin 3D Printer Firmware
*
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* This program is free software: you can redistribute it and/or modify
@@ -19,22 +18,23 @@
*/
#ifdef __PLAT_LINUX__
extern void setup();
extern void loop();
#include <thread>
#include <iostream>
#include <fstream>
//#define GPIO_LOGGING // Full GPIO and Positional Logging
#include "../../inc/MarlinConfig.h"
#include <stdio.h>
#include <stdarg.h>
#include "../shared/Delay.h"
#include "hardware/IOLoggerCSV.h"
#include "hardware/Heater.h"
#include "hardware/LinearAxis.h"
#include <stdio.h>
#include <stdarg.h>
#include <thread>
#include <iostream>
#include <fstream>
extern void setup();
extern void loop();
// simple stdout / stdin implementation for fake serial port
void write_serial_thread() {
for (;;) {
@@ -64,8 +64,6 @@ void simulation_loop() {
LinearAxis z_axis(Z_ENABLE_PIN, Z_DIR_PIN, Z_STEP_PIN, Z_MIN_PIN, Z_MAX_PIN);
LinearAxis extruder0(E0_ENABLE_PIN, E0_DIR_PIN, E0_STEP_PIN, P_NC, P_NC);
//#define GPIO_LOGGING // Full GPIO and Positional Logging
#ifdef GPIO_LOGGING
IOLoggerCSV logger("all_gpio_log.csv");
Gpio::attachLogger(&logger);
@@ -88,7 +86,7 @@ void simulation_loop() {
#ifdef GPIO_LOGGING
if (x_axis.position != x || y_axis.position != y || z_axis.position != z) {
uint64_t update = MAX3(x_axis.last_update, y_axis.last_update, z_axis.last_update);
uint64_t update = _MAX(x_axis.last_update, y_axis.last_update, z_axis.last_update);
position_log << update << ", " << x_axis.position << ", " << y_axis.position << ", " << z_axis.position << std::endl;
position_log.flush();
x = x_axis.position;
+17 -16
View File
@@ -24,31 +24,32 @@
#include "../../core/macros.h"
#include "../../inc/MarlinConfigPre.h"
#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
#if BOTH(HAS_MARLINUI_U8GLIB, SDSUPPORT) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
// needed due to the speed and mode required for communicating with each device being different.
// This requirement can be removed if the SPI access to these devices is updated to use
// spiBeginTransaction.
#endif
/** onboard SD card */
//#define SCK_PIN P0_07
//#define MISO_PIN P0_08
//#define MOSI_PIN P0_09
//#define SS_PIN P0_06
/** external */
#ifndef SCK_PIN
#define SCK_PIN 50
// 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
#endif
#ifndef MISO_PIN
#define MISO_PIN 51
#ifndef SD_MISO_PIN
#define SD_MISO_PIN 51
#endif
#ifndef MOSI_PIN
#define MOSI_PIN 52
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN 52
#endif
#ifndef SS_PIN
#define SS_PIN 53
#ifndef SD_SS_PIN
#define SD_SS_PIN 53
#endif
#ifndef SDSS
#define SDSS SS_PIN
#define SDSS SD_SS_PIN
#endif
+8 -11
View File
@@ -29,21 +29,18 @@
#include "watchdog.h"
#endif
DefaultSerial USBSerial(false, UsbSerial);
uint32_t HAL_adc_reading = 0;
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
}
extern "C" void u8g_MicroDelay() {
u8g_xMicroDelay(1);
}
extern "C" void u8g_10MicroDelay() {
u8g_xMicroDelay(10);
}
extern "C" void u8g_Delay(uint16_t val) {
delay(val);
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
+25 -14
View File
@@ -47,9 +47,6 @@ extern "C" volatile uint32_t _millis;
#include <pinmapping.h>
#include <CDCSerial.h>
// i2c uses 8-bit shifted address
#define I2C_ADDRESS(A) uint8_t((A) << 1)
//
// Default graphical display delays
//
@@ -63,12 +60,15 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
typedef ForwardSerial0Type< decltype(UsbSerial) > DefaultSerial;
extern DefaultSerial USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL0 UsbSerial
#define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
@@ -77,7 +77,7 @@ extern "C" volatile uint32_t _millis;
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 UsbSerial
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
@@ -85,9 +85,19 @@ extern "C" volatile uint32_t _millis;
#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 -1 to 3. Please update your configuration."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL UsbSerial
#define LCD_SERIAL USBSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
@@ -107,10 +117,16 @@ extern "C" volatile uint32_t _millis;
//
// Utility functions
//
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#pragma GCC diagnostic pop
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
//
// ADC API
@@ -201,8 +217,3 @@ void HAL_clear_reset_source(void);
uint8_t HAL_get_reset_source(void);
inline void HAL_reboot() {} // reboot the board or restart the bootloader
// Add strcmp_P if missing
#ifndef strcmp_P
#define strcmp_P(a, b) strcmp((a), (b))
#endif
+44 -38
View File
@@ -55,27 +55,33 @@
#include <lpc17xx_pinsel.h>
#include <lpc17xx_clkpwr.h>
#include "../shared/HAL_SPI.h"
// ------------------------
// Public functions
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
#include <SoftwareSPI.h>
// Software SPI
static uint8_t SPI_speed = 0;
#include <SoftwareSPI.h>
#ifndef HAL_SPI_SPEED
#define HAL_SPI_SPEED SPI_FULL_SPEED
#endif
static uint8_t SPI_speed = HAL_SPI_SPEED;
static uint8_t spiTransfer(uint8_t b) {
return swSpiTransfer(b, SPI_speed, SCK_PIN, MISO_PIN, MOSI_PIN);
return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiBegin() {
swSpiBegin(SCK_PIN, MISO_PIN, MOSI_PIN);
swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
}
void spiInit(uint8_t spiRate) {
SPI_speed = swSpiInit(spiRate, SCK_PIN, MOSI_PIN);
SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN);
}
uint8_t spiRec() { return spiTransfer(0xFF); }
@@ -100,14 +106,20 @@
#else
void spiBegin() { // setup SCK, MOSI & MISO pins for SSP0
spiInit(SPI_SPEED);
}
#ifndef HAL_SPI_SPEED
#ifdef SD_SPI_SPEED
#define HAL_SPI_SPEED SD_SPI_SPEED
#else
#define HAL_SPI_SPEED SPI_FULL_SPEED
#endif
#endif
void spiBegin() { spiInit(HAL_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0
void spiInit(uint8_t spiRate) {
#if MISO_PIN == BOARD_SPI1_MISO_PIN
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPI.setModule(1);
#elif MISO_PIN == BOARD_SPI2_MISO_PIN
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPI.setModule(2);
#endif
SPI.setDataSize(DATA_SIZE_8BIT);
@@ -127,11 +139,9 @@
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
}
void spiSend(uint32_t chan, byte b) {
}
void spiSend(uint32_t chan, byte b) {}
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {
}
void spiSend(uint32_t chan, const uint8_t* buf, size_t nbyte) {}
// Read single byte from SPI
uint8_t spiRec() { return doio(0xFF); }
@@ -143,9 +153,7 @@
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
}
uint8_t spiTransfer(uint8_t b) {
return doio(b);
}
uint8_t spiTransfer(uint8_t b) { return doio(b); }
// Write from buffer to SPI
void spiSendBlock(uint8_t token, const uint8_t* buf) {
@@ -154,10 +162,9 @@
(void)spiTransfer(buf[i]);
}
/** Begin SPI transaction, set clock, bit order, data mode */
// Begin SPI transaction, set clock, bit order, data mode
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
// TODO: to be implemented
// TODO: Implement this method
}
#endif // LPC_SOFTWARE_SPI
@@ -201,6 +208,15 @@ SPIClass::SPIClass(uint8_t device) {
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
}
void SPIClass::begin() {
// Init the SPI pins in the first begin call
if ((_currentSetting->spi_d == LPC_SSP0 && spiInitialised[0] == false) ||
@@ -331,25 +347,15 @@ void SPIClass::read(uint8_t *buf, uint32_t len) {
for (uint16_t i = 0; i < len; i++) buf[i] = transfer(0xFF);
}
void SPIClass::setClock(uint32_t clock) {
_currentSetting->clock = clock;
}
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::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::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
void SPIClass::setDataMode(uint8_t dataMode) {
_currentSetting->dataMode = dataMode;
}
void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
void SPIClass::setDataSize(uint32_t ds) {
_currentSetting->dataSize = ds;
}
void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
/**
* Set up/tear down
@@ -397,9 +403,9 @@ void SPIClass::updateSettings() {
SSP_Init(_currentSetting->spi_d, &HW_SPI_init); // puts the values into the proper bits in the SSP0 registers
}
#if MISO_PIN == BOARD_SPI1_MISO_PIN
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
SPIClass SPI(1);
#elif MISO_PIN == BOARD_SPI2_MISO_PIN
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
SPIClass SPI(2);
#endif
+45
View File
@@ -0,0 +1,45 @@
/**
* 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 <SPI.h>
/**
* 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.
*
*/
using MarlinSPI = SPIClass;
+8 -19
View File
@@ -25,31 +25,20 @@
#include "MarlinSerial.h"
#if USING_SERIAL_0
MarlinSerial MSerial(LPC_UART0);
extern "C" void UART0_IRQHandler() {
MSerial.IRQHandler();
}
MSerialT MSerial(true, LPC_UART0);
extern "C" void UART0_IRQHandler() { MSerial.IRQHandler(); }
#endif
#if USING_SERIAL_1
MarlinSerial MSerial1((LPC_UART_TypeDef *) LPC_UART1);
extern "C" void UART1_IRQHandler() {
MSerial1.IRQHandler();
}
MSerialT MSerial1(true, (LPC_UART_TypeDef *) LPC_UART1);
extern "C" void UART1_IRQHandler() { MSerial1.IRQHandler(); }
#endif
#if USING_SERIAL_2
MarlinSerial MSerial2(LPC_UART2);
extern "C" void UART2_IRQHandler() {
MSerial2.IRQHandler();
}
MSerialT MSerial2(true, LPC_UART2);
extern "C" void UART2_IRQHandler() { MSerial2.IRQHandler(); }
#endif
#if USING_SERIAL_3
MarlinSerial MSerial3(LPC_UART3);
extern "C" void UART3_IRQHandler() {
MSerial3.IRQHandler();
}
MSerialT MSerial3(true, LPC_UART3);
extern "C" void UART3_IRQHandler() { MSerial3.IRQHandler(); }
#endif
#endif // TARGET_LPC1768
+8 -14
View File
@@ -28,6 +28,7 @@
#if ENABLED(EMERGENCY_PARSER)
#include "../../feature/e_parser.h"
#endif
#include "../../core/serial_hook.h"
#ifndef SERIAL_PORT
#define SERIAL_PORT 0
@@ -41,27 +42,20 @@
class MarlinSerial : public HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE> {
public:
MarlinSerial(LPC_UART_TypeDef *UARTx) :
HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE>(UARTx)
#if ENABLED(EMERGENCY_PARSER)
, emergency_state(EmergencyParser::State::EP_RESET)
#endif
{ }
MarlinSerial(LPC_UART_TypeDef *UARTx) : HardwareSerial<RX_BUFFER_SIZE, TX_BUFFER_SIZE>(UARTx) { }
void end() {}
#if ENABLED(EMERGENCY_PARSER)
bool recv_callback(const char c) override {
emergency_parser.update(emergency_state, c);
emergency_parser.update(static_cast<Serial0Type<MarlinSerial> *>(this)->emergency_state, c);
return true; // do not discard character
}
EmergencyParser::State emergency_state;
static inline bool emergency_parser_enabled() { return true; }
#endif
};
extern MarlinSerial MSerial;
extern MarlinSerial MSerial1;
extern MarlinSerial MSerial2;
extern MarlinSerial MSerial3;
typedef Serial0Type<MarlinSerial> MSerialT;
extern MSerialT MSerial;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
+1 -1
View File
@@ -25,7 +25,7 @@
* 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 "levelling" scheme is used that
* 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.
+13 -13
View File
@@ -46,79 +46,79 @@ void setup_endstop_interrupts() {
#if HAS_X_MAX
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
#error "X_MAX_PIN is not INTERRUPT-capable."
#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."
#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."
#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."
#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."
#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."
#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."
#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."
#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."
#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."
#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."
#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."
#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."
#error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
#endif
_ATTACH(Z_MIN_PROBE_PIN);
#endif
@@ -20,3 +20,7 @@
*
*/
#pragma once
#if DISABLED(NO_SD_HOST_DRIVE)
#define HAS_SD_HOST_DRIVE 1
#endif
@@ -26,3 +26,10 @@
#elif EITHER(I2C_EEPROM, SPI_EEPROM)
#define USE_SHARED_EEPROM 1
#endif
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
// TODO: Which other boards are incompatible?
#if defined(MCU_LPC1768) && PRINTCOUNTER_SAVE_INTERVAL > 0
#warning "To prevent step loss, motion will pause for PRINTCOUNTER auto-save."
#define PRINTCOUNTER_SYNC 1
#endif
+7 -7
View File
@@ -24,7 +24,7 @@
#if PIO_PLATFORM_VERSION < 1001
#error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically."
#endif
#if PIO_FRAMEWORK_VERSION < 2005
#if PIO_FRAMEWORK_VERSION < 2006
#error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
#endif
@@ -97,8 +97,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#define IS_RX0(P) (P == P0_03)
#if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI)
#error "Serial port pins (0) conflict with Trinamic SPI pins!"
#elif ENABLED(MK2_MULTIPLEXER) && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
#error "Serial port pins (0) conflict with MK2 multiplexer pins!"
#elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
#error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!"
#elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN))
#error "Serial port pins (0) conflict with X/Y axis SPI pins!"
#endif
@@ -116,8 +116,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#elif HAS_WIRED_LCD
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
#error "Serial port pins (1) conflict with Encoder Buttons!"
#elif ANY_TX(1, SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK) \
|| ANY_RX(1, LCD_SDSS, LCD_PINS_RS, MISO_PIN, DOGLCD_A0, SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
#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, 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
@@ -205,8 +205,8 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#error "SDA0 overlaps with BEEPER_PIN!"
#elif IS_SCL0(BTN_ENC)
#error "SCL0 overlaps with Encoder Button!"
#elif IS_SCL0(SS_PIN)
#error "SCL0 overlaps with SS_PIN!"
#elif IS_SCL0(SD_SS_PIN)
#error "SCL0 overlaps with SD_SS_PIN!"
#elif IS_SCL0(LCD_SDSS)
#error "SCL0 overlaps with LCD_SDSS!"
#endif
+5
View File
@@ -126,6 +126,11 @@ public:
*/
SPIClass(uint8_t spiPortNumber);
/**
* Init using pins
*/
SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1);
/**
* Select and configure the current selected SPI device to use
*/
+12 -11
View File
@@ -31,17 +31,18 @@
#include <CDCSerial.h>
#include <usb/mscuser.h>
extern "C" {
#include <debug_frmwrk.h>
}
#include "../../sd/cardreader.h"
#include "../../inc/MarlinConfig.h"
#include "../../core/millis_t.h"
#include "../../sd/cardreader.h"
extern uint32_t MSC_SD_Init(uint8_t pdrv);
extern "C" int isLPC1769();
extern "C" void disk_timerproc();
extern "C" {
#include <debug_frmwrk.h>
extern "C" int isLPC1769();
extern "C" void disk_timerproc();
}
void SysTick_Callback() { disk_timerproc(); }
@@ -89,11 +90,11 @@ void HAL_init() {
//debug_frmwrk_init();
//_DBG("\n\nDebug running\n");
// Initialize the SD card chip select pins as soon as possible
#if PIN_EXISTS(SS)
OUT_WRITE(SS_PIN, HIGH);
#if PIN_EXISTS(SD_SS)
OUT_WRITE(SD_SS_PIN, HIGH);
#endif
#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SS_PIN
#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH);
#endif
@@ -122,7 +123,7 @@ void HAL_init() {
delay(1000); // Give OS time to notice
USB_Connect(TRUE);
#if DISABLED(NO_SD_HOST_DRIVE)
#if HAS_SD_HOST_DRIVE
MSC_SD_Init(0); // Enable USB SD card access
#endif
+14 -14
View File
@@ -23,7 +23,7 @@
#include "../../core/macros.h"
#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SCK_PIN || LCD_PINS_ENABLE == MOSI_PIN || DOGLCD_SCK == SCK_PIN || DOGLCD_MOSI == MOSI_PIN)
#if BOTH(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
// needed due to the speed and mode required for communicating with each device being different.
// This requirement can be removed if the SPI access to these devices is updated to use
@@ -31,24 +31,24 @@
#endif
/** onboard SD card */
//#define SCK_PIN P0_07
//#define MISO_PIN P0_08
//#define MOSI_PIN P0_09
//#define SS_PIN P0_06
//#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 SCK_PIN
#define SCK_PIN P0_15
#ifndef SD_SCK_PIN
#define SD_SCK_PIN P0_15
#endif
#ifndef MISO_PIN
#define MISO_PIN P0_17
#ifndef SD_MISO_PIN
#define SD_MISO_PIN P0_17
#endif
#ifndef MOSI_PIN
#define MOSI_PIN P0_18
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN P0_18
#endif
#ifndef SS_PIN
#define SS_PIN P1_23
#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 SS_PIN
#define SDSS SD_SS_PIN
#endif
+5 -2
View File
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,7 +22,7 @@
#include "../../../inc/MarlinConfig.h"
#if HAS_TFT_XPT2046 || HAS_TOUCH_XPT2046
#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS
#include "xpt2046.h"
#include <SPI.h>
+8 -5
View File
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,16 +28,16 @@
#endif
#ifndef TOUCH_MISO_PIN
#define TOUCH_MISO_PIN MISO_PIN
#define TOUCH_MISO_PIN SD_MISO_PIN
#endif
#ifndef TOUCH_MOSI_PIN
#define TOUCH_MOSI_PIN MOSI_PIN
#define TOUCH_MOSI_PIN SD_MOSI_PIN
#endif
#ifndef TOUCH_SCK_PIN
#define TOUCH_SCK_PIN SCK_PIN
#define TOUCH_SCK_PIN SD_SCK_PIN
#endif
#ifndef TOUCH_CS_PIN
#define TOUCH_CS_PIN CS_PIN
#define TOUCH_CS_PIN SD_SS_PIN
#endif
#ifndef TOUCH_INT_PIN
#define TOUCH_INT_PIN -1
+1 -1
View File
@@ -152,7 +152,7 @@ FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// This function is missing from CMSIS
FORCE_INLINE static bool NVIC_GetEnableIRQ(IRQn_Type IRQn) {
return (NVIC->ISER[((uint32_t)IRQn) >> 5] & (1 << ((uint32_t)IRQn) & 0x1F)) != 0;
return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
@@ -62,10 +62,13 @@
#include <U8glib.h>
#include "../../shared/HAL_SPI.h"
void spiBegin();
void spiInit(uint8_t spiRate);
void spiSend(uint8_t b);
void spiSend(const uint8_t* buf, size_t n);
#ifndef LCD_SPI_SPEED
#ifdef SD_SPI_SPEED
#define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD
#else
#define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied
#endif
#endif
uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
switch (msg) {
@@ -81,10 +84,7 @@ uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
u8g_SetPIOutput(u8g, U8G_PI_RESET);
u8g_Delay(5);
spiBegin();
#ifndef SPI_SPEED
#define SPI_SPEED SPI_FULL_SPEED // use same SPI speed as SD card
#endif
spiInit(SPI_SPEED);
spiInit(LCD_SPI_SPEED);
break;
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
@@ -62,9 +62,11 @@
#include <U8glib.h>
#include <SoftwareSPI.h>
#include "../../shared/Delay.h"
#include "../../shared/HAL_SPI.h"
#undef SPI_SPEED
#define SPI_SPEED 3 // About 1 MHz
#ifndef LCD_SPI_SPEED
#define LCD_SPI_SPEED SPI_EIGHTH_SPEED // About 1 MHz
#endif
static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
static uint8_t SPI_speed = 0;
@@ -92,7 +94,7 @@ uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t ar
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
u8g_Delay(5);
SPI_speed = swSpiInit(SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
SPI_speed = swSpiInit(LCD_SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
@@ -60,9 +60,11 @@
#if HAS_MARLINUI_U8GLIB && DISABLED(U8GLIB_ST7920)
#include <SoftwareSPI.h>
#include "../../shared/HAL_SPI.h"
#undef SPI_SPEED
#define SPI_SPEED 2 // About 2 MHz
#ifndef LCD_SPI_SPEED
#define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz
#endif
#include <Arduino.h>
#include <algorithm>
@@ -145,7 +147,7 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
u8g_SetPIOutput(u8g, U8G_PI_CS);
u8g_SetPIOutput(u8g, U8G_PI_A0);
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET);
SPI_speed = swSpiInit(SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
SPI_speed = swSpiInit(LCD_SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
break;
+33 -55
View File
@@ -23,63 +23,50 @@ def print_error(e):
%(e, env.get('PIOENV')))
try:
#
# Find a disk for upload
#
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
if current_OS == 'Windows':
#
# 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
#
#
# get all drives on this computer
#
import subprocess
# typical result (string): 'Drives: C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
driveStr = str(subprocess.check_output("fsutil fsinfo drives"))
# typical result (string): 'C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
# driveStr = driveStr.strip().lstrip('Drives: ') <- Doesn't work in other Languages as English. In German is "Drives:" = "Laufwerke:"
FirstFound = driveStr.find(':',0,-1) # Find the first ":" and
driveStr = driveStr[FirstFound + 1 : -1] # truncate to the rest
# typical result (array of stings): ['C:\\', 'D:\\', 'E:\\', 'F:\\',
# 'G:\\', 'H:\\', 'I:\\', 'J:\\', 'K:\\', 'L:\\', 'M:\\', 'Y:\\', 'Z:\\']
drives = driveStr.split()
from ctypes import windll
import string
# getting list of drives
# https://stackoverflow.com/questions/827371/is-there-a-way-to-list-all-the-available-drive-letters-in-python
drives = []
bitmask = windll.kernel32.GetLogicalDrives()
for letter in string.ascii_uppercase:
if bitmask & 1:
drives.append(letter)
bitmask >>= 1
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
for drive in drives:
final_drive_name = drive.strip().rstrip('\\') # typical result (string): 'C:'
final_drive_name = drive + ':\\'
# print ('disc check: {}'.format(final_drive_name))
try:
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
print ('error:{}'.format(e))
continue
else:
if target_drive in volume_info and target_file_found == False: # set upload if not found target file yet
if target_drive in volume_info and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = final_drive_name
if target_filename in volume_info:
if target_file_found == False:
if not target_file_found:
upload_disk = final_drive_name
target_file_found = True
#
# set upload_port to drive if found
#
if target_file_found == True or target_drive_found == True:
env.Replace(
UPLOAD_PORT=upload_disk
)
print('upload disk: ', upload_disk)
else:
print_error('Autodetect Error')
elif current_OS == 'Linux':
#
# platformio.ini will accept this for a Linux upload port designation: 'upload_port = /media/media_name/drive'
#
upload_disk = 'Disk not found'
target_file_found = False
target_drive_found = False
drives = os.listdir(os.path.join(os.sep, 'media', getpass.getuser()))
if target_drive in drives: # If target drive is found, use it.
target_drive_found = True
@@ -101,22 +88,15 @@ try:
if target_file_found or target_drive_found:
env.Replace(
UPLOAD_FLAGS="-P$UPLOAD_PORT",
UPLOAD_PORT=upload_disk
UPLOAD_FLAGS="-P$UPLOAD_PORT"
)
print('upload disk: ', upload_disk)
else:
print_error('Autodetect Error')
elif current_OS == 'Darwin': # MAC
#
# platformio.ini will accept this for a OSX upload port designation: 'upload_port = /media/media_name/drive'
#
upload_disk = 'Disk not found'
drives = os.listdir('/Volumes') # human readable names
target_file_found = False
target_drive_found = False
if target_drive in drives and target_file_found == False: # set upload if not found target file yet
if target_drive in drives and not target_file_found: # set upload if not found target file yet
target_drive_found = True
upload_disk = '/Volumes/' + target_drive + '/'
for drive in drives:
@@ -126,20 +106,18 @@ try:
continue
else:
if target_filename in filenames:
if target_file_found == False:
if not target_file_found:
upload_disk = '/Volumes/' + drive + '/'
target_file_found = True
#
# set upload_port to drive if found
#
if target_file_found == True or target_drive_found == True:
env.Replace(
UPLOAD_PORT=upload_disk
)
print('\nupload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
#
# Set upload_port to drive if found
#
if target_file_found or target_drive_found:
env.Replace(UPLOAD_PORT=upload_disk)
print('\nUpload disk: ', upload_disk, '\n')
else:
print_error('Autodetect Error')
except Exception as e:
print_error(str(e))
+5
View File
@@ -24,6 +24,11 @@
#include <Adafruit_ZeroDMA.h>
#include <wiring_private.h>
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
DefaultSerial MSerial(false, Serial);
DefaultSerial1 MSerial1(false, Serial1);
#endif
// ------------------------
// Local defines
// ------------------------
+27 -7
View File
@@ -32,15 +32,19 @@
#include "MarlinSerial_AGCM4.h"
// Serial ports
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
extern DefaultSerial1 MSerial1;
// MYSERIAL0 required before MarlinSerial includes!
#define __MSERIAL(X) Serial##X
#define __MSERIAL(X) MSerial##X
#define _MSERIAL(X) __MSERIAL(X)
#define MSERIAL(X) _MSERIAL(INCREMENT(X))
#if SERIAL_PORT == -1
#define MYSERIAL0 Serial
#define MYSERIAL0 MSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
@@ -49,7 +53,7 @@
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 Serial
#define MYSERIAL1 MSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
@@ -57,9 +61,19 @@
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL Serial
#define LCD_SERIAL MSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
@@ -135,10 +149,16 @@ void HAL_idletask();
//
FORCE_INLINE void _delay_ms(const int delay_ms) { delay(delay_ms); }
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#if GCC_VERSION <= 50000
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
int freeMemory();
#pragma GCC diagnostic pop
#if GCC_VERSION <= 50000
#pragma GCC diagnostic pop
#endif
#ifdef __cplusplus
extern "C" {
+7 -7
View File
@@ -21,30 +21,30 @@
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
/**
* Framework doesn't define some serial to save sercom resources
* Framework doesn't define some serials to save sercom resources
* hence if these are used I need to define them
*/
#include "../../inc/MarlinConfig.h"
#if SERIAL_PORT == 1 || SERIAL_PORT_2 == 1
Uart Serial2(&sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
#if USING_SERIAL_1
UartT Serial2(false, &sercom4, PIN_SERIAL2_RX, PIN_SERIAL2_TX, PAD_SERIAL2_RX, PAD_SERIAL2_TX);
void SERCOM4_0_Handler() { Serial2.IrqHandler(); }
void SERCOM4_1_Handler() { Serial2.IrqHandler(); }
void SERCOM4_2_Handler() { Serial2.IrqHandler(); }
void SERCOM4_3_Handler() { Serial2.IrqHandler(); }
#endif
#if SERIAL_PORT == 2 || SERIAL_PORT_2 == 2
Uart Serial3(&sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
#if USING_SERIAL_2
UartT Serial3(false, &sercom1, PIN_SERIAL3_RX, PIN_SERIAL3_TX, PAD_SERIAL3_RX, PAD_SERIAL3_TX);
void SERCOM1_0_Handler() { Serial3.IrqHandler(); }
void SERCOM1_1_Handler() { Serial3.IrqHandler(); }
void SERCOM1_2_Handler() { Serial3.IrqHandler(); }
void SERCOM1_3_Handler() { Serial3.IrqHandler(); }
#endif
#if SERIAL_PORT == 3 || SERIAL_PORT_2 == 3
Uart Serial4(&sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
#if USING_SERIAL_3
UartT Serial4(false, &sercom5, PIN_SERIAL4_RX, PIN_SERIAL4_TX, PAD_SERIAL4_RX, PAD_SERIAL4_TX);
void SERCOM5_0_Handler() { Serial4.IrqHandler(); }
void SERCOM5_1_Handler() { Serial4.IrqHandler(); }
void SERCOM5_2_Handler() { Serial4.IrqHandler(); }
+7 -3
View File
@@ -20,6 +20,10 @@
*/
#pragma once
extern Uart Serial2;
extern Uart Serial3;
extern Uart Serial4;
#include "../../core/serial_hook.h"
typedef Serial0Type<Uart> UartT;
extern UartT Serial2;
extern UartT Serial3;
extern UartT Serial4;
+1 -1
View File
@@ -31,7 +31,7 @@
*/
#ifndef MASK
#define MASK(PIN) (1 << PIN)
#define MASK(PIN) _BV(PIN)
#endif
/**
+8 -8
View File
@@ -30,16 +30,16 @@
* SPI | 53 52 50 51 |
* SPI1 | 83 81 80 82 |
* +-------------------------+
* Any pin can be used for Chip Select (SS_PIN)
* Any pin can be used for Chip Select (SD_SS_PIN)
*/
#ifndef SCK_PIN
#define SCK_PIN 52
#ifndef SD_SCK_PIN
#define SD_SCK_PIN 52
#endif
#ifndef MISO_PIN
#define MISO_PIN 50
#ifndef SD_MISO_PIN
#define SD_MISO_PIN 50
#endif
#ifndef MOSI_PIN
#define MOSI_PIN 51
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN 51
#endif
#ifndef SDSS
#define SDSS 53
@@ -51,4 +51,4 @@
#endif
#define SS_PIN SDSS
#define SD_SS_PIN SDSS
+1 -1
View File
@@ -157,7 +157,7 @@ void HAL_timer_disable_interrupt(const uint8_t timer_num) {
// missing from CMSIS: Check if interrupt is enabled or not
static bool NVIC_GetEnabledIRQ(IRQn_Type IRQn) {
return (NVIC->ISER[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F))) != 0;
return TEST(NVIC->ISER[uint32_t(IRQn) >> 5], uint32_t(IRQn) & 0x1F);
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
+4
View File
@@ -28,6 +28,10 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
#ifdef USBCON
DefaultSerial MSerial(false, SerialUSB);
#endif
#if ENABLED(SRAM_EEPROM_EMULATION)
#if STM32F7xx
#include <stm32f7xx_ll_pwr.h>
+22 -14
View File
@@ -29,6 +29,7 @@
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "Servo.h"
#include "watchdog.h"
#include "MarlinSerial.h"
@@ -38,6 +39,9 @@
#ifdef USBCON
#include <USBSerial.h>
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(SerialUSB) > DefaultSerial;
extern DefaultSerial MSerial;
#endif
// ------------------------
@@ -47,7 +51,7 @@
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
#define MYSERIAL0 SerialUSB
#define MYSERIAL0 MSerial
#elif WITHIN(SERIAL_PORT, 1, 6)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
@@ -56,7 +60,7 @@
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 SerialUSB
#define MYSERIAL1 MSerial
#elif WITHIN(SERIAL_PORT_2, 1, 6)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
@@ -64,9 +68,19 @@
#endif
#endif
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial
#elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
#error "MMU2_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#endif
#endif
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL SerialUSB
#define LCD_SERIAL MSerial
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
@@ -95,14 +109,6 @@
// On AVR this is in math.h?
#define square(x) ((x)*(x))
#ifndef strncpy_P
#define strncpy_P(dest, src, num) strncpy((dest), (src), (num))
#endif
// Fix bug in pgm_read_ptr
#undef pgm_read_ptr
#define pgm_read_ptr(addr) (*(addr))
// ------------------------
// Types
// ------------------------
@@ -110,6 +116,8 @@
typedef int16_t pin_t;
#define HAL_SERVO_LIB libServo
#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
// ------------------------
// Public Variables
@@ -156,14 +164,14 @@ static inline int freeMemory() {
#define HAL_ANALOG_SELECT(pin) pinMode(pin, INPUT)
inline void HAL_adc_init() {}
#define HAL_ADC_VREF 3.3
#define HAL_ADC_RESOLUTION 10
#define HAL_ADC_RESOLUTION ADC_RESOLUTION // 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
inline void HAL_adc_init() { analogReadResolution(HAL_ADC_RESOLUTION); }
void HAL_adc_start_conversion(const uint8_t adc_pin);
uint16_t HAL_adc_get_result();
+13 -14
View File
@@ -45,10 +45,10 @@ static SPISettings spiConfig;
#include "../shared/Delay.h"
void spiBegin(void) {
OUT_WRITE(SS_PIN, HIGH);
OUT_WRITE(SCK_PIN, HIGH);
SET_INPUT(MISO_PIN);
OUT_WRITE(MOSI_PIN, HIGH);
OUT_WRITE(SD_SS_PIN, HIGH);
OUT_WRITE(SD_SCK_PIN, HIGH);
SET_INPUT(SD_MISO_PIN);
OUT_WRITE(SD_MOSI_PIN, HIGH);
}
static uint16_t delay_STM32_soft_spi;
@@ -72,15 +72,15 @@ static SPISettings spiConfig;
uint8_t HAL_SPI_STM32_SpiTransfer_Mode_3(uint8_t b) { // using Mode 3
for (uint8_t bits = 8; bits--;) {
WRITE(SCK_PIN, LOW);
WRITE(MOSI_PIN, b & 0x80);
WRITE(SD_SCK_PIN, LOW);
WRITE(SD_MOSI_PIN, b & 0x80);
DELAY_NS(delay_STM32_soft_spi);
WRITE(SCK_PIN, HIGH);
WRITE(SD_SCK_PIN, HIGH);
DELAY_NS(delay_STM32_soft_spi);
b <<= 1; // little setup time
b |= (READ(MISO_PIN) != 0);
b |= (READ(SD_MISO_PIN) != 0);
}
DELAY_NS(125);
return b;
@@ -132,8 +132,8 @@ static SPISettings spiConfig;
* @details Only configures SS pin since stm32duino creates and initialize the SPI object
*/
void spiBegin() {
#if PIN_EXISTS(SS)
OUT_WRITE(SS_PIN, HIGH);
#if PIN_EXISTS(SD_SS)
OUT_WRITE(SD_SS_PIN, HIGH);
#endif
}
@@ -154,10 +154,9 @@ static SPISettings spiConfig;
spiConfig = SPISettings(clock, MSBFIRST, SPI_MODE0);
#if ENABLED(CUSTOM_SPI_PINS)
SPI.setMISO(MISO_PIN);
SPI.setMOSI(MOSI_PIN);
SPI.setSCLK(SCK_PIN);
SPI.setSSEL(SS_PIN);
SPI.setMISO(SD_MISO_PIN);
SPI.setMOSI(SD_MOSI_PIN);
SPI.setSCLK(SD_SCK_PIN);
#endif
SPI.begin();
+168
View File
@@ -0,0 +1,168 @@
/**
* 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/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "MarlinSPI.h"
static void spi_init(spi_t *obj, uint32_t speed, spi_mode_e mode, uint8_t msb, uint32_t dataSize) {
spi_init(obj, speed, mode, msb);
// spi_init set 8bit always
// TODO: copy the code from spi_init and handle data size, to avoid double init always!!
if (dataSize != SPI_DATASIZE_8BIT) {
obj->handle.Init.DataSize = dataSize;
HAL_SPI_Init(&obj->handle);
__HAL_SPI_ENABLE(&obj->handle);
}
}
void MarlinSPI::setClockDivider(uint8_t _div) {
_speed = spi_getClkFreq(&_spi);// / _div;
_clockDivider = _div;
}
void MarlinSPI::begin(void) {
//TODO: only call spi_init if any parameter changed!!
spi_init(&_spi, _speed, _dataMode, _bitOrder, _dataSize);
}
void MarlinSPI::setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc) {
_dmaHandle.Init.Direction = direction;
_dmaHandle.Init.PeriphInc = DMA_PINC_DISABLE;
_dmaHandle.Init.Mode = DMA_NORMAL;
_dmaHandle.Init.Priority = DMA_PRIORITY_LOW;
_dmaHandle.Init.MemInc = minc ? DMA_MINC_ENABLE : DMA_MINC_DISABLE;
if (_dataSize == DATA_SIZE_8BIT) {
_dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
}
else {
_dmaHandle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
_dmaHandle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
}
#ifdef STM32F4xx
_dmaHandle.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
#endif
// start DMA hardware
// TODO: check if hardware is already enabled
#ifdef SPI1_BASE
if (_spiHandle.Instance == SPI1) {
#ifdef STM32F1xx
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel3 : DMA1_Channel2;
#elif defined(STM32F4xx)
__HAL_RCC_DMA2_CLK_ENABLE();
_dmaHandle.Init.Channel = DMA_CHANNEL_3;
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Stream3 : DMA2_Stream0;
#endif
}
#endif
#ifdef SPI2_BASE
if (_spiHandle.Instance == SPI2) {
#ifdef STM32F1xx
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Channel5 : DMA1_Channel4;
#elif defined(STM32F4xx)
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Init.Channel = DMA_CHANNEL_0;
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream4 : DMA1_Stream3;
#endif
}
#endif
#ifdef SPI3_BASE
if (_spiHandle.Instance == SPI3) {
#ifdef STM32F1xx
__HAL_RCC_DMA2_CLK_ENABLE();
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA2_Channel2 : DMA2_Channel1;
#elif defined(STM32F4xx)
__HAL_RCC_DMA1_CLK_ENABLE();
_dmaHandle.Init.Channel = DMA_CHANNEL_0;
_dmaHandle.Instance = (direction == DMA_MEMORY_TO_PERIPH) ? DMA1_Stream5 : DMA1_Stream2;
#endif
}
#endif
HAL_DMA_Init(&_dmaHandle);
}
byte MarlinSPI::transfer(uint8_t _data) {
uint8_t rxData = 0xFF;
HAL_SPI_TransmitReceive(&_spi.handle, &_data, &rxData, 1, HAL_MAX_DELAY);
return rxData;
}
uint8_t MarlinSPI::dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length) {
const uint8_t ff = 0xFF;
//if ((hspi->Instance->CR1 & SPI_CR1_SPE) != SPI_CR1_SPE) //only enable if disabled
__HAL_SPI_ENABLE(&_spi.handle);
if (receiveBuf) {
setupDma(_spi.handle, _dmaRx, DMA_PERIPH_TO_MEMORY, true);
HAL_DMA_Start(&_dmaRx, (uint32_t)&(_spi.handle.Instance->DR), (uint32_t)receiveBuf, length);
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_RXDMAEN); /* Enable Rx DMA Request */
}
// check for 2 lines transfer
bool mincTransmit = true;
if (transmitBuf == nullptr && _spi.handle.Init.Direction == SPI_DIRECTION_2LINES && _spi.handle.Init.Mode == SPI_MODE_MASTER) {
transmitBuf = &ff;
mincTransmit = false;
}
if (transmitBuf) {
setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, mincTransmit);
HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
}
if (transmitBuf) {
HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Abort(&_dmaTx);
HAL_DMA_DeInit(&_dmaTx);
}
// while ((_spi.handle.Instance->SR & SPI_FLAG_RXNE) != SPI_FLAG_RXNE) {}
if (receiveBuf) {
HAL_DMA_PollForTransfer(&_dmaRx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Abort(&_dmaRx);
HAL_DMA_DeInit(&_dmaRx);
}
return 1;
}
uint8_t MarlinSPI::dmaSend(const void * transmitBuf, uint16_t length, bool minc) {
setupDma(_spi.handle, _dmaTx, DMA_MEMORY_TO_PERIPH, minc);
HAL_DMA_Start(&_dmaTx, (uint32_t)transmitBuf, (uint32_t)&(_spi.handle.Instance->DR), length);
__HAL_SPI_ENABLE(&_spi.handle);
SET_BIT(_spi.handle.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
HAL_DMA_PollForTransfer(&_dmaTx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Abort(&_dmaTx);
// DeInit objects
HAL_DMA_DeInit(&_dmaTx);
return 1;
}
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+107
View File
@@ -0,0 +1,107 @@
/**
* 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 "HAL.h"
#include <SPI.h>
extern "C" {
#include <utility/spi_com.h>
}
/**
* 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.
*
*/
#define DATA_SIZE_8BIT SPI_DATASIZE_8BIT
#define DATA_SIZE_16BIT SPI_DATASIZE_16BIT
class MarlinSPI {
public:
MarlinSPI() : MarlinSPI(NC, NC, NC, NC) {}
MarlinSPI(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)NC) : _mosiPin(mosi), _misoPin(miso), _sckPin(sclk), _ssPin(ssel) {
_spi.pin_miso = digitalPinToPinName(_misoPin);
_spi.pin_mosi = digitalPinToPinName(_mosiPin);
_spi.pin_sclk = digitalPinToPinName(_sckPin);
_spi.pin_ssel = digitalPinToPinName(_ssPin);
_dataSize = DATA_SIZE_8BIT;
_bitOrder = MSBFIRST;
_dataMode = SPI_MODE_0;
_spi.handle.State = HAL_SPI_STATE_RESET;
setClockDivider(SPI_SPEED_CLOCK_DIV2_MHZ);
}
void begin(void);
void end(void) {}
byte transfer(uint8_t _data);
uint8_t dmaTransfer(const void *transmitBuf, void *receiveBuf, uint16_t length);
uint8_t dmaSend(const void * transmitBuf, uint16_t length, bool minc = true);
/* These methods are deprecated and kept for compatibility.
* Use SPISettings with SPI.beginTransaction() to configure SPI parameters.
*/
void setBitOrder(BitOrder _order) { _bitOrder = _order; }
void setDataMode(uint8_t _mode) {
switch (_mode) {
case SPI_MODE0: _dataMode = SPI_MODE_0; break;
case SPI_MODE1: _dataMode = SPI_MODE_1; break;
case SPI_MODE2: _dataMode = SPI_MODE_2; break;
case SPI_MODE3: _dataMode = SPI_MODE_3; break;
}
}
void setClockDivider(uint8_t _div);
private:
void setupDma(SPI_HandleTypeDef &_spiHandle, DMA_HandleTypeDef &_dmaHandle, uint32_t direction, bool minc = false);
spi_t _spi;
DMA_HandleTypeDef _dmaTx;
DMA_HandleTypeDef _dmaRx;
BitOrder _bitOrder;
spi_mode_e _dataMode;
uint8_t _clockDivider;
uint32_t _speed;
uint32_t _dataSize;
pin_t _mosiPin;
pin_t _misoPin;
pin_t _sckPin;
pin_t _ssPin;
};
+5 -2
View File
@@ -16,7 +16,6 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfig.h"
@@ -36,7 +35,7 @@
#define DECLARE_SERIAL_PORT(ser_num) \
void _rx_complete_irq_ ## ser_num (serial_t * obj); \
MarlinSerial MSerial ## ser_num (USART ## ser_num, &_rx_complete_irq_ ## ser_num); \
MSerialT MSerial ## ser_num (true, USART ## ser_num, &_rx_complete_irq_ ## ser_num); \
void _rx_complete_irq_ ## ser_num (serial_t * obj) { MSerial ## ser_num ._rx_complete_irq(obj); }
#define DECLARE_SERIAL_PORT_EXP(ser_num) DECLARE_SERIAL_PORT(ser_num)
@@ -49,6 +48,10 @@
DECLARE_SERIAL_PORT_EXP(SERIAL_PORT_2)
#endif
#if defined(MMU2_SERIAL_PORT) && MMU2_SERIAL_PORT >= 0
DECLARE_SERIAL_PORT_EXP(MMU2_SERIAL_PORT)
#endif
#if defined(LCD_SERIAL_PORT) && LCD_SERIAL_PORT >= 0
DECLARE_SERIAL_PORT_EXP(LCD_SERIAL_PORT)
#endif
+15 -23
View File
@@ -24,21 +24,15 @@
#include "../../feature/e_parser.h"
#endif
#include "../../core/serial_hook.h"
typedef void (*usart_rx_callback_t)(serial_t * obj);
class MarlinSerial : public HardwareSerial {
public:
struct MarlinSerial : public HardwareSerial {
MarlinSerial(void* peripheral, usart_rx_callback_t rx_callback) :
HardwareSerial(peripheral), _rx_callback(rx_callback)
#if ENABLED(EMERGENCY_PARSER)
, emergency_state(EmergencyParser::State::EP_RESET)
#endif
{ }
#if ENABLED(EMERGENCY_PARSER)
static inline bool emergency_parser_enabled() { return true; }
#endif
void begin(unsigned long baud, uint8_t config);
inline void begin(unsigned long baud) { begin(baud, SERIAL_8N1); }
@@ -46,19 +40,17 @@ public:
protected:
usart_rx_callback_t _rx_callback;
#if ENABLED(EMERGENCY_PARSER)
EmergencyParser::State emergency_state;
#endif
};
extern MarlinSerial MSerial1;
extern MarlinSerial MSerial2;
extern MarlinSerial MSerial3;
extern MarlinSerial MSerial4;
extern MarlinSerial MSerial5;
extern MarlinSerial MSerial6;
extern MarlinSerial MSerial7;
extern MarlinSerial MSerial8;
extern MarlinSerial MSerial9;
extern MarlinSerial MSerial10;
extern MarlinSerial MSerialLP1;
typedef Serial0Type<MarlinSerial> MSerialT;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
extern MSerialT MSerial4;
extern MSerialT MSerial5;
extern MSerialT MSerial6;
extern MSerialT MSerial7;
extern MSerialT MSerial8;
extern MSerialT MSerial9;
extern MSerialT MSerial10;
extern MSerialT MSerialLP1;
@@ -19,10 +19,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDIO_SUPPORT) && !defined(STM32GENERIC)
#if ENABLED(SDIO_SUPPORT)
#include <stdint.h>
#include <stdbool.h>
@@ -31,7 +32,7 @@
#error "ERROR - Only STM32F103xE, STM32F103xG, STM32F4xx or STM32F7xx CPUs supported"
#endif
#ifdef USBD_USE_CDC_COMPOSITE
#if HAS_SD_HOST_DRIVE
// use USB drivers
@@ -87,18 +88,37 @@
MKS Robin board seems to have stable SDIO with BusWide 1bit and ClockDiv 8 i.e. 4.8MHz SDIO clock frequency
Additional testing is required as there are clearly some 4bit initialization problems
Add -DTRANSFER_CLOCK_DIV=8 to build parameters to improve SDIO stability
*/
#ifndef TRANSFER_CLOCK_DIV
#define TRANSFER_CLOCK_DIV (uint8_t(SDIO_INIT_CLK_DIV) / 40)
#endif
#ifndef USBD_OK
#define USBD_OK 0
#endif
// Target Clock, configurable. Default is 18MHz, from STM32F1
#ifndef SDIO_CLOCK
#define SDIO_CLOCK 18000000 /* 18 MHz */
#endif
// SDIO retries, configurable. Default is 3, from STM32F1
#ifndef SDIO_READ_RETRIES
#define SDIO_READ_RETRIES 3
#endif
// SDIO Max Clock (naming from STM Manual, don't change)
#define SDIOCLK 48000000
static uint32_t clock_to_divider(uint32_t clk) {
// limit the SDIO master clock to 8/3 of PCLK2. See STM32 Manuals
// Also limited to no more than 48Mhz (SDIOCLK).
const uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
clk = min(clk, (uint32_t)(pclk2 * 8 / 3));
clk = min(clk, (uint32_t)SDIOCLK);
// Round up divider, so we don't run the card over the speed supported,
// and subtract by 2, because STM32 will add 2, as written in the manual:
// SDIO_CK frequency = SDIOCLK / [CLKDIV + 2]
return pclk2 / clk + (pclk2 % clk != 0) - 2;
}
void go_to_transfer_speed() {
SD_InitTypeDef Init;
@@ -108,7 +128,7 @@
Init.ClockPowerSave = hsd.Init.ClockPowerSave;
Init.BusWide = hsd.Init.BusWide;
Init.HardwareFlowControl = hsd.Init.HardwareFlowControl;
Init.ClockDiv = TRANSFER_CLOCK_DIV;
Init.ClockDiv = clock_to_divider(SDIO_CLOCK);
/* Initialize SDIO peripheral interface with default configuration */
SDIO_Init(hsd.Instance, Init);
@@ -154,38 +174,25 @@
//Initialize the SDIO (with initial <400Khz Clock)
tempreg = 0; //Reset value
tempreg |= SDIO_CLKCR_CLKEN; // Clock enabled
tempreg |= (uint32_t)0x76; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
tempreg |= SDIO_INIT_CLK_DIV; // Clock Divider. Clock = 48000 / (118 + 2) = 400Khz
// Keep the rest at 0 => HW_Flow Disabled, Rising Clock Edge, Disable CLK ByPass, Bus Width = 0, Power save Disable
SDIO->CLKCR = tempreg;
// Power up the SDIO
SDIO->POWER = 0x03;
SDIO_PowerState_ON(SDIO);
}
void HAL_SD_MspInit(SD_HandleTypeDef *hsd) { // application specific init
UNUSED(hsd); /* Prevent unused argument(s) compilation warning */
UNUSED(hsd); // Prevent unused argument(s) compilation warning
__HAL_RCC_SDIO_CLK_ENABLE(); // turn on SDIO clock
}
constexpr uint8_t SD_RETRY_COUNT = TERN(SD_CHECK_AND_RETRY, 3, 1);
bool SDIO_Init() {
//init SDIO and get SD card info
uint8_t retryCnt = SD_RETRY_COUNT;
uint8_t retryCnt = SDIO_READ_RETRIES;
bool status;
hsd.Instance = SDIO;
hsd.State = (HAL_SD_StateTypeDef) 0; // HAL_SD_STATE_RESET
/*
hsd.Init.ClockEdge = SDIO_CLOCK_EDGE_RISING;
hsd.Init.ClockBypass = SDIO_CLOCK_BYPASS_DISABLE;
hsd.Init.ClockPowerSave = SDIO_CLOCK_POWER_SAVE_DISABLE;
hsd.Init.BusWide = SDIO_BUS_WIDE_1B;
hsd.Init.HardwareFlowControl = SDIO_HARDWARE_FLOW_CONTROL_DISABLE;
hsd.Init.ClockDiv = 8;
*/
hsd.State = HAL_SD_STATE_RESET;
SD_LowLevel_Init();
@@ -257,7 +264,7 @@
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst) {
hsd.Instance = SDIO;
uint8_t retryCnt = SD_RETRY_COUNT;
uint8_t retryCnt = SDIO_READ_RETRIES;
bool status;
for (;;) {
@@ -306,7 +313,7 @@
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src) {
hsd.Instance = SDIO;
uint8_t retryCnt = SD_RETRY_COUNT;
uint8_t retryCnt = SDIO_READ_RETRIES;
bool status;
for (;;) {
status = (bool) HAL_SD_WriteBlocks(&hsd, (uint8_t*)src, block, 1, 500); // write one 512 byte block with 500mS timeout
@@ -319,3 +326,4 @@
#endif // !USBD_USE_CDC_COMPOSITE
#endif // SDIO_SUPPORT
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+7 -14
View File
@@ -28,15 +28,6 @@
#include "../shared/eeprom_api.h"
#if HAS_SERVOS
#include "Servo.h"
#define PAUSE_SERVO_OUTPUT() libServo::pause_all_servos()
#define RESUME_SERVO_OUTPUT() libServo::resume_all_servos()
#else
#define PAUSE_SERVO_OUTPUT()
#define RESUME_SERVO_OUTPUT()
#endif
/**
* The STM32 HAL supports chips that deal with "pages" and some with "sectors" and some that
* even have multiple "banks" of flash.
@@ -70,7 +61,9 @@
#define FLASH_UNIT_SIZE 0x20000 // 128kB
#endif
#define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - (FLASH_SECTOR)) * (FLASH_UNIT_SIZE)) + 1)
#ifndef FLASH_ADDRESS_START
#define FLASH_ADDRESS_START (FLASH_END - ((FLASH_SECTOR_TOTAL - (FLASH_SECTOR)) * (FLASH_UNIT_SIZE)) + 1)
#endif
#define FLASH_ADDRESS_END (FLASH_ADDRESS_START + FLASH_UNIT_SIZE - 1)
#define EEPROM_SLOTS ((FLASH_UNIT_SIZE) / (MARLIN_EEPROM_SIZE))
@@ -172,11 +165,11 @@ bool PersistentStore::access_finish() {
current_slot = EEPROM_SLOTS - 1;
UNLOCK_FLASH();
PAUSE_SERVO_OUTPUT();
TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
DISABLE_ISRS();
status = HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError);
ENABLE_ISRS();
RESUME_SERVO_OUTPUT();
TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
if (status != HAL_OK) {
DEBUG_ECHOLNPAIR("HAL_FLASHEx_Erase=", status);
DEBUG_ECHOLNPAIR("GetError=", HAL_FLASH_GetError());
@@ -227,11 +220,11 @@ bool PersistentStore::access_finish() {
// Interrupts during this time can have unpredictable results, such as killing Servo
// output. Servo output still glitches with interrupts disabled, but recovers after the
// erase.
PAUSE_SERVO_OUTPUT();
TERN_(HAS_PAUSE_SERVO_OUTPUT, PAUSE_SERVO_OUTPUT());
DISABLE_ISRS();
eeprom_buffer_flush();
ENABLE_ISRS();
RESUME_SERVO_OUTPUT();
TERN_(HAS_PAUSE_SERVO_OUTPUT, RESUME_SERVO_OUTPUT());
eeprom_data_written = false;
#endif
+2 -3
View File
@@ -19,13 +19,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
/**
* Implementation of EEPROM settings in SD Card
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfig.h"
#if ENABLED(SDCARD_EEPROM_EMULATION)
@@ -89,4 +88,4 @@ bool PersistentStore::read_data(int &pos, uint8_t *value, const size_t size, uin
}
#endif // SDCARD_EEPROM_EMULATION
#endif // STM32 && !STM32GENERIC
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+2
View File
@@ -19,6 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../inc/MarlinConfigPre.h"
@@ -55,3 +56,4 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
}
#endif // NEEDS_HARDWARE_PWM
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+1 -1
View File
@@ -59,7 +59,7 @@ void FastIO_init(); // Must be called before using fast io macros
#endif
#define _READ(IO) bool(READ_BIT(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->IDR, _BV32(STM_PIN(digitalPinToPinName(IO)))))
#define _TOGGLE(IO) (FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR ^= _BV32(STM_PIN(digitalPinToPinName(IO))))
#define _TOGGLE(IO) TBI32(FastIOPortMap[STM_PORT(digitalPinToPinName(IO))]->ODR, STM_PIN(digitalPinToPinName(IO)))
#define _GET_MODE(IO)
#define _SET_MODE(IO,M) pinMode(IO, M)
@@ -20,3 +20,7 @@
*
*/
#pragma once
#if defined(USBD_USE_CDC_COMPOSITE) && DISABLED(NO_SD_HOST_DRIVE)
#define HAS_SD_HOST_DRIVE 1
#endif
+4
View File
@@ -51,3 +51,7 @@
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#endif
#if ANY(TFT_COLOR_UI, TFT_LVGL_UI, TFT_CLASSIC_UI) && NOT_TARGET(STM32F4xx, STM32F1xx)
#error "TFT_COLOR_UI, TFT_LVGL_UI and TFT_CLASSIC_UI are currently only supported on STM32F4 and STM32F1 hardware."
#endif
+239 -9
View File
@@ -18,17 +18,247 @@
*/
#pragma once
#if !(defined(NUM_DIGITAL_PINS) || defined(BOARD_NR_GPIO_PINS))
#error "M43 not supported for this board"
#include <Arduino.h>
#ifndef NUM_DIGITAL_PINS
// Only in ST's Arduino core (STM32duino, STM32Core)
#error "Expected NUM_DIGITAL_PINS not found"
#endif
// Strange - STM32F4 comes to HAL_STM32 rather than HAL_STM32F4 for these files
#ifdef STM32F4
#ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core)
#include "pinsDebug_STM32duino.h"
#elif defined(BOARD_NR_GPIO_PINS) // Only in STM32GENERIC (Maple)
#include "pinsDebug_STM32GENERIC.h"
/**
* Life gets complicated if you want an easy to use 'M43 I' output (in port/pin order)
* because the variants in this platform do not always define all the I/O port/pins
* that a CPU has.
*
* VARIABLES:
* Ard_num - Arduino pin number - defined by the platform. It is used by digitalRead and
* digitalWrite commands and by M42.
* - does not contain port/pin info
* - is not in port/pin order
* - typically a variant will only assign Ard_num to port/pins that are actually used
* Index - M43 counter - only used to get Ard_num
* x - a parameter/argument used to search the pin_array to try to find a signal name
* associated with a Ard_num
* Port_pin - port number and pin number for use with CPU registers and printing reports
*
* Since M43 uses digitalRead and digitalWrite commands, only the Port_pins with an Ard_num
* are accessed and/or displayed.
*
* Three arrays are used.
*
* digitalPin[] is provided by the platform. It consists of the Port_pin numbers in
* Arduino pin number order.
*
* pin_array is a structure generated by the pins/pinsDebug.h header file. It is generated by
* the preprocessor. Only the signals associated with enabled options are in this table.
* It contains:
* - name of the signal
* - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines.
* EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the
* argument to digitalPinToPinName(IO) to get the Port_pin number
* - if it is a digital or analog signal. PWMs are considered digital here.
*
* pin_xref is a structure generated by this header file. It is generated by the
* preprocessor. It is in port/pin order. It contains just the port/pin numbers defined by the
* platform for this variant.
* - Ard_num
* - printable version of Port_pin
*
* Routines with an "x" as a parameter/argument are used to search the pin_array to try to
* find a signal name associated with a port/pin.
*
* NOTE - the Arduino pin number is what is used by the M42 command, NOT the port/pin for that
* signal. The Arduino pin number is listed by the M43 I command.
*/
////////////////////////////////////////////////////////
//
// make a list of the Arduino pin numbers in the Port/Pin order
//
#define _PIN_ADD_2(NAME_ALPHA, ARDUINO_NUM) { {NAME_ALPHA}, ARDUINO_NUM },
#define _PIN_ADD(NAME_ALPHA, ARDUINO_NUM) { NAME_ALPHA, ARDUINO_NUM },
#define PIN_ADD(NAME) _PIN_ADD(#NAME, NAME)
typedef struct {
char Port_pin_alpha[5];
pin_t Ard_num;
} XrefInfo;
const XrefInfo pin_xref[] PROGMEM = {
#include "pins_Xref.h"
};
////////////////////////////////////////////////////////////
#define MODE_PIN_INPUT 0 // Input mode (reset state)
#define MODE_PIN_OUTPUT 1 // General purpose output mode
#define MODE_PIN_ALT 2 // Alternate function mode
#define MODE_PIN_ANALOG 3 // Analog mode
#define PIN_NUM(P) (P & 0x000F)
#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
#define PORT_NUM(P) ((P >> 4) & 0x0007)
#define PORT_ALPHA(P) ('A' + (P >> 4))
/**
* Translation of routines & variables used by pinsDebug.h
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL)
#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
#define PRINT_PIN(Q)
#define PRINT_PORT(ANUM) port_print(ANUM)
#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine
#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num
// x is a variable used to search pin_array
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].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 MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
#ifndef M43_NEVER_TOUCH
#define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP)
#ifdef KILL_PIN
#define M43_NEVER_TOUCH(Index) m43_never_touch(Index)
bool m43_never_touch(const pin_t Index) {
static pin_t M43_kill_index = -1;
if (M43_kill_index < 0)
for (M43_kill_index = 0; M43_kill_index < NUMBER_PINS_TOTAL; M43_kill_index++)
if (KILL_PIN == GET_PIN_MAP_PIN_M43(M43_kill_index)) break;
return _M43_NEVER_TOUCH(Index) || Index == M43_kill_index; // KILL_PIN and SERIAL/USB
}
#else
#error "M43 not supported for this board"
#define M43_NEVER_TOUCH(Index) _M43_NEVER_TOUCH(Index)
#endif
#endif
uint8_t get_pin_mode(const pin_t Ard_num) {
const PinName dp = digitalPinToPinName(Ard_num);
uint32_t ll_pin = STM_LL_GPIO_PIN(dp);
GPIO_TypeDef *port = get_GPIO_Port(STM_PORT(dp));
uint32_t mode = LL_GPIO_GetPinMode(port, ll_pin);
switch (mode) {
case LL_GPIO_MODE_ANALOG: return MODE_PIN_ANALOG;
case LL_GPIO_MODE_INPUT: return MODE_PIN_INPUT;
case LL_GPIO_MODE_OUTPUT: return MODE_PIN_OUTPUT;
case LL_GPIO_MODE_ALTERNATE: return MODE_PIN_ALT;
TERN_(STM32F1xx, case LL_GPIO_MODE_FLOATING:)
default: return 0;
}
}
bool GET_PINMODE(const pin_t Ard_num) {
const uint8_t pin_mode = get_pin_mode(Ard_num);
return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM
}
int8_t digital_pin_to_analog_pin(pin_t Ard_num) {
Ard_num -= NUM_ANALOG_FIRST;
return (Ard_num >= 0 && Ard_num < NUM_ANALOG_INPUTS) ? Ard_num : -1;
}
bool IS_ANALOG(const pin_t Ard_num) {
return get_pin_mode(Ard_num) == MODE_PIN_ANALOG;
}
bool is_digital(const pin_t x) {
const uint8_t pin_mode = get_pin_mode(pin_array[x].pin);
return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT;
}
void port_print(const pin_t Ard_num) {
char buffer[16];
pin_t Index;
for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++)
if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break;
const char * ppa = pin_xref[Index].Port_pin_alpha;
sprintf_P(buffer, PSTR("%s"), ppa);
SERIAL_ECHO(buffer);
if (ppa[3] == '\0') SERIAL_CHAR(' ');
// print analog pin number
const int8_t Port_pin = digital_pin_to_analog_pin(Ard_num);
if (Port_pin >= 0) {
sprintf_P(buffer, PSTR(" (A%d) "), Port_pin);
SERIAL_ECHO(buffer);
if (Port_pin < 10) SERIAL_CHAR(' ');
}
else
SERIAL_ECHO_SP(7);
// Print number to be used with M42
sprintf_P(buffer, PSTR(" M42 P%d "), Ard_num);
SERIAL_ECHO(buffer);
if (Ard_num < 10) SERIAL_CHAR(' ');
if (Ard_num < 100) SERIAL_CHAR(' ');
}
bool pwm_status(const pin_t Ard_num) {
return get_pin_mode(Ard_num) == MODE_PIN_ALT;
}
void pwm_details(const pin_t Ard_num) {
#ifndef STM32F1xx
if (pwm_status(Ard_num)) {
uint32_t alt_all = 0;
const PinName dp = digitalPinToPinName(Ard_num);
pin_t pin_number = uint8_t(PIN_NUM(dp));
const bool over_7 = pin_number >= 8;
const uint8_t ind = over_7 ? 1 : 0;
switch (PORT_ALPHA(dp)) { // get alt function
case 'A' : alt_all = GPIOA->AFR[ind]; break;
case 'B' : alt_all = GPIOB->AFR[ind]; break;
case 'C' : alt_all = GPIOC->AFR[ind]; break;
case 'D' : alt_all = GPIOD->AFR[ind]; break;
#ifdef PE_0
case 'E' : alt_all = GPIOE->AFR[ind]; break;
#elif defined (PF_0)
case 'F' : alt_all = GPIOF->AFR[ind]; break;
#elif defined (PG_0)
case 'G' : alt_all = GPIOG->AFR[ind]; break;
#elif defined (PH_0)
case 'H' : alt_all = GPIOH->AFR[ind]; break;
#elif defined (PI_0)
case 'I' : alt_all = GPIOI->AFR[ind]; break;
#elif defined (PJ_0)
case 'J' : alt_all = GPIOJ->AFR[ind]; break;
#elif defined (PK_0)
case 'K' : alt_all = GPIOK->AFR[ind]; break;
#elif defined (PL_0)
case 'L' : alt_all = GPIOL->AFR[ind]; break;
#endif
}
if (over_7) pin_number -= 8;
uint8_t alt_func = (alt_all >> (4 * pin_number)) & 0x0F;
SERIAL_ECHOPAIR("Alt Function: ", alt_func);
if (alt_func < 10) SERIAL_CHAR(' ');
SERIAL_ECHOPGM(" - ");
switch (alt_func) {
case 0 : SERIAL_ECHOPGM("system (misc. I/O)"); break;
case 1 : SERIAL_ECHOPGM("TIM1/TIM2 (probably PWM)"); break;
case 2 : SERIAL_ECHOPGM("TIM3..5 (probably PWM)"); break;
case 3 : SERIAL_ECHOPGM("TIM8..11 (probably PWM)"); break;
case 4 : SERIAL_ECHOPGM("I2C1..3"); break;
case 5 : SERIAL_ECHOPGM("SPI1/SPI2"); break;
case 6 : SERIAL_ECHOPGM("SPI3"); break;
case 7 : SERIAL_ECHOPGM("USART1..3"); break;
case 8 : SERIAL_ECHOPGM("USART4..6"); break;
case 9 : SERIAL_ECHOPGM("CAN1/CAN2, TIM12..14 (probably PWM)"); break;
case 10 : SERIAL_ECHOPGM("OTG"); break;
case 11 : SERIAL_ECHOPGM("ETH"); break;
case 12 : SERIAL_ECHOPGM("FSMC, SDIO, OTG"); break;
case 13 : SERIAL_ECHOPGM("DCMI"); break;
case 14 : SERIAL_ECHOPGM("unused (shouldn't see this)"); break;
case 15 : SERIAL_ECHOPGM("EVENTOUT"); break;
}
}
#else
// TODO: F1 doesn't support changing pins function, so we need to check the function of the PIN and if it's enabled
#endif
} // pwm_details
@@ -1,125 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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
/**
* Support routines for STM32GENERIC (Maple)
*/
/**
* Translation of routines & variables used by pinsDebug.h
*/
#ifdef BOARD_NR_GPIO_PINS // Only in STM32GENERIC (Maple)
#ifdef __STM32F1__
#include "../STM32F1/fastio.h"
#elif defined(STM32F4) || defined(STM32F7)
#include "../STM32_F4_F7/fastio.h"
#else
#include "fastio.h"
#endif
extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS];
#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS
#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS
#define VALID_PIN(pin) (pin >= 0 && pin < BOARD_NR_GPIO_PINS)
#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin)
#define pwm_status(pin) PWM_PIN(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_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
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
#ifndef M43_NEVER_TOUCH
#define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX)
#endif
static inline int8_t get_pin_mode(pin_t pin) {
return VALID_PIN(pin) ? _GET_MODE(pin) : -1;
}
static inline pin_t DIGITAL_PIN_TO_ANALOG_PIN(pin_t pin) {
if (!VALID_PIN(pin)) return -1;
int8_t adc_channel = int8_t(PIN_MAP[pin].adc_channel);
#ifdef NUM_ANALOG_INPUTS
if (adc_channel >= NUM_ANALOG_INPUTS) adc_channel = ADCx;
#endif
return pin_t(adc_channel);
}
static inline bool IS_ANALOG(pin_t pin) {
if (!VALID_PIN(pin)) return false;
if (PIN_MAP[pin].adc_channel != ADCx) {
#ifdef NUM_ANALOG_INPUTS
if (PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) return false;
#endif
return _GET_MODE(pin) == GPIO_INPUT_ANALOG && !M43_NEVER_TOUCH(pin);
}
return false;
}
static inline bool GET_PINMODE(const pin_t pin) {
return VALID_PIN(pin) && !IS_INPUT(pin);
}
static inline bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) {
const pin_t pin = GET_ARRAY_PIN(array_pin);
return (!IS_ANALOG(pin)
#ifdef NUM_ANALOG_INPUTS
|| PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS
#endif
);
}
#include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density
static inline void pwm_details(const pin_t pin) {
if (PWM_PIN(pin)) {
timer_dev * const tdev = PIN_MAP[pin].timer_device;
const uint8_t channel = PIN_MAP[pin].timer_channel;
const char num = (
#if EITHER(STM32_HIGH_DENSITY, STM32_XL_DENSITY)
tdev == &timer8 ? '8' :
tdev == &timer5 ? '5' :
#endif
tdev == &timer4 ? '4' :
tdev == &timer3 ? '3' :
tdev == &timer2 ? '2' :
tdev == &timer1 ? '1' : '?'
);
char buffer[10];
sprintf_P(buffer, PSTR(" TIM%c CH%c"), num, ('0' + channel));
SERIAL_ECHO(buffer);
}
}
static inline void print_port(pin_t pin) {
const char port = 'A' + char(pin >> 4); // pin div 16
const int16_t gbit = PIN_MAP[pin].gpio_bit;
char buffer[8];
sprintf_P(buffer, PSTR("P%c%hd "), port, gbit);
if (gbit < 10) SERIAL_CHAR(' ');
SERIAL_ECHO(buffer);
}
#endif // BOARD_NR_GPIO_PINS
-273
View File
@@ -1,273 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* 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 <Arduino.h>
#ifdef NUM_DIGITAL_PINS // Only in ST's Arduino core (STM32duino, STM32Core)
/**
* Life gets complicated if you want an easy to use 'M43 I' output (in port/pin order)
* because the variants in this platform do not always define all the I/O port/pins
* that a CPU has.
*
* VARIABLES:
* Ard_num - Arduino pin number - defined by the platform. It is used by digitalRead and
* digitalWrite commands and by M42.
* - does not contain port/pin info
* - is not in port/pin order
* - typically a variant will only assign Ard_num to port/pins that are actually used
* Index - M43 counter - only used to get Ard_num
* x - a parameter/argument used to search the pin_array to try to find a signal name
* associated with a Ard_num
* Port_pin - port number and pin number for use with CPU registers and printing reports
*
* Since M43 uses digitalRead and digitalWrite commands, only the Port_pins with an Ard_num
* are accessed and/or displayed.
*
* Three arrays are used.
*
* digitalPin[] is provided by the platform. It consists of the Port_pin numbers in
* Arduino pin number order.
*
* pin_array is a structure generated by the pins/pinsDebug.h header file. It is generated by
* the preprocessor. Only the signals associated with enabled options are in this table.
* It contains:
* - name of the signal
* - the Ard_num assigned by the pins_YOUR_BOARD.h file using the platform defines.
* EXAMPLE: "#define KILL_PIN PB1" results in Ard_num of 57. 57 is then used as the
* argument to digitalPinToPinName(IO) to get the Port_pin number
* - if it is a digital or analog signal. PWMs are considered digital here.
*
* pin_xref is a structure generated by this header file. It is generated by the
* preprocessor. It is in port/pin order. It contains just the port/pin numbers defined by the
* platform for this variant.
* - Ard_num
* - printable version of Port_pin
*
* Routines with an "x" as a parameter/argument are used to search the pin_array to try to
* find a signal name associated with a port/pin.
*
* NOTE - the Arduino pin number is what is used by the M42 command, NOT the port/pin for that
* signal. The Arduino pin number is listed by the M43 I command.
*/
////////////////////////////////////////////////////////
//
// make a list of the Arduino pin numbers in the Port/Pin order
//
#define _PIN_ADD_2(NAME_ALPHA, ARDUINO_NUM) { {NAME_ALPHA}, ARDUINO_NUM },
#define _PIN_ADD(NAME_ALPHA, ARDUINO_NUM) { NAME_ALPHA, ARDUINO_NUM },
#define PIN_ADD(NAME) _PIN_ADD(#NAME, NAME)
typedef struct {
char Port_pin_alpha[5];
pin_t Ard_num;
} XrefInfo;
const XrefInfo pin_xref[] PROGMEM = {
#include "pins_Xref.h"
};
////////////////////////////////////////////////////////////
#define MODE_PIN_INPUT 0 // Input mode (reset state)
#define MODE_PIN_OUTPUT 1 // General purpose output mode
#define MODE_PIN_ALT 2 // Alternate function mode
#define MODE_PIN_ANALOG 3 // Analog mode
#define PIN_NUM(P) (P & 0x000F)
#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1')
#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 )
#define PORT_NUM(P) ((P >> 4) & 0x0007)
#define PORT_ALPHA(P) ('A' + (P >> 4))
/**
* Translation of routines & variables used by pinsDebug.h
*/
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
#define VALID_PIN(ANUM) ((ANUM) >= 0 && (ANUM) < NUMBER_PINS_TOTAL)
#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads
#define PRINT_PIN(Q)
#define PRINT_PORT(ANUM) port_print(ANUM)
#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine
#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num
// x is a variable used to search pin_array
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].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 MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin
#ifndef M43_NEVER_TOUCH
#define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP)
#ifdef KILL_PIN
#define M43_NEVER_TOUCH(Index) m43_never_touch(Index)
bool m43_never_touch(const pin_t Index) {
static pin_t M43_kill_index = -1;
if (M43_kill_index < 0)
for (M43_kill_index = 0; M43_kill_index < NUMBER_PINS_TOTAL; M43_kill_index++)
if (KILL_PIN == GET_PIN_MAP_PIN_M43(M43_kill_index)) break;
return _M43_NEVER_TOUCH(Index) || Index == M43_kill_index; // KILL_PIN and SERIAL/USB
}
#else
#define M43_NEVER_TOUCH(Index) _M43_NEVER_TOUCH(Index)
#endif
#endif
uint8_t get_pin_mode(const pin_t Ard_num) {
uint32_t mode_all = 0;
const PinName dp = digitalPinToPinName(Ard_num);
switch (PORT_ALPHA(dp)) {
case 'A' : mode_all = GPIOA->MODER; break;
case 'B' : mode_all = GPIOB->MODER; break;
case 'C' : mode_all = GPIOC->MODER; break;
case 'D' : mode_all = GPIOD->MODER; break;
#ifdef PE_0
case 'E' : mode_all = GPIOE->MODER; break;
#elif defined(PF_0)
case 'F' : mode_all = GPIOF->MODER; break;
#elif defined(PG_0)
case 'G' : mode_all = GPIOG->MODER; break;
#elif defined(PH_0)
case 'H' : mode_all = GPIOH->MODER; break;
#elif defined(PI_0)
case 'I' : mode_all = GPIOI->MODER; break;
#elif defined(PJ_0)
case 'J' : mode_all = GPIOJ->MODER; break;
#elif defined(PK_0)
case 'K' : mode_all = GPIOK->MODER; break;
#elif defined(PL_0)
case 'L' : mode_all = GPIOL->MODER; break;
#endif
}
return (mode_all >> (2 * uint8_t(PIN_NUM(dp)))) & 0x03;
}
bool GET_PINMODE(const pin_t Ard_num) {
const uint8_t pin_mode = get_pin_mode(Ard_num);
return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM
}
int8_t digital_pin_to_analog_pin(pin_t Ard_num) {
Ard_num -= NUM_ANALOG_FIRST;
return (Ard_num >= 0 && Ard_num < NUM_ANALOG_INPUTS) ? Ard_num : -1;
}
bool IS_ANALOG(const pin_t Ard_num) {
return get_pin_mode(Ard_num) == MODE_PIN_ANALOG;
}
bool is_digital(const pin_t x) {
const uint8_t pin_mode = get_pin_mode(pin_array[x].pin);
return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT;
}
void port_print(const pin_t Ard_num) {
char buffer[16];
pin_t Index;
for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++)
if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break;
const char * ppa = pin_xref[Index].Port_pin_alpha;
sprintf_P(buffer, PSTR("%s"), ppa);
SERIAL_ECHO(buffer);
if (ppa[3] == '\0') SERIAL_CHAR(' ');
// print analog pin number
const int8_t Port_pin = digital_pin_to_analog_pin(Ard_num);
if (Port_pin >= 0) {
sprintf_P(buffer, PSTR(" (A%d) "), Port_pin);
SERIAL_ECHO(buffer);
if (Port_pin < 10) SERIAL_CHAR(' ');
}
else
SERIAL_ECHO_SP(7);
// Print number to be used with M42
sprintf_P(buffer, PSTR(" M42 P%d "), Ard_num);
SERIAL_ECHO(buffer);
if (Ard_num < 10) SERIAL_CHAR(' ');
if (Ard_num < 100) SERIAL_CHAR(' ');
}
bool pwm_status(const pin_t Ard_num) {
return get_pin_mode(Ard_num) == MODE_PIN_ALT;
}
void pwm_details(const pin_t Ard_num) {
if (pwm_status(Ard_num)) {
uint32_t alt_all = 0;
const PinName dp = digitalPinToPinName(Ard_num);
pin_t pin_number = uint8_t(PIN_NUM(dp));
const bool over_7 = pin_number >= 8;
const uint8_t ind = over_7 ? 1 : 0;
switch (PORT_ALPHA(dp)) { // get alt function
case 'A' : alt_all = GPIOA->AFR[ind]; break;
case 'B' : alt_all = GPIOB->AFR[ind]; break;
case 'C' : alt_all = GPIOC->AFR[ind]; break;
case 'D' : alt_all = GPIOD->AFR[ind]; break;
#ifdef PE_0
case 'E' : alt_all = GPIOE->AFR[ind]; break;
#elif defined (PF_0)
case 'F' : alt_all = GPIOF->AFR[ind]; break;
#elif defined (PG_0)
case 'G' : alt_all = GPIOG->AFR[ind]; break;
#elif defined (PH_0)
case 'H' : alt_all = GPIOH->AFR[ind]; break;
#elif defined (PI_0)
case 'I' : alt_all = GPIOI->AFR[ind]; break;
#elif defined (PJ_0)
case 'J' : alt_all = GPIOJ->AFR[ind]; break;
#elif defined (PK_0)
case 'K' : alt_all = GPIOK->AFR[ind]; break;
#elif defined (PL_0)
case 'L' : alt_all = GPIOL->AFR[ind]; break;
#endif
}
if (over_7) pin_number -= 8;
uint8_t alt_func = (alt_all >> (4 * pin_number)) & 0x0F;
SERIAL_ECHOPAIR("Alt Function: ", alt_func);
if (alt_func < 10) SERIAL_CHAR(' ');
SERIAL_ECHOPGM(" - ");
switch (alt_func) {
case 0 : SERIAL_ECHOPGM("system (misc. I/O)"); break;
case 1 : SERIAL_ECHOPGM("TIM1/TIM2 (probably PWM)"); break;
case 2 : SERIAL_ECHOPGM("TIM3..5 (probably PWM)"); break;
case 3 : SERIAL_ECHOPGM("TIM8..11 (probably PWM)"); break;
case 4 : SERIAL_ECHOPGM("I2C1..3"); break;
case 5 : SERIAL_ECHOPGM("SPI1/SPI2"); break;
case 6 : SERIAL_ECHOPGM("SPI3"); break;
case 7 : SERIAL_ECHOPGM("USART1..3"); break;
case 8 : SERIAL_ECHOPGM("USART4..6"); break;
case 9 : SERIAL_ECHOPGM("CAN1/CAN2, TIM12..14 (probably PWM)"); break;
case 10 : SERIAL_ECHOPGM("OTG"); break;
case 11 : SERIAL_ECHOPGM("ETH"); break;
case 12 : SERIAL_ECHOPGM("FSMC, SDIO, OTG"); break;
case 13 : SERIAL_ECHOPGM("DCMI"); break;
case 14 : SERIAL_ECHOPGM("unused (shouldn't see this)"); break;
case 15 : SERIAL_ECHOPGM("EVENTOUT"); break;
}
}
} // pwm_details
#endif // NUM_DIGITAL_PINS
+8 -8
View File
@@ -21,15 +21,15 @@
/**
* Define SPI Pins: SCK, MISO, MOSI, SS
*/
#ifndef SCK_PIN
#define SCK_PIN PIN_SPI_SCK
#ifndef SD_SCK_PIN
#define SD_SCK_PIN PIN_SPI_SCK
#endif
#ifndef MISO_PIN
#define MISO_PIN PIN_SPI_MISO
#ifndef SD_MISO_PIN
#define SD_MISO_PIN PIN_SPI_MISO
#endif
#ifndef MOSI_PIN
#define MOSI_PIN PIN_SPI_MOSI
#ifndef SD_MOSI_PIN
#define SD_MOSI_PIN PIN_SPI_MOSI
#endif
#ifndef SS_PIN
#define SS_PIN PIN_SPI_SS
#ifndef SD_SS_PIN
#define SD_SS_PIN PIN_SPI_SS
#endif
+34 -33
View File
@@ -19,6 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../../inc/MarlinConfig.h"
@@ -47,13 +48,14 @@ void TFT_FSMC::Init() {
uint32_t NSBank = (uint32_t)pinmap_peripheral(digitalPinToPinName(TFT_CS_PIN), PinMap_FSMC_CS);
// Perform the SRAM1 memory initialization sequence
SRAMx.Instance = FSMC_NORSRAM_DEVICE;
SRAMx.Extended = FSMC_NORSRAM_EXTENDED_DEVICE;
/* SRAMx.Init */
// SRAMx.Init
SRAMx.Init.NSBank = NSBank;
SRAMx.Init.DataAddressMux = FSMC_DATA_ADDRESS_MUX_DISABLE;
SRAMx.Init.MemoryType = FSMC_MEMORY_TYPE_SRAM;
SRAMx.Init.MemoryDataWidth = FSMC_NORSRAM_MEM_BUS_WIDTH_16;
SRAMx.Init.MemoryDataWidth = TERN(TFT_INTERFACE_FSMC_8BIT, FSMC_NORSRAM_MEM_BUS_WIDTH_8, FSMC_NORSRAM_MEM_BUS_WIDTH_16);
SRAMx.Init.BurstAccessMode = FSMC_BURST_ACCESS_MODE_DISABLE;
SRAMx.Init.WaitSignalPolarity = FSMC_WAIT_SIGNAL_POLARITY_LOW;
SRAMx.Init.WrapMode = FSMC_WRAP_MODE_DISABLE;
@@ -66,8 +68,8 @@ void TFT_FSMC::Init() {
#ifdef STM32F4xx
SRAMx.Init.PageSize = FSMC_PAGE_SIZE_NONE;
#endif
/* Read Timing - relatively slow to ensure ID information is correctly read from TFT controller */
/* Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss */
// Read Timing - relatively slow to ensure ID information is correctly read from TFT controller
// Can be decreases from 15-15-24 to 4-4-8 with risk of stability loss
Timing.AddressSetupTime = 15;
Timing.AddressHoldTime = 15;
Timing.DataSetupTime = 24;
@@ -75,8 +77,8 @@ void TFT_FSMC::Init() {
Timing.CLKDivision = 16;
Timing.DataLatency = 17;
Timing.AccessMode = FSMC_ACCESS_MODE_A;
/* Write Timing */
/* Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss */
// Write Timing
// Can be decreases from 8-15-8 to 0-0-1 with risk of stability loss
ExtTiming.AddressSetupTime = 8;
ExtTiming.AddressHoldTime = 15;
ExtTiming.DataSetupTime = 8;
@@ -130,7 +132,7 @@ void TFT_FSMC::Init() {
uint32_t TFT_FSMC::GetID() {
uint32_t id;
WriteReg(0x0000);
WriteReg(0);
id = LCD->RAM;
if (id == 0)
@@ -140,41 +142,40 @@ uint32_t TFT_FSMC::GetID() {
return id;
}
uint32_t TFT_FSMC::ReadID(uint16_t Reg) {
uint32_t id;
WriteReg(Reg);
id = LCD->RAM; // dummy read
id = Reg << 24;
id |= (LCD->RAM & 0x00FF) << 16;
id |= (LCD->RAM & 0x00FF) << 8;
id |= LCD->RAM & 0x00FF;
return id;
}
uint32_t TFT_FSMC::ReadID(tft_data_t Reg) {
uint32_t id;
WriteReg(Reg);
id = LCD->RAM; // dummy read
id = Reg << 24;
id |= (LCD->RAM & 0x00FF) << 16;
id |= (LCD->RAM & 0x00FF) << 8;
id |= LCD->RAM & 0x00FF;
return id;
}
bool TFT_FSMC::isBusy() {
if (__IS_DMA_ENABLED(&DMAtx))
#if defined(STM32F1xx)
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
#elif defined(STM32F4xx)
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
#endif
if (dmaEnabled) {
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
Abort();
return __IS_DMA_ENABLED(&DMAtx);
}
else
Abort();
return dmaEnabled;
}
void TFT_FSMC::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
DMAtx.Init.PeriphInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
__HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx));
__HAL_DMA_CLEAR_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx));
#ifdef STM32F1xx
DMAtx.Instance->CNDTR = Count;
DMAtx.Instance->CPAR = (uint32_t)Data;
DMAtx.Instance->CMAR = (uint32_t)&(LCD->RAM);
#elif defined(STM32F4xx)
DMAtx.Instance->NDTR = Count;
DMAtx.Instance->PAR = (uint32_t)Data;
DMAtx.Instance->M0AR = (uint32_t)&(LCD->RAM);
#endif
__HAL_DMA_ENABLE(&DMAtx);
DataTransferBegin();
HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(LCD->RAM), Count);
HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
Abort();
}
#endif // HAS_FSMC_TFT
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+38 -27
View File
@@ -21,34 +21,33 @@
*/
#pragma once
#include "../../../inc/MarlinConfig.h"
#ifdef STM32F1xx
#include "stm32f1xx_hal.h"
#elif defined(STM32F4xx)
#include "stm32f4xx_hal.h"
#else
#error FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware.
#error "FSMC TFT is currently only supported on STM32F1 and STM32F4 hardware."
#endif
#ifndef LCD_READ_ID
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#define LCD_READ_ID 0x04 // Read display identification information (0xD3 on ILI9341)
#endif
#ifndef LCD_READ_ID4
#define LCD_READ_ID4 0xD3 // Read display identification information (0xD3 on ILI9341)
#endif
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_FSMC
#define DATASIZE_8BIT SPI_DATASIZE_8BIT
#define DATASIZE_16BIT SPI_DATASIZE_16BIT
#define TFT_IO_DRIVER TFT_FSMC
#ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#endif
#define TFT_DATASIZE TERN(TFT_INTERFACE_FSMC_8BIT, DATASIZE_8BIT, DATASIZE_16BIT)
typedef TERN(TFT_INTERFACE_FSMC_8BIT, uint8_t, uint16_t) tft_data_t;
typedef struct {
__IO uint16_t REG;
__IO uint16_t RAM;
__IO tft_data_t REG;
__IO tft_data_t RAM;
} LCD_CONTROLLER_TypeDef;
class TFT_FSMC {
@@ -58,8 +57,8 @@ class TFT_FSMC {
static LCD_CONTROLLER_TypeDef *LCD;
static uint32_t ReadID(uint16_t Reg);
static void Transmit(uint16_t Data) { LCD->RAM = Data; __DSB(); }
static uint32_t ReadID(tft_data_t Reg);
static void Transmit(tft_data_t Data) { LCD->RAM = Data; __DSB(); }
static void TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count);
public:
@@ -68,17 +67,23 @@ class TFT_FSMC {
static bool isBusy();
static void Abort() { __HAL_DMA_DISABLE(&DMAtx); }
static void DataTransferBegin(uint16_t DataWidth = DATASIZE_16BIT) {}
static void DataTransferBegin(uint16_t DataWidth = TFT_DATASIZE) {}
static void DataTransferEnd() {};
static void WriteData(uint16_t Data) { Transmit(Data); }
static void WriteReg(uint16_t Reg) { LCD->REG = Reg; __DSB(); }
static void WriteData(uint16_t Data) { Transmit(tft_data_t(Data)); }
static void WriteReg(uint16_t Reg) { LCD->REG = tft_data_t(Reg); __DSB(); }
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_PINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_PINC_DISABLE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
}
}
};
#ifdef STM32F1xx
#define FSMC_PIN_DATA STM_PIN_DATA(STM_MODE_AF_PP, GPIO_NOPULL, AFIO_NONE)
#elif defined(STM32F4xx)
@@ -100,14 +105,16 @@ const PinMap PinMap_FSMC[] = {
{PE_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D05
{PE_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D06
{PE_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D07
{PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08
{PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09
{PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10
{PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11
{PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12
{PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13
{PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14
{PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15
#if DISABLED(TFT_INTERFACE_FSMC_8BIT)
{PE_11, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D08
{PE_12, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D09
{PE_13, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D10
{PE_14, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D11
{PE_15, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D12
{PD_8, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D13
{PD_9, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D14
{PD_10, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_D15
#endif
{PD_4, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NOE
{PD_5, FSMC_NORSRAM_DEVICE, FSMC_PIN_DATA}, // FSMC_NWE
{NC, NP, 0}
@@ -123,7 +130,11 @@ const PinMap PinMap_FSMC_CS[] = {
{NC, NP, 0}
};
#define FSMC_RS(A) (void *)((2 << A) - 2)
#if ENABLED(TFT_INTERFACE_FSMC_8BIT)
#define FSMC_RS(A) (void *)((2 << (A-1)) - 1)
#else
#define FSMC_RS(A) (void *)((2 << A) - 2)
#endif
const PinMap PinMap_FSMC_RS[] = {
#ifdef PF0
+68 -45
View File
@@ -19,6 +19,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../../inc/MarlinConfig.h"
@@ -33,22 +34,13 @@ DMA_HandleTypeDef TFT_SPI::DMAtx;
void TFT_SPI::Init() {
SPI_TypeDef *spiInstance;
#if PIN_EXISTS(TFT_RESET)
OUT_WRITE(TFT_RESET_PIN, HIGH);
HAL_Delay(100);
#endif
#if PIN_EXISTS(TFT_BACKLIGHT)
OUT_WRITE(TFT_BACKLIGHT_PIN, HIGH);
#endif
OUT_WRITE(TFT_A0_PIN, HIGH);
OUT_WRITE(TFT_CS_PIN, HIGH);
if ((spiInstance = (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK)) == NP) return;
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI)) return;
#if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
#if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN
if (spiInstance != (SPI_TypeDef *)pinmap_peripheral(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO)) return;
#endif
@@ -56,12 +48,7 @@ void TFT_SPI::Init() {
SPIx.State = HAL_SPI_STATE_RESET;
SPIx.Init.NSS = SPI_NSS_SOFT;
SPIx.Init.Mode = SPI_MODE_MASTER;
SPIx.Init.Direction =
#if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_DIRECTION_1LINE;
#else
SPI_DIRECTION_2LINES;
#endif
SPIx.Init.Direction = (TFT_MISO_PIN == TFT_MOSI_PIN) ? SPI_DIRECTION_1LINE : SPI_DIRECTION_2LINES;
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
SPIx.Init.CLKPhase = SPI_PHASE_1EDGE;
SPIx.Init.CLKPolarity = SPI_POLARITY_LOW;
@@ -73,7 +60,7 @@ void TFT_SPI::Init() {
pinmap_pinout(digitalPinToPinName(TFT_SCK_PIN), PinMap_SPI_SCLK);
pinmap_pinout(digitalPinToPinName(TFT_MOSI_PIN), PinMap_SPI_MOSI);
#if PIN_EXISTS(TFT_MISO) && (TFT_MISO_PIN != TFT_MOSI_PIN)
#if PIN_EXISTS(TFT_MISO) && TFT_MISO_PIN != TFT_MOSI_PIN
pinmap_pinout(digitalPinToPinName(TFT_MISO_PIN), PinMap_SPI_MISO);
#endif
pin_PullConfig(get_GPIO_Port(STM_PORT(digitalPinToPinName(TFT_SCK_PIN))), STM_LL_GPIO_PIN(digitalPinToPinName(TFT_SCK_PIN)), GPIO_PULLDOWN);
@@ -81,23 +68,41 @@ void TFT_SPI::Init() {
#ifdef SPI1_BASE
if (SPIx.Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
#ifdef STM32F1xx
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Channel3;
#elif defined(STM32F4xx)
__HAL_RCC_DMA2_CLK_ENABLE();
DMAtx.Instance = DMA2_Stream3;
DMAtx.Init.Channel = DMA_CHANNEL_3;
#endif
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
DMAtx.Instance = DMA1_Channel3;
}
#endif
#ifdef SPI2_BASE
if (SPIx.Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Channel5;
#ifdef STM32F1xx
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Channel5;
#elif defined(STM32F4xx)
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Stream4;
DMAtx.Init.Channel = DMA_CHANNEL_0;
#endif
}
#endif
#ifdef SPI3_BASE
if (SPIx.Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
DMAtx.Instance = DMA2_Channel2;
#ifdef STM32F1xx
__HAL_RCC_DMA2_CLK_ENABLE();
DMAtx.Instance = DMA2_Channel2;
#elif defined(STM32F4xx)
__HAL_RCC_DMA1_CLK_ENABLE();
DMAtx.Instance = DMA1_Stream5;
DMAtx.Init.Channel = DMA_CHANNEL_0;
#endif
}
#endif
@@ -109,6 +114,9 @@ void TFT_SPI::Init() {
DMAtx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
DMAtx.Init.Mode = DMA_NORMAL;
DMAtx.Init.Priority = DMA_PRIORITY_LOW;
#ifdef STM32F4xx
DMAtx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
#endif
}
void TFT_SPI::DataTransferBegin(uint16_t DataSize) {
@@ -127,11 +135,10 @@ uint32_t TFT_SPI::GetID() {
}
uint32_t TFT_SPI::ReadID(uint16_t Reg) {
#if !PIN_EXISTS(TFT_MISO)
return 0;
#else
uint32_t Data = 0;
#if PIN_EXISTS(TFT_MISO)
uint32_t BaudRatePrescaler = SPIx.Init.BaudRatePrescaler;
uint32_t i, Data = 0;
uint32_t i;
SPIx.Init.BaudRatePrescaler = SPIx.Instance == SPI1 ? SPI_BAUDRATEPRESCALER_8 : SPI_BAUDRATEPRESCALER_4;
DataTransferBegin(DATASIZE_8BIT);
@@ -155,27 +162,42 @@ uint32_t TFT_SPI::ReadID(uint16_t Reg) {
DataTransferEnd();
SPIx.Init.BaudRatePrescaler = BaudRatePrescaler;
return Data >> 7;
#endif
return Data >> 7;
}
bool TFT_SPI::isBusy() {
if (DMAtx.Instance->CCR & DMA_CCR_EN)
#if defined(STM32F1xx)
volatile bool dmaEnabled = (DMAtx.Instance->CCR & DMA_CCR_EN) != RESET;
#elif defined(STM32F4xx)
volatile bool dmaEnabled = DMAtx.Instance->CR & DMA_SxCR_EN;
#endif
if (dmaEnabled) {
if (__HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TC_FLAG_INDEX(&DMAtx)) != 0 || __HAL_DMA_GET_FLAG(&DMAtx, __HAL_DMA_GET_TE_FLAG_INDEX(&DMAtx)) != 0)
Abort();
return DMAtx.Instance->CCR & DMA_CCR_EN;
}
else
Abort();
return dmaEnabled;
}
void TFT_SPI::Abort() {
__HAL_DMA_DISABLE(&DMAtx);
// Wait for any running spi
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
// First, abort any running dma
HAL_DMA_Abort(&DMAtx);
// DeInit objects
HAL_DMA_DeInit(&DMAtx);
HAL_SPI_DeInit(&SPIx);
// Deselect CS
DataTransferEnd();
}
void TFT_SPI::Transmit(uint16_t Data) {
#if TFT_MISO_PIN == TFT_MOSI_PIN
if (TFT_MISO_PIN == TFT_MOSI_PIN)
SPI_1LINE_TX(&SPIx);
#endif
__HAL_SPI_ENABLE(&SPIx);
@@ -184,29 +206,30 @@ void TFT_SPI::Transmit(uint16_t Data) {
while ((SPIx.Instance->SR & SPI_FLAG_TXE) != SPI_FLAG_TXE) {}
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
#if TFT_MISO_PIN != TFT_MOSI_PIN
if (TFT_MISO_PIN != TFT_MOSI_PIN)
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */
#endif
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
// Wait last dma finish, to start another
while(isBusy()) { }
DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
if (TFT_MISO_PIN == TFT_MOSI_PIN)
SPI_1LINE_TX(&SPIx);
DataTransferBegin();
#if TFT_MISO_PIN == TFT_MOSI_PIN
SPI_1LINE_TX(&SPIx);
#endif
DMAtx.DmaBaseAddress->IFCR = (DMA_ISR_GIF1 << DMAtx.ChannelIndex);
DMAtx.Instance->CNDTR = Count;
DMAtx.Instance->CPAR = (uint32_t)&(SPIx.Instance->DR);
DMAtx.Instance->CMAR = (uint32_t)Data;
__HAL_DMA_ENABLE(&DMAtx);
HAL_DMA_Start(&DMAtx, (uint32_t)Data, (uint32_t)&(SPIx.Instance->DR), Count);
__HAL_SPI_ENABLE(&SPIx);
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
Abort();
}
#endif // HAS_SPI_TFT
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+7
View File
@@ -64,4 +64,11 @@ public:
static void WriteSequence(uint16_t *Data, uint16_t Count) { TransmitDMA(DMA_MINC_ENABLE, Data, Count); }
static void WriteMultiple(uint16_t Color, uint16_t Count) { static uint16_t Data; Data = Color; TransmitDMA(DMA_MINC_DISABLE, &Data, Count); }
static void WriteMultiple(uint16_t Color, uint32_t Count) {
static uint16_t Data; Data = Color;
while (Count > 0) {
TransmitDMA(DMA_MINC_DISABLE, &Data, Count > 0xFFFF ? 0xFFFF : Count);
Count = Count > 0xFFFF ? Count - 0xFFFF : 0;
}
}
};
+7 -22
View File
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -16,10 +19,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "../../../inc/MarlinConfig.h"
#if HAS_TFT_XPT2046
#if HAS_TFT_XPT2046 || HAS_TOUCH_BUTTONS
#include "xpt2046.h"
#include "pinconfig.h"
@@ -27,7 +31,6 @@
uint16_t delta(uint16_t a, uint16_t b) { return a > b ? a - b : b - a; }
SPI_HandleTypeDef XPT2046::SPIx;
DMA_HandleTypeDef XPT2046::DMAtx;
void XPT2046::Init() {
SPI_TypeDef *spiInstance;
@@ -67,34 +70,16 @@ void XPT2046::Init() {
if (SPIx.Instance == SPI1) {
__HAL_RCC_SPI1_CLK_ENABLE();
SPIx.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;
#ifdef STM32F1xx
DMAtx.Instance = DMA1_Channel3;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA2_Stream3; // DMA2_Stream5
#endif
//SERIAL_ECHO_MSG(" Touch Screen on SPI1");
}
#endif
#ifdef SPI2_BASE
if (SPIx.Instance == SPI2) {
__HAL_RCC_SPI2_CLK_ENABLE();
#ifdef STM32F1xx
DMAtx.Instance = DMA1_Channel5;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA1_Stream4;
#endif
//SERIAL_ECHO_MSG(" Touch Screen on SPI2");
}
#endif
#ifdef SPI3_BASE
if (SPIx.Instance == SPI3) {
__HAL_RCC_SPI3_CLK_ENABLE();
#ifdef STM32F1xx
DMAtx.Instance = DMA2_Channel2;
#elif defined(STM32F4xx)
DMAtx.Instance = DMA1_Stream5; // DMA1_Stream7
#endif
//SERIAL_ECHO_MSG(" Touch Screen on SPI3");
}
#endif
}
@@ -103,7 +88,6 @@ void XPT2046::Init() {
SET_INPUT(TOUCH_MISO_PIN);
SET_OUTPUT(TOUCH_MOSI_PIN);
SET_OUTPUT(TOUCH_SCK_PIN);
//SERIAL_ECHO_MSG(" Touch Screen on Software SPI");
}
getRawData(XPT2046_Z1);
@@ -183,3 +167,4 @@ uint16_t XPT2046::SoftwareIO(uint16_t data) {
}
#endif // HAS_TFT_XPT2046
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+5 -10
View File
@@ -1,6 +1,9 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,19 +60,11 @@ enum XPTCoordinate : uint8_t {
#define XPT2046_Z1_THRESHOLD 10
#endif
#ifdef STM32F1xx
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CCR & DMA_CCR_EN)
#elif defined(STM32F4xx)
#define __IS_DMA_ENABLED(__HANDLE__) ((__HANDLE__)->Instance->CR & DMA_SxCR_EN)
#endif
class XPT2046 {
private:
static SPI_HandleTypeDef SPIx;
static DMA_HandleTypeDef DMAtx;
static bool isBusy() { return SPIx.Instance ? __IS_DMA_ENABLED(&DMAtx) : false; }
static bool isBusy() { return false; }
static uint16_t getRawData(const XPTCoordinate coordinate);
static bool isTouched();
+112 -73
View File
@@ -27,7 +27,6 @@
// Local defines
// ------------------------
// Default timer priorities. Override by specifying alternate priorities in the board pins file.
// The TONE timer is not present here, as it currently cannot be set programmatically. It is set
// by defining TIM_IRQ_PRIO in the variant.h or platformio.ini file, which adjusts the default
@@ -96,11 +95,6 @@
#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
#define __TIMER_IRQ_NAME(X) TIM##X##_IRQn
#define _TIMER_IRQ_NAME(X) __TIMER_IRQ_NAME(X)
#define STEP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(STEP_TIMER)
#define TEMP_TIMER_IRQ_NAME _TIMER_IRQ_NAME(TEMP_TIMER)
// ------------------------
// Private Variables
// ------------------------
@@ -197,87 +191,132 @@ void SetTimerInterruptPriorities() {
TERN_(HAS_SERVOS, libServo::setInterruptPriority(SERVO_TIMER_IRQ_PRIO, 0));
}
// This is a terrible hack to replicate the behavior used in the framework's SoftwareSerial.cpp
// to choose a serial timer. It will select TIM7 on most boards used by Marlin, but this is more
// resiliant to new MCUs which may not have a TIM7. Best practice is to explicitly specify
// TIMER_SERIAL to avoid relying on framework selections which may not be predictable.
#if !defined(TIMER_SERIAL)
#if defined (TIM18_BASE)
#define TIMER_SERIAL TIM18
#elif defined (TIM7_BASE)
#define TIMER_SERIAL TIM7
#elif defined (TIM6_BASE)
#define TIMER_SERIAL TIM6
#elif defined (TIM22_BASE)
#define TIMER_SERIAL TIM22
#elif defined (TIM21_BASE)
#define TIMER_SERIAL TIM21
#elif defined (TIM17_BASE)
#define TIMER_SERIAL TIM17
#elif defined (TIM16_BASE)
#define TIMER_SERIAL TIM16
#elif defined (TIM15_BASE)
#define TIMER_SERIAL TIM15
#elif defined (TIM14_BASE)
#define TIMER_SERIAL TIM14
#elif defined (TIM13_BASE)
#define TIMER_SERIAL TIM13
#elif defined (TIM11_BASE)
#define TIMER_SERIAL TIM11
#elif defined (TIM10_BASE)
#define TIMER_SERIAL TIM10
#elif defined (TIM12_BASE)
#define TIMER_SERIAL TIM12
#elif defined (TIM19_BASE)
#define TIMER_SERIAL TIM19
#elif defined (TIM9_BASE)
#define TIMER_SERIAL TIM9
#elif defined (TIM5_BASE)
#define TIMER_SERIAL TIM5
#elif defined (TIM4_BASE)
#define TIMER_SERIAL TIM4
#elif defined (TIM3_BASE)
#define TIMER_SERIAL TIM3
#elif defined (TIM2_BASE)
#define TIMER_SERIAL TIM2
#elif defined (TIM20_BASE)
#define TIMER_SERIAL TIM20
#elif defined (TIM8_BASE)
#define TIMER_SERIAL TIM8
#elif defined (TIM1_BASE)
#define TIMER_SERIAL TIM1
#else
#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
// ------------------------
// Detect timer conflicts
// ------------------------
// This list serves two purposes. Firstly, it facilitates build-time mapping between
// variant-defined timer names (such as TIM1) and timer numbers. It also replicates
// the order of timers used in the framework's SoftwareSerial.cpp. The first timer in
// this list will be automatically used by SoftwareSerial if it is not already defined
// in the board's variant or compiler options.
static constexpr struct {uintptr_t base_address; int timer_number;} stm32_timer_map[] = {
#ifdef TIM18_BASE
{ uintptr_t(TIM18), 18 },
#endif
#ifdef TIM7_BASE
{ uintptr_t(TIM7), 7 },
#endif
#ifdef TIM6_BASE
{ uintptr_t(TIM6), 6 },
#endif
#ifdef TIM22_BASE
{ uintptr_t(TIM22), 22 },
#endif
#ifdef TIM21_BASE
{ uintptr_t(TIM21), 21 },
#endif
#ifdef TIM17_BASE
{ uintptr_t(TIM17), 17 },
#endif
#ifdef TIM16_BASE
{ uintptr_t(TIM16), 16 },
#endif
#ifdef TIM15_BASE
{ uintptr_t(TIM15), 15 },
#endif
#ifdef TIM14_BASE
{ uintptr_t(TIM14), 14 },
#endif
#ifdef TIM13_BASE
{ uintptr_t(TIM13), 13 },
#endif
#ifdef TIM11_BASE
{ uintptr_t(TIM11), 11 },
#endif
#ifdef TIM10_BASE
{ uintptr_t(TIM10), 10 },
#endif
#ifdef TIM12_BASE
{ uintptr_t(TIM12), 12 },
#endif
#ifdef TIM19_BASE
{ uintptr_t(TIM19), 19 },
#endif
#ifdef TIM9_BASE
{ uintptr_t(TIM9), 9 },
#endif
#ifdef TIM5_BASE
{ uintptr_t(TIM5), 5 },
#endif
#ifdef TIM4_BASE
{ uintptr_t(TIM4), 4 },
#endif
#ifdef TIM3_BASE
{ uintptr_t(TIM3), 3 },
#endif
#ifdef TIM2_BASE
{ uintptr_t(TIM2), 2 },
#endif
#ifdef TIM20_BASE
{ uintptr_t(TIM20), 20 },
#endif
#ifdef TIM8_BASE
{ uintptr_t(TIM8), 8 },
#endif
#ifdef TIM1_BASE
{ uintptr_t(TIM1), 1 }
#endif
};
// Convert from a timer base address to its integer timer number.
static constexpr int get_timer_num_from_base_address(uintptr_t base_address) {
for (const auto &timer : stm32_timer_map)
if (timer.base_address == base_address) return timer.timer_number;
return 0;
}
// The platform's SoftwareSerial.cpp will use the first timer from stm32_timer_map.
#if HAS_TMC_SW_SERIAL && !defined(TIMER_SERIAL)
#define TIMER_SERIAL (stm32_timer_map[0].base_address)
#endif
// Place all timers used into an array, then recursively check for duplicates during compilation.
// This does not currently account for timers used for PWM, such as for fans.
// Timers are actually pointers. Convert to integers to simplify constexpr logic.
static constexpr uintptr_t timers_in_use[] = {
uintptr_t(TEMP_TIMER_DEV), // Override in pins file
uintptr_t(STEP_TIMER_DEV), // Override in pins file
// constexpr doesn't like using the base address pointers that timers evaluate to.
// We can get away with casting them to uintptr_t, if we do so inside an array.
// GCC will not currently do it directly to a uintptr_t.
IF_ENABLED(HAS_TMC_SW_SERIAL, static constexpr uintptr_t timer_serial[] = {uintptr_t(TIMER_SERIAL)});
IF_ENABLED(SPEAKER, static constexpr uintptr_t timer_tone[] = {uintptr_t(TIMER_TONE)});
IF_ENABLED(HAS_SERVOS, static constexpr uintptr_t timer_servo[] = {uintptr_t(TIMER_SERVO)});
enum TimerPurpose { TP_SERIAL, TP_TONE, TP_SERVO, TP_STEP, TP_TEMP };
// List of timers, to enable checking for conflicts.
// Includes the purpose of each timer to ease debugging when evaluating at build-time.
// This cannot yet account for timers used for PWM output, such as for fans.
static constexpr struct { TimerPurpose p; int t; } timers_in_use[] = {
#if HAS_TMC_SW_SERIAL
uintptr_t(TIMER_SERIAL), // Set in variant.h, or as a define in platformio.h if not present in variant.h
{TP_SERIAL, get_timer_num_from_base_address(timer_serial[0])}, // Set in variant.h, or as a define in platformio.h if not present in variant.h
#endif
#if ENABLED(SPEAKER)
uintptr_t(TIMER_TONE), // Set in variant.h, or as a define in platformio.h if not present in variant.h
{TP_TONE, get_timer_num_from_base_address(timer_tone[0])}, // Set in variant.h, or as a define in platformio.h if not present in variant.h
#endif
#if HAS_SERVOS
uintptr_t(TIMER_SERVO), // Set in variant.h, or as a define in platformio.h if not present in variant.h
{TP_SERVO, get_timer_num_from_base_address(timer_servo[0])}, // Set in variant.h, or as a define in platformio.h if not present in variant.h
#endif
};
{TP_STEP, STEP_TIMER},
{TP_TEMP, TEMP_TIMER},
};
static constexpr bool verify_no_duplicate_timers() {
static constexpr bool verify_no_timer_conflicts() {
LOOP_L_N(i, COUNT(timers_in_use))
LOOP_S_L_N(j, i + 1, COUNT(timers_in_use))
if (timers_in_use[i] == timers_in_use[j]) return false;
if (timers_in_use[i].t == timers_in_use[j].t) return false;
return true;
}
// If this assertion fails at compile time, review the timers_in_use array. If default_envs is
// defined properly in platformio.ini, VS Code can evaluate the array when hovering over it,
// making it easy to identify the conflicting timers.
static_assert(verify_no_duplicate_timers(), "One or more timer conflict detected");
// If this assertion fails at compile time, review the timers_in_use array.
// If default_envs is defined properly in platformio.ini, VS Code can evaluate the array
// when hovering over it, making it easy to identify the conflicting timers.
static_assert(verify_no_timer_conflicts(), "One or more timer conflict detected. Examine \"timers_in_use\" to help identify conflict.");
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+1 -1
View File
@@ -105,7 +105,7 @@ void SetTimerInterruptPriorities();
// FORCE_INLINE because these are used in performance-critical situations
FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) {
return timer_instance[timer_num] != NULL;
return timer_instance[timer_num] != nullptr;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
return HAL_timer_initialized(timer_num) ? timer_instance[timer_num]->getCount() : 0;

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