Compare commits

..

70 Commits

Author SHA1 Message Date
InsanityAutomation 6118d41baa Tweak probe preheat to wait for cooldown, bypass block on unload prime 2021-02-14 14:13:41 -05:00
InsanityAutomation 09dcc85328 Merge branch 'bugfix-2.0.x' into CR-6Devel 2021-02-14 12:06:14 -05:00
InsanityAutomation a11f88a44a Update probe.cpp 2021-02-10 14:20:41 -05:00
InsanityAutomation c639e9fcc6 preheat and parking tweaks 2021-02-10 07:03:48 -05:00
InsanityAutomation bfb81d8c92 Merge branch 'bugfix-2.0.x' into CR-6Devel 2021-02-08 11:16:20 -05:00
InsanityAutomation fbb5a5baf2 Merge branch 'bugfix-2.0.x' into CR-6Devel 2021-02-06 12:58:31 -05:00
InsanityAutomation 83872e7b67 Update Configuration_adv.h 2021-02-06 12:57:44 -05:00
InsanityAutomation 7d4870fb4d Update temperature.cpp 2021-02-06 12:57:41 -05:00
InsanityAutomation 3cacab40da Update dwin.cpp 2021-02-02 09:32:51 -05:00
InsanityAutomation b8d900b70d Save after leveling explicitly 2021-01-30 18:08:46 -05:00
InsanityAutomation b4ede61682 Bump to current, fix temp drop, bump version 2021-01-30 15:56:58 -05:00
InsanityAutomation 7e8e06fe2f Merge branch 'bugfix-2.0.x' into CR-6Devel 2021-01-30 11:03:34 -05:00
InsanityAutomation 0d0beea222 Fix website feed, version 2021-01-19 21:46:56 -05:00
InsanityAutomation f34a9cc66c Update DGUSScreenHandler.cpp 2021-01-19 14:27:20 -05:00
InsanityAutomation c4e0d50ad8 Bump to match community head 2021-01-17 16:56:40 -05:00
InsanityAutomation bcc28b118c Merge branch 'bugfix-2.0.x' into CR-6Devel 2021-01-17 13:29:54 -05:00
InsanityAutomation 2e59150dbe Update Configuration.h 2021-01-09 20:08:14 -05:00
InsanityAutomation 60278bfd75 Update DGUSScreenHandler.cpp 2021-01-01 16:12:11 -05:00
InsanityAutomation a77735d69a Misc updates 2020-12-28 23:42:53 -05:00
InsanityAutomation d03227d564 Minor tweaks 2020-12-27 16:53:14 -05:00
InsanityAutomation 6305bda964 453 board support 2020-12-27 13:08:16 -05:00
InsanityAutomation e082d40d32 Update DGUSScreenHandler.cpp 2020-12-21 13:13:06 -05:00
InsanityAutomation c4963d3d77 Update DGUSScreenHandler.cpp 2020-12-20 16:34:58 -05:00
InsanityAutomation 70740fa7b1 Welcome message 2020-12-20 15:03:27 -05:00
InsanityAutomation 226f077a9a FInish Mesh, fix M117 size 2020-12-20 13:06:06 -05:00
InsanityAutomation 241c27e636 Add mesh value feedback 2020-12-15 13:52:37 -05:00
InsanityAutomation b7d5374020 Send popup button text 2020-12-15 09:56:39 -05:00
InsanityAutomation 30e0d36bc3 Update Configuration.h 2020-12-14 11:34:07 -05:00
InsanityAutomation 057764766e Update DGUSDisplayDef.cpp 2020-12-14 10:38:39 -05:00
InsanityAutomation b5e131b523 Fixups for probe tare, add endstop report and M401 2020-12-13 14:55:50 -05:00
InsanityAutomation 92c60cd22e Make M600 happy 2020-12-13 12:41:50 -05:00
InsanityAutomation dd42b65980 Update Configuration.h 2020-12-12 18:49:02 -05:00
InsanityAutomation f6627c0352 Touchup mesh point updates and M600 fix 2020-12-12 17:44:03 -05:00
InsanityAutomation 2dcdbf6f36 Filament change park and Probing disable heaters 2020-12-12 16:50:16 -05:00
InsanityAutomation 41ccd4a81b Fix a partial overwrite of a merge, a few tweaks and version info 2020-12-12 16:36:42 -05:00
InsanityAutomation 5f20f8f9c7 CR6 Configs 2020-12-12 15:31:55 -05:00
InsanityAutomation a4c2e21329 Initial Touchscreen Support 2020-12-12 15:31:45 -05:00
InsanityAutomation e4714e4d29 Merge branch 'ProbesRequiringEnablePin' into CR-6Devel 2020-12-12 14:04:48 -05:00
InsanityAutomation af9d36ae6d Merge branch 'AddMinimumTempForNozzleAsProbe' into CR-6Devel 2020-12-12 14:03:26 -05:00
Jason Smith c393153243 cleanup 2020-12-08 20:51:57 -08:00
Jason Smith 88613ca7e0 Invert compare, use correct constants, add parens 2020-12-08 20:47:51 -08:00
Jason Smith 88f1e635ac Get all new PROBE_REQUIRES_MINTEMP code inside #ifs 2020-12-08 20:27:53 -08:00
Jason Smith 0c0f7adfaf Clarify that PROBE_REQUIRES_MINTEMP_NOZZLE only works with first extruder 2020-12-08 20:27:01 -08:00
Jason Smith 49b53a04b5 Wait for the same hotend that is heating. 2020-12-08 20:26:36 -08:00
Jason Smith 72cdf4a11d Typos, comments. 2020-12-08 20:15:18 -08:00
Jason Smith 647f776309 Merge remote-tracking branch 'upstream/bugfix-2.0.x' into PRR/20383_AddMinimumTempForNozzleAsProbe 2020-12-08 20:05:28 -08:00
Jason Smith 524eae8e86 explicit return type 2020-12-08 19:59:42 -08:00
Jason Smith 6ce0f3dafb Fix inconsistent lambda return type 2020-12-08 19:54:31 -08:00
Jason Smith 61a1fb7478 Allow multiple endstops along with new feature, simplify code 2020-12-08 19:40:21 -08:00
Jason Smith d8fa698b25 Fix missed rename 2020-12-08 01:21:56 -08:00
Jason Smith 5ed93ec18a Only tare when homing if using probe 2020-12-08 01:18:20 -08:00
Jason Smith a870ebdf9f Add compile test for new feature 2020-12-08 01:11:29 -08:00
Jason Smith 0bf9f04a4d Renames 2020-12-08 01:11:16 -08:00
Jason Smith 0653027c98 Merge remote-tracking branch 'upstream/bugfix-2.0.x' into PRR/20379_ProbesRequiringEnablePin 2020-12-07 21:43:32 -08:00
Victor Mateus Oliveira 5ccfbd44a6 Merge remote-tracking branch 'upstream/bugfix-2.0.x' into pr/20379 2020-12-07 18:00:58 -03:00
InsanityAutomation 26e61f6814 Merge branch 'AddMinimumTempForNozzleAsProbe' of https://github.com/InsanityAutomation/Marlin into AddMinimumTempForNozzleAsProbe 2020-12-06 11:11:34 -05:00
InsanityAutomation e3982ca308 Set configs disabled, add tests 2020-12-06 11:11:14 -05:00
InsanityAutomation 62b81dc2be Update nozzle.cpp 2020-12-06 11:08:32 -05:00
InsanityAutomation 1c0770ea5c Update nozzle.cpp 2020-12-06 11:02:07 -05:00
InsanityAutomation cfb1c4c9f2 Update LPC1768-tests 2020-12-06 10:55:17 -05:00
InsanityAutomation 438bae5f38 Set configs disabled, add tests 2020-12-06 10:48:13 -05:00
InsanityAutomation 3a7f17d782 Add G12 minimum temp 2020-12-06 10:36:25 -05:00
InsanityAutomation 8394f0c3f4 Generalize function out of nozzle as probe 2020-12-06 10:23:09 -05:00
Scott Lahteine e8e4a742b0 fix typo 2020-12-05 22:45:04 -06:00
Scott Lahteine 48b61b7cbd It's not golf 2020-12-05 22:42:15 -06:00
InsanityAutomation bbdd481dab Tweak comments 2020-12-05 18:34:58 -05:00
InsanityAutomation 1570559bba Add safety temperature for nozzle as probe 2020-12-05 18:33:39 -05:00
InsanityAutomation ae24cfa655 Fix borked search / replace 2020-12-05 17:55:46 -05:00
InsanityAutomation f583d933eb Tweaks following PR thread 2020-12-05 17:55:46 -05:00
InsanityAutomation 750bc64202 Add initial support for probes requiring Tare and Enable pins 2020-12-05 17:55:46 -05:00
632 changed files with 13586 additions and 20295 deletions
Binary file not shown.
+162 -317
View File
@@ -1,4 +1,5 @@
/** Marlin 3D Printer Firmware
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
@@ -41,35 +42,36 @@
//===========================================================================
/**
* Here are some useful links to help get your machine configured and calibrated:
* Here are some standard links for getting your machine calibrated:
*
* Example Configs: https://github.com/MarlinFirmware/Configurations/branches/all
*
* Průša Calculator: https://blog.prusaprinters.org/calculator_3416/
*
* Calibration Guides: https://reprap.org/wiki/Calibration
* https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
* https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
* https://youtu.be/wAL9d7FgInk
*
* Calibration Objects: https://www.thingiverse.com/thing:5573
* https://www.thingiverse.com/thing:1278865
* https://reprap.org/wiki/Calibration
* https://youtu.be/wAL9d7FgInk
* http://calculator.josefprusa.cz
* https://reprap.org/wiki/Triffid_Hunter%27s_Calibration_Guide
* https://www.thingiverse.com/thing:5573
* https://sites.google.com/site/repraplogphase/calibration-of-your-reprap
* https://www.thingiverse.com/thing:298812
*/
//===========================================================================
//========================== DELTA / SCARA / TPARA ==========================
//============================= DELTA Printer ===============================
//===========================================================================
// 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.
//
// Download configurations from the link above and customize for your machine.
// Examples are located in config/examples/delta, .../SCARA, and .../TPARA.
//
//===========================================================================
//============================= SCARA Printer ===============================
//===========================================================================
// 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
// Author info of this build printed to the host during boot and M115
#define STRING_CONFIG_H_AUTHOR "3DXtech / Insanity Automation" // Who made the changes.
//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
#define STRING_CONFIG_H_AUTHOR "Tinymachines" // Who made the changes.
#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
/**
* *** VENDORS PLEASE READ ***
@@ -101,14 +103,14 @@
*
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
*/
#define SERIAL_PORT 0
#define SERIAL_PORT 1
/**
* Select a secondary serial port on the board to use for communication with the host.
* Currently Ethernet (-2) is only supported on Teensy 4.1 boards.
* :[-2, -1, 0, 1, 2, 3, 4, 5, 6, 7]
*/
//#define SERIAL_PORT_2 -1
//#define SERIAL_PORT_2 3
/**
* This setting determines the communication speed of the printer.
@@ -119,14 +121,14 @@
*
* :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000]
*/
#define BAUDRATE 250000
#define BAUDRATE 115200
// Enable the Bluetooth serial interface on AT90USB devices
//#define BLUETOOTH
// Choose the name from boards.h that matches your setup
#ifndef MOTHERBOARD
#define MOTHERBOARD BOARD_INTAMSYS40
#define MOTHERBOARD BOARD_CREALITY_V453
#endif
// Name displayed in the LCD "Ready" message and Info menu
@@ -162,8 +164,8 @@
* 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)
* 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.
* See additional options in Configuration_adv.h.
@@ -310,29 +312,24 @@
* Enable and connect the power supply to the PS_ON_PIN.
* Specify whether the power supply is active HIGH or active LOW.
*/
#define PSU_CONTROL
//#define PSU_CONTROL
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
#define PSU_ACTIVE_STATE HIGH // Set 'LOW' for ATX, 'HIGH' for X-Box
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
//#define PSU_POWERUP_DELAY 250 // (ms) Delay for the PSU to warm up to full power
//#define PSU_POWERUP_GCODE "M355 S1" // G-code to run after power-on (e.g., case light on)
//#define PSU_POWEROFF_GCODE "M355 S0" // G-code to run before power-off (e.g., case light off)
#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
//#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
#if ENABLED(AUTO_POWER_CONTROL)
#define AUTO_POWER_FANS // Turn on PSU if fans need power
#define AUTO_POWER_E_FANS
#define AUTO_POWER_CONTROLLERFAN
#define AUTO_POWER_CHAMBER_FAN
#define AUTO_POWER_COOLER_FAN
#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 AUTO_POWER_COOLER_TEMP 26 // (°C) Turn on PSU if the cooler is over this temperature
#define POWER_TIMEOUT 120 // (s) Turn off power if the machine is idle for this duration
//#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
@@ -408,7 +405,7 @@
* 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
* 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
*/
#define TEMP_SENSOR_0 20
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
#define TEMP_SENSOR_2 0
#define TEMP_SENSOR_3 0
@@ -418,8 +415,7 @@
#define TEMP_SENSOR_7 0
#define TEMP_SENSOR_BED 1
#define TEMP_SENSOR_PROBE 0
#define TEMP_SENSOR_CHAMBER 1
#define TEMP_SENSOR_COOLER 0
#define TEMP_SENSOR_CHAMBER 0
// Dummy thermistor constant temperature readings, for use with 998 and 999
#define DUMMY_THERMISTOR_998_VALUE 25
@@ -436,21 +432,17 @@
//#define TEMP_SENSOR_1_AS_REDUNDANT
#define MAX_REDUNDANT_TEMP_SENSOR_DIFF 10
#define TEMP_RESIDENCY_TIME 3 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_WINDOW 3 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_HYSTERESIS 5 // (°C) Temperature proximity considered "close enough" to the target
#define TEMP_RESIDENCY_TIME 10 // (seconds) Time to wait for hotend to "settle" in M109
#define TEMP_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
#define TEMP_BED_RESIDENCY_TIME 5 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_RESIDENCY_TIME 10 // (seconds) Time to wait for bed to "settle" in M190
#define TEMP_BED_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_BED_HYSTERESIS 3 // (°C) Temperature proximity considered "close enough" to the target
#define TEMP_CHAMBER_RESIDENCY_TIME 10 // (seconds) Time to wait for chamber to "settle" in M191
#define TEMP_CHAMBER_WINDOW 1 // (°C) Temperature proximity for the "temperature reached" timer
#define TEMP_CHAMBER_HYSTERESIS 5 // (°C) Temperature proximity considered "close enough" to the target
// Below this temperature the heater will be switched off
// because it probably indicates a broken thermistor wire.
#define HEATER_0_MINTEMP 5
#define HEATER_0_MINTEMP 0
#define HEATER_1_MINTEMP 5
#define HEATER_2_MINTEMP 5
#define HEATER_3_MINTEMP 5
@@ -458,13 +450,12 @@
#define HEATER_5_MINTEMP 5
#define HEATER_6_MINTEMP 5
#define HEATER_7_MINTEMP 5
#define BED_MINTEMP 5
#define CHAMBER_MINTEMP 5
#define BED_MINTEMP 0
// Above this temperature the heater will be switched off.
// This can protect components from overheating, but NOT from shorts and failures.
// (Use MINTEMP for thermistor short/failure protection.)
#define HEATER_0_MAXTEMP 415
#define HEATER_0_MAXTEMP 300
#define HEATER_1_MAXTEMP 275
#define HEATER_2_MAXTEMP 275
#define HEATER_3_MAXTEMP 275
@@ -472,17 +463,7 @@
#define HEATER_5_MAXTEMP 275
#define HEATER_6_MAXTEMP 275
#define HEATER_7_MAXTEMP 275
#define BED_MAXTEMP 150
#define CHAMBER_MAXTEMP 80
/**
* Thermal Overshoot
* During heatup (and printing) the temperature can often "overshoot" the target by many degrees
* (especially before PID tuning). Setting the target temperature too close to MAXTEMP guarantees
* a MAXTEMP shutdown! Use these values to forbid temperatures being set too close to MAXTEMP.
*/
#define HOTEND_OVERSHOOT 15 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
#define BED_MAXTEMP 120
//===========================================================================
//============================= PID Settings ================================
@@ -496,8 +477,8 @@
#define PID_K1 0.95 // Smoothing factor within any PID loop
#if ENABLED(PIDTEMP)
#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of PROGMEM)
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of PROGMEM)
//#define PID_PARAMS_PER_HOTEND // Uses separate PID parameters for each extruder (useful for mismatched extruders)
// Set/get with gcode: M301 E[extruder number, 0-2]
@@ -508,9 +489,9 @@
#define DEFAULT_Ki_LIST { 1.08, 1.08 }
#define DEFAULT_Kd_LIST { 114.00, 114.00 }
#else
#define DEFAULT_Kp 10.5
#define DEFAULT_Ki 0.45
#define DEFAULT_Kd 70
#define DEFAULT_Kp 14.32
#define DEFAULT_Ki 0.81
#define DEFAULT_Kd 63.12
#endif
#endif // PIDTEMP
@@ -549,58 +530,14 @@
//120V 250W silicone heater into 4mm borosilicate (MendelMax 1.5+)
//from FOPDT model - kp=.39 Tp=405 Tdead=66, Tc set to 79.2, aggressive factor of .15 (vs .1, 1, 10)
#define DEFAULT_bedKp 104.28
#define DEFAULT_bedKi 20.53
#define DEFAULT_bedKd 353.10
#define DEFAULT_bedKp 79.49
#define DEFAULT_bedKi 1.17
#define DEFAULT_bedKd 1349.52
// FIND YOUR OWN: "M303 E-1 C8 S90" to run autotune on the bed at 90 degreesC for 8 cycles.
#endif // PIDTEMPBED
//===========================================================================
//==================== PID > Chamber Temperature Control ====================
//===========================================================================
/**
* PID Chamber Heating
*
* If this option is enabled set PID constants below.
* If this option is disabled, bang-bang will be used and CHAMBER_LIMIT_SWITCHING will enable
* hysteresis.
*
* The PID frequency will be the same as the extruder PWM.
* If PID_dT is the default, and correct for the hardware/configuration, that means 7.689Hz,
* which is fine for driving a square wave into a resistive load and does not significantly
* impact FET heating. This also works fine on a Fotek SSR-10DA Solid State Relay into a 200W
* heater. If your configuration is significantly different than this and you don't understand
* the issues involved, don't use chamber PID until someone else verifies that your hardware works.
*/
//#define PIDTEMPCHAMBER
//#define CHAMBER_LIMIT_SWITCHING
/**
* Max Chamber Power
* Applies to all forms of chamber control (PID, bang-bang, and bang-bang with hysteresis).
* When set to any value below 255, enables a form of PWM to the chamber heater that acts like a divider
* so don't use it unless you are OK with PWM on your heater. (See the comment on enabling PIDTEMPCHAMBER)
*/
#define MAX_CHAMBER_POWER 255 // limits duty cycle to chamber heater; 255=full current
#if ENABLED(PIDTEMPCHAMBER)
#define MIN_CHAMBER_POWER 0
//#define PID_CHAMBER_DEBUG // Sends debug data to the serial port.
// Lasko "MyHeat Personal Heater" (200w) modified with a Fotek SSR-10DA to control only the heating element
// and placed inside the small Creality printer enclosure tent.
//
#define DEFAULT_chamberKp 37.04
#define DEFAULT_chamberKi 1.40
#define DEFAULT_chamberKd 655.17
// M309 P37.04 I1.04 D655.17
// FIND YOUR OWN: "M303 E-2 C8 S50" to run autotune on the chamber at 50 degreesC for 8 cycles.
#endif // PIDTEMPCHAMBER
#if ANY(PIDTEMP, PIDTEMPBED, PIDTEMPCHAMBER)
#if EITHER(PIDTEMP, PIDTEMPBED)
//#define PID_DEBUG // Sends debug data to the serial port. Use 'M303 D' to toggle activation.
//#define PID_OPENLOOP // Puts PID in open loop. M104/M140 sets the output power from 0 to PID_MAX
//#define SLOW_PWM_HEATERS // PWM with very low frequency (roughly 0.125Hz=8s) and minimum state time of approximately 1s useful for heaters driven by a relay
@@ -625,7 +562,7 @@
* Note: For Bowden Extruders make this large enough to allow load/unload.
*/
#define PREVENT_LENGTHY_EXTRUDE
#define EXTRUDE_MAXLENGTH 200
#define EXTRUDE_MAXLENGTH 1000
//===========================================================================
//======================== Thermal Runaway Protection =======================
@@ -646,8 +583,7 @@
#define THERMAL_PROTECTION_HOTENDS // Enable thermal protection for all extruders
#define THERMAL_PROTECTION_BED // Enable thermal protection for the heated bed
#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber
#define THERMAL_PROTECTION_COOLER // Enable thermal protection for the laser cooling
//#define THERMAL_PROTECTION_CHAMBER // Enable thermal protection for the heated chamber
//===========================================================================
//============================= Mechanical Settings =========================
@@ -708,13 +644,13 @@
#endif
// Mechanical endstop with COM to ground and NC to Signal uses "false" here (most common setup).
#define X_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING true // Set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING true // Set to true to invert the logic of the probe.
#define X_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define X_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Y_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MAX_ENDSTOP_INVERTING false // Set to true to invert the logic of the endstop.
#define Z_MIN_PROBE_ENDSTOP_INVERTING false // Set to true to invert the logic of the probe.
/**
* Stepper Drivers
@@ -724,8 +660,6 @@
*
* A4988 is assumed for unspecified drivers.
*
* Use TMC2208/TMC2208_STANDALONE for TMC2225 drivers and TMC2209/TMC2209_STANDALONE for TMC2226 drivers.
*
* Options: A4988, A5984, DRV8825, LV8729, L6470, L6474, POWERSTEP01,
* TB6560, TB6600, TMC2100,
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
@@ -734,15 +668,15 @@
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'L6470', 'L6474', 'POWERSTEP01', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC26X', 'TMC26X_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
*/
#define X_DRIVER_TYPE A4988
#define Y_DRIVER_TYPE A4988
#define Z_DRIVER_TYPE A4988
#define X_DRIVER_TYPE TMC2209_STANDALONE
#define Y_DRIVER_TYPE TMC2209_STANDALONE
#define Z_DRIVER_TYPE TMC2209_STANDALONE
//#define X2_DRIVER_TYPE A4988
//#define Y2_DRIVER_TYPE A4988
//#define Z2_DRIVER_TYPE A4988
//#define Z3_DRIVER_TYPE A4988
//#define Z4_DRIVER_TYPE A4988
#define E0_DRIVER_TYPE A4988
#define E0_DRIVER_TYPE TMC2209_STANDALONE
//#define E1_DRIVER_TYPE A4988
//#define E2_DRIVER_TYPE A4988
//#define E3_DRIVER_TYPE A4988
@@ -797,14 +731,14 @@
* Override with M92
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 800, 92.6 }
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 93 }
/**
* Default Max Feed Rate (mm/s)
* Override with M203
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_FEEDRATE { 300, 300, 20, 70 }
#define DEFAULT_MAX_FEEDRATE { 500, 500, 5, 25 }
//#define LIMITED_MAX_FR_EDITING // Limit edit via M203 or LCD to DEFAULT_MAX_FEEDRATE * 2
#if ENABLED(LIMITED_MAX_FR_EDITING)
@@ -817,7 +751,7 @@
* Override with M201
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_ACCELERATION { 9000, 9000, 100, 10000 }
#define DEFAULT_MAX_ACCELERATION { 500, 500, 100, 1000 }
//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2
#if ENABLED(LIMITED_MAX_ACCEL_EDITING)
@@ -832,9 +766,9 @@
* M204 R Retract Acceleration
* M204 T Travel Acceleration
*/
#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves
#define DEFAULT_RETRACT_ACCELERATION 3000 // E acceleration for retracts
#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves
#define DEFAULT_ACCELERATION 500 // X, Y, Z and E acceleration for printing moves
#define DEFAULT_RETRACT_ACCELERATION 1000 // E acceleration for retracts
#define DEFAULT_TRAVEL_ACCELERATION 1000 // X, Y, Z acceleration for travel (non printing) moves
/**
* Default Jerk limits (mm/s)
@@ -868,7 +802,7 @@
* https://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html
*/
#if DISABLED(CLASSIC_JERK)
#define JUNCTION_DEVIATION_MM 0.013 // (mm) Distance from real junction edge
#define JUNCTION_DEVIATION_MM 0.05 // (mm) Distance from real junction edge
#define JD_HANDLE_SMALL_SEGMENTS // Use curvature estimation instead of just the junction angle
// for small segments (< 1mm) with large junction angles (> 135°).
#endif
@@ -900,7 +834,7 @@
#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN
// Force the use of the probe for Z-axis homing
//#define USE_PROBE_FOR_Z_HOMING
#define USE_PROBE_FOR_Z_HOMING
/**
* Z_MIN_PROBE_PIN
@@ -944,7 +878,7 @@
* Use the nozzle as the probe, as with a conductive
* nozzle system or a piezo-electric smart effector.
*/
//#define NOZZLE_AS_PROBE
#define NOZZLE_AS_PROBE
/**
* Z Servo Probe, such as an endstop switch on a rotating arm.
@@ -1047,20 +981,29 @@
* | [-] |
* O-- FRONT --+
*/
#define NOZZLE_TO_PROBE_OFFSET { 10, 10, 0 }
#define NOZZLE_TO_PROBE_OFFSET { 0, 0, 0.2 }
// Most probes should stay away from the edges of the bed, but
// with NOZZLE_AS_PROBE this can be negative for a wider probing area.
#define PROBING_MARGIN 10
#define PROBING_MARGIN 5
// X and Y axis travel speed (mm/min) between probes
#define XY_PROBE_FEEDRATE (133*60)
#define XY_PROBE_SPEED (133*60)
// Feedrate (mm/min) for the first approach when double-probing (MULTIPLE_PROBING == 2)
#define Z_PROBE_FEEDRATE_FAST (4*60)
#define Z_PROBE_SPEED_FAST ((4 * 60) / 2)
// Feedrate (mm/min) for the "accurate" probe of each point
#define Z_PROBE_FEEDRATE_SLOW (Z_PROBE_FEEDRATE_FAST / 2)
#define Z_PROBE_SPEED_SLOW (Z_PROBE_SPEED_FAST / 2)
// Fail to probe if the probe does not indicate itself as active.
// This may be a switch indicating proper deployment, or an optical switch to report the carriage is near the bed.
#define PROBE_ACTIVE_INPUT
#if ENABLED(PROBE_ACTIVE_INPUT)
#define PROBE_ACTIVE_INPUT_STATE LOW // State indicating probe is active
//#define PROBE_ENABLE_PIN PC6 // Override default pin
#endif
/**
* Probe Activation Switch
@@ -1073,19 +1016,18 @@
//#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
// Probe should be tared prior to each probe
// Useful for strain or piezo sensors which must exclude strain such
// as that from cables or bowden 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_TIME 200 // Time to hold tare pin (milliseconds)
#define PROBE_TARE_DELAY 200 // Delay after tare before (milliseconds)
#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
#if ENABLED(PROBE_ACTIVE_INPUT)
// Fail to tare/probe if PROBE_ACTIVE_INPUT reports the probe to be active
//#define PROBE_TARE_ONLY_WHILE_INACTIVE
#endif
#endif
@@ -1098,7 +1040,7 @@
* A total of 2 does fast/slow probes with a weighted average.
* A total of 3 or more adds more slow probes, taking the average.
*/
//#define MULTIPLE_PROBING 2
#define MULTIPLE_PROBING 2
//#define EXTRA_PROBING 1
/**
@@ -1116,18 +1058,18 @@
* But: `M851 Z+1` with a CLEARANCE of 2 => 2mm from bed to nozzle.
*/
#define Z_CLEARANCE_DEPLOY_PROBE 10 // Z Clearance for Deploy/Stow
#define Z_CLEARANCE_BETWEEN_PROBES 5 // Z Clearance between probe points
#define Z_CLEARANCE_MULTI_PROBE 5 // Z Clearance between multiple probes
#define Z_CLEARANCE_BETWEEN_PROBES 3 // Z Clearance between probe points
#define Z_CLEARANCE_MULTI_PROBE 3 // Z Clearance between multiple probes
//#define Z_AFTER_PROBING 5 // Z position after probing is done
#define Z_PROBE_LOW_POINT -2 // Farthest distance below the trigger-point to go before stopping
#define Z_PROBE_LOW_POINT -3 // Farthest distance below the trigger-point to go before stopping
// For M851 give a range for adjusting the Z probe offset
#define Z_PROBE_OFFSET_RANGE_MIN -9
#define Z_PROBE_OFFSET_RANGE_MAX 9
#define Z_PROBE_OFFSET_RANGE_MIN -10
#define Z_PROBE_OFFSET_RANGE_MAX 10
// Enable the M48 repeatability test to test probe accuracy
//#define Z_MIN_PROBE_REPEATABILITY_TEST
#define Z_MIN_PROBE_REPEATABILITY_TEST
// Before deploy/stow pause for user confirmation
//#define PAUSE_BEFORE_DEPLOY_STOW
@@ -1142,19 +1084,18 @@
* These options are most useful for the BLTouch probe, but may also improve
* readings with inductive probes and piezo sensors.
*/
//#define PROBING_HEATERS_OFF // Turn heaters off when probing
#define PROBING_HEATERS_OFF // Turn heaters off when probing
#if ENABLED(PROBING_HEATERS_OFF)
//#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy)
//#define WAIT_FOR_HOTEND // Wait for hotend to heat back up between probes (to improve accuracy & prevent cold extrude)
#define WAIT_FOR_BED_HEATER // Wait for bed to heat back up between probes (to improve accuracy)
#endif
//#define PROBING_FANS_OFF // Turn fans off when probing
//#define PROBING_STEPPERS_OFF // Turn steppers off (unless needed to hold position) when probing
#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
#define PREHEAT_BEFORE_PROBING
#if ENABLED(PREHEAT_BEFORE_PROBING)
#define PROBING_NOZZLE_TEMP 120 // (°C) Only applies to E0 at this time
#define PROBING_NOZZLE_TEMP 170 // (°C) Only applies to E0 at this time
#define PROBING_BED_TEMP 50
#endif
@@ -1189,7 +1130,7 @@
// @section extruder
// For direct drive extruder v9 set to true, for geared extruder set to false.
#define INVERT_E0_DIR false
#define INVERT_E0_DIR true
#define INVERT_E1_DIR false
#define INVERT_E2_DIR false
#define INVERT_E3_DIR false
@@ -1200,20 +1141,14 @@
// @section homing
//#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 NO_MOTION_BEFORE_HOMING // Inhibit movement until all axes have been homed
/**
* Set Z_IDLE_HEIGHT if the Z-Axis moves on its own when steppers are disabled.
* - Use a low value (i.e., Z_MIN_POS) if the nozzle falls down to the bed.
* - Use a large value (i.e., Z_MAX_POS) if the bed falls down, away from the nozzle.
*/
//#define Z_IDLE_HEIGHT Z_HOME_POS
//#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 Z_HOMING_HEIGHT 4 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
#define Z_HOMING_HEIGHT 15 // (mm) Minimal Z height before homing (G28) for Z clearance above the bed, clamps, ...
// Be sure to have this much clearance over your Z_MAX_POS to prevent grinding.
//#define Z_AFTER_HOMING 10 // (mm) Height to move to after homing Z
#define Z_AFTER_HOMING 5 // (mm) Height to move to after homing Z
// Direction of endstops when homing; 1=MAX, -1=MIN
// :[-1,1]
@@ -1224,16 +1159,16 @@
// @section machine
// The size of the print bed
#define X_BED_SIZE 260
#define Y_BED_SIZE 260
#define X_BED_SIZE 235
#define Y_BED_SIZE 235
// Travel limits (mm) after homing, corresponding to endstop positions.
#define X_MIN_POS 0
#define Y_MIN_POS 0
#define X_MIN_POS -5
#define Y_MIN_POS -2
#define Z_MIN_POS 0
#define X_MAX_POS X_BED_SIZE
#define Y_MAX_POS Y_BED_SIZE
#define Z_MAX_POS 260
#define Z_MAX_POS 250
/**
* Software Endstops
@@ -1261,19 +1196,13 @@
#endif
#if EITHER(MIN_SOFTWARE_ENDSTOPS, MAX_SOFTWARE_ENDSTOPS)
#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD
//#define SOFT_ENDSTOPS_MENU_ITEM // Enable/Disable software endstops from the LCD
#endif
/**
* Filament Runout Sensors
* Mechanical or opto endstops are used to check for the presence of filament.
*
* IMPORTANT: Runout will only trigger if Marlin is aware that a print job is running.
* Marlin knows a print job is running when:
* 1. Running a print job from media started with M24.
* 2. The Print Job Timer has been started with M75.
* 3. The heaters were turned on and PRINTJOB_TIMER_AUTOSTART is enabled.
*
* RAMPS-based boards use SERVO3_PIN for the first runout sensor.
* For other boards you may need to define FIL_RUNOUT_PIN, FIL_RUNOUT2_PIN, etc.
*/
@@ -1281,49 +1210,12 @@
#if ENABLED(FILAMENT_RUNOUT_SENSOR)
#define FIL_RUNOUT_ENABLED_DEFAULT true // Enable the sensor on startup. Override with M412 followed by M500.
#define NUM_RUNOUT_SENSORS 1 // Number of sensors, up to one per extruder. Define a FIL_RUNOUT#_PIN for each.
#define FIL_RUNOUT_STATE HIGH // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
#define FIL_RUNOUT_STATE LOW // Pin state indicating that filament is NOT present.
#define FIL_RUNOUT_PULLUP // Use internal pullup for filament runout pins.
//#define FIL_RUNOUT_PULLDOWN // Use internal pulldown for filament runout pins.
//#define WATCH_ALL_RUNOUT_SENSORS // Execute runout script on any triggering sensor, not only for the active extruder.
// This is automatically enabled for MIXING_EXTRUDERs.
// 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
// Commands to execute on filament runout.
// With multiple runout sensors use the %c placeholder for the current tool in commands (e.g., "M600 T%c")
// NOTE: After 'M412 H1' the host handles filament runout and this script does not apply.
// 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"
// After a runout is detected, continue printing this length of filament
@@ -1379,9 +1271,9 @@
*/
//#define AUTO_BED_LEVELING_3POINT
//#define AUTO_BED_LEVELING_LINEAR
//#define AUTO_BED_LEVELING_BILINEAR
#define AUTO_BED_LEVELING_BILINEAR
//#define AUTO_BED_LEVELING_UBL
#define MESH_BED_LEVELING
//#define MESH_BED_LEVELING
/**
* Normally G28 leaves leveling disabled on completion. Enable one of
@@ -1405,16 +1297,13 @@
* Turn on with the command 'M111 S32'.
* NOTE: Requires a lot of PROGMEM!
*/
//#define DEBUG_LEVELING_FEATURE
#define DEBUG_LEVELING_FEATURE
#if ANY(MESH_BED_LEVELING, AUTO_BED_LEVELING_BILINEAR, AUTO_BED_LEVELING_UBL)
// Gradually reduce leveling correction until a set height is reached,
// at which point movement will be level to the machine's XY plane.
// The height can be set with M420 Z<height>
#define ENABLE_LEVELING_FADE_HEIGHT
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
#define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height.
#endif
// For Cartesian machines, instead of dividing moves on mesh boundaries,
// split up moves into short segments like a Delta. This follows the
@@ -1441,17 +1330,17 @@
#if EITHER(AUTO_BED_LEVELING_LINEAR, AUTO_BED_LEVELING_BILINEAR)
// Set the number of grid points per dimension.
#define GRID_MAX_POINTS_X 3
#define GRID_MAX_POINTS_X 5
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
// Probe along the Y axis, advancing X after each column
//#define PROBE_Y_FIRST
#define PROBE_Y_FIRST
#if ENABLED(AUTO_BED_LEVELING_BILINEAR)
// Beyond the probed grid, continue the implied tilt?
// Default is to maintain the height of the nearest edge.
//#define EXTRAPOLATE_BEYOND_GRID
#define EXTRAPOLATE_BEYOND_GRID
//
// Experimental Subdivision of the grid by Catmull-Rom method.
@@ -1490,7 +1379,7 @@
//===========================================================================
#define MESH_INSET 10 // Set Mesh bounds as an inset region of the bed
#define GRID_MAX_POINTS_X 5 // Don't use more than 7 points per axis, implementation limited.
#define GRID_MAX_POINTS_X 3 // Don't use more than 7 points per axis, implementation limited.
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
//#define MESH_G28_REST_ORIGIN // After homing all axes ('G28' or 'G28 XYZ') rest Z at Z_MIN_POS
@@ -1501,28 +1390,22 @@
* Add a bed leveling sub-menu for ABL or MBL.
* Include a guided procedure if manual probing is enabled.
*/
#define LCD_BED_LEVELING
//#define LCD_BED_LEVELING
#if ENABLED(LCD_BED_LEVELING)
#define MESH_EDIT_Z_STEP 0.025 // (mm) Step size while manually probing Z axis.
#define LCD_PROBE_Z_RANGE 4 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
#define MESH_EDIT_MENU // Add a menu to edit mesh points
//#define MESH_EDIT_MENU // Add a menu to edit mesh points
#endif
// Add a menu item to move between bed corners for manual bed adjustment
#define LEVEL_BED_CORNERS
//#define LEVEL_BED_CORNERS
#if ENABLED(LEVEL_BED_CORNERS)
#define LEVEL_CORNERS_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
#define LEVEL_CORNERS_HEIGHT 0.0 // (mm) Z height of nozzle at leveling points
#define LEVEL_CORNERS_Z_HOP 4.0 // (mm) Z height of nozzle between leveling points
//#define LEVEL_CENTER_TOO // Move to the center after the last corner
//#define LEVEL_CORNERS_USE_PROBE
#if ENABLED(LEVEL_CORNERS_USE_PROBE)
#define LEVEL_CORNERS_PROBE_TOLERANCE 0.1
#define LEVEL_CORNERS_VERIFY_RAISED // After adjustment triggers the probe, re-probe to verify
//#define LEVEL_CORNERS_AUDIO_FEEDBACK
#endif
/**
* Corner Leveling Order
@@ -1570,7 +1453,7 @@
// - Move the Z probe (or nozzle) to a defined XY point before Z Homing.
// - Prevent Z homing when the Z probe is outside bed area.
//
//#define Z_SAFE_HOMING
#define Z_SAFE_HOMING
#if ENABLED(Z_SAFE_HOMING)
#define Z_SAFE_HOMING_X_POINT X_CENTER // X point for Z homing
@@ -1578,7 +1461,7 @@
#endif
// Homing speeds (mm/min)
#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (4*60) }
#define HOMING_FEEDRATE_MM_M { (50*60), (50*60), (10*60) }
// Validate that endstops are triggered on homing moves
#define VALIDATE_HOMING_ENDSTOPS
@@ -1657,7 +1540,7 @@
*/
#define EEPROM_SETTINGS // Persistent storage with M500 and M501
//#define DISABLE_M503 // Saves ~2700 bytes of PROGMEM. Disable for release!
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
//#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save PROGMEM.
#define EEPROM_BOOT_SILENT // Keep M503 quiet and only give errors during first load
#if ENABLED(EEPROM_SETTINGS)
#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
@@ -1689,16 +1572,14 @@
// Preheat Constants - Up to 5 are supported without changes
//
#define PREHEAT_1_LABEL "PLA"
#define PREHEAT_1_TEMP_HOTEND 180
#define PREHEAT_1_TEMP_BED 70
#define PREHEAT_1_TEMP_CHAMBER 35
#define PREHEAT_1_FAN_SPEED 0 // Value from 0 to 255
#define PREHEAT_1_TEMP_HOTEND 200
#define PREHEAT_1_TEMP_BED 60
#define PREHEAT_1_FAN_SPEED 255 // Value from 0 to 255
#define PREHEAT_2_LABEL "ABS"
#define PREHEAT_2_TEMP_HOTEND 240
#define PREHEAT_2_TEMP_BED 110
#define PREHEAT_2_TEMP_CHAMBER 45
#define PREHEAT_2_FAN_SPEED 0 // Value from 0 to 255
#define PREHEAT_2_TEMP_BED 70
#define PREHEAT_2_FAN_SPEED 255 // Value from 0 to 255
/**
* Nozzle Park
@@ -1715,8 +1596,8 @@
#if ENABLED(NOZZLE_PARK_FEATURE)
// Specify a park position as { X, Y, Z_raise }
#define NOZZLE_PARK_POINT { (X_CENTER), (Y_CENTER), 20 }
//#define NOZZLE_PARK_X_ONLY // X move only is required to park
#define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
#define NOZZLE_PARK_X_ONLY // X move only is required to park
//#define NOZZLE_PARK_Y_ONLY // Y move only is required to park
#define NOZZLE_PARK_Z_RAISE_MIN 2 // (mm) Always raise Z by at least this distance
#define NOZZLE_PARK_XY_FEEDRATE 100 // (mm/s) X and Y axes feedrate (also used for delta Z axis)
@@ -1828,7 +1709,7 @@
*
* View the current statistics with M78.
*/
//#define PRINTCOUNTER
#define PRINTCOUNTER
#if ENABLED(PRINTCOUNTER)
#define PRINTCOUNTER_SAVE_INTERVAL 60 // (minutes) EEPROM save interval during print
#endif
@@ -1943,13 +1824,13 @@
// This option overrides the default number of encoder pulses needed to
// produce one step. Should be increased for high-resolution encoders.
//
//#define ENCODER_PULSES_PER_STEP 4
//#define ENCODER_PULSES_PER_STEP 4 // SD: I don't think this is needed, Ender 3 V2 used probably same codebase
//
// Use this option to override the number of step signals required to
// move between next/prev menu items.
//
//#define ENCODER_STEPS_PER_MENU_ITEM 1
//#define ENCODER_STEPS_PER_MENU_ITEM 1 // SD: I don't think this is needed, Ender 3 V2 used probably same codebase
/**
* Encoder Direction Options
@@ -1989,7 +1870,7 @@
//
// Add individual axis homing items (Home X, Home Y, and Home Z) to the LCD menu.
//
#define INDIVIDUAL_AXIS_HOMING_MENU
//#define INDIVIDUAL_AXIS_HOMING_MENU
//
// SPEAKER/BUZZER
@@ -2006,8 +1887,8 @@
// Note: Test audio output with the G-Code:
// M300 S<frequency Hz> P<duration ms>
//
//#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
//#define LCD_FEEDBACK_FREQUENCY_HZ 5000
#define LCD_FEEDBACK_FREQUENCY_DURATION_MS 2
#define LCD_FEEDBACK_FREQUENCY_HZ 5000
//=============================================================================
//======================== LCD / Controller Selection =========================
@@ -2022,14 +1903,6 @@
//
//#define REPRAP_DISCOUNT_SMART_CONTROLLER
//
// GT2560 (YHCB2004) LCD Display
//
// Requires Testato, Koepel softwarewire library and
// Andriy Golovnya's LiquidCrystal_AIP31068 library.
//
//#define YHCB2004
//
// Original RADDS LCD Display+Encoder+SDCardReader
// http://doku.radds.org/dokumentation/lcd-display/
@@ -2178,12 +2051,7 @@
// RepRapDiscount FULL GRAPHIC Smart Controller
// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
//
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
//
// K.3D Full Graphic Smart Controller
//
//#define K3D_FULL_GRAPHIC_SMART_CONTROLLER
//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
//
// ReprapWorld Graphical LCD
@@ -2284,7 +2152,6 @@
// 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
@@ -2322,7 +2189,7 @@
//#define OLED_PANEL_TINYBOY2
//
// MKS OLED 1.3" 128×64 Full Graphics Controller
// MKS OLED 1.3" 128×64 FULL GRAPHICS CONTROLLER
// https://reprap.org/wiki/MKS_12864OLED
//
// Tiny, but very sharp OLED display
@@ -2331,7 +2198,7 @@
//#define MKS_12864OLED_SSD1306 // Uses the SSD1306 controller
//
// Zonestar OLED 128×64 Full Graphics Controller
// Zonestar OLED 128×64 FULL GRAPHICS CONTROLLER
//
//#define ZONESTAR_12864LCD // Graphical (DOGM) with ST7920 controller
//#define ZONESTAR_12864OLED // 1.3" OLED with SH1106 controller (default)
@@ -2348,15 +2215,10 @@
//#define OVERLORD_OLED
//
// FYSETC OLED 2.42" 128×64 Full Graphics Controller with WS2812 RGB
// FYSETC OLED 2.42" 128×64 FULL GRAPHICS CONTROLLER with WS2812 RGB
// Where to find : https://www.aliexpress.com/item/4000345255731.html
//#define FYSETC_242_OLED_12864 // Uses the SSD1309 controller
//
// K.3D SSD1309 OLED 2.42" 128×64 Full Graphics Controller
//
//#define K3D_242_OLED_CONTROLLER // Software SPI
//=============================================================================
//========================== Extensible UI Displays ===========================
//=============================================================================
@@ -2369,7 +2231,12 @@
//#define DGUS_LCD_UI_ORIGIN
//#define DGUS_LCD_UI_FYSETC
//#define DGUS_LCD_UI_HIPRECY
//#define DGUS_LCD_UI_MKS
//
// CR-6 OEM touch screen. A DWIN display with touch.
//
#define DGUS_LCD_UI_CREALITY_TOUCH
//
// Touch-screen LCD for Malyan M200/M300 printers
@@ -2395,14 +2262,6 @@
//#define ANYCUBIC_LCD_DEBUG
#endif
//
// 320x240 Nextion 2.8" serial TFT Resistive Touch Screen NX3224T028
//
//#define NEXTION_TFT
#if ENABLED(NEXTION_TFT)
#define LCD_SERIAL_PORT 1 // Default is 1 for Nextion
#endif
//
// Third-party or vendor-customized controller interfaces.
// Sources should be installed in 'src/lcd/extui'.
@@ -2492,19 +2351,6 @@
// Generic TFT with detailed options
//
//#define TFT_GENERIC
#if ENABLED(TFT_GENERIC)
// :[ 'AUTO', 'ST7735', 'ST7789', 'ST7796', 'R61505', 'ILI9328', 'ILI9341', 'ILI9488' ]
#define TFT_DRIVER AUTO
// Interface. Enable one of the following options:
//#define TFT_INTERFACE_FSMC
//#define TFT_INTERFACE_SPI
// TFT Resolution. Enable one of the following options:
//#define TFT_RES_320x240
//#define TFT_RES_480x272
//#define TFT_RES_480x320
#endif
/**
* TFT UI - User Interface Selection. Enable one of the following options:
@@ -2679,7 +2525,6 @@
// Use a single NeoPixel LED for static (background) lighting
//#define NEOPIXEL_BKGD_LED_INDEX 0 // Index of the LED to use
//#define NEOPIXEL_BKGD_COLOR { 255, 255, 255, 0 } // R, G, B, W
//#define NEOPIXEL_BKGD_ALWAYS_ON // Keep the backlight on when other NeoPixels are off
#endif
/**
+188 -305
View File
File diff suppressed because it is too large Load Diff
-2
View File
@@ -323,8 +323,6 @@ else ifeq ($(HARDWARE_MOTHERBOARD),1203)
else ifeq ($(HARDWARE_MOTHERBOARD),1204)
# abee Scoovo X9H
else ifeq ($(HARDWARE_MOTHERBOARD),1205)
# Rambo ThinkerV2
else ifeq ($(HARDWARE_MOTHERBOARD),1206)
#
# Other ATmega1280, ATmega2560
+6 -6
View File
@@ -28,25 +28,25 @@
/**
* Marlin release version identifier
*/
//#define SHORT_BUILD_VERSION "bugfix-2.0.x"
#define SHORT_BUILD_VERSION "TM3D2.0.7.2-CR6-C"
/**
* Verbose version identifier which should contain a reference to the location
* from where the binary was downloaded or the source code was compiled.
*/
//#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION
#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION
/**
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
* here we define this default string as the date where the latest release
* version was tagged.
*/
//#define STRING_DISTRIBUTION_DATE "2019-07-10"
#define STRING_DISTRIBUTION_DATE "2020-12-28"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
*/
//#define MACHINE_NAME "3D Printer"
#define MACHINE_NAME "TM3D CR-6"
/**
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
@@ -54,7 +54,7 @@
* has a distinct Github fork— the Source Code URL should just be the main
* Marlin repository.
*/
//#define SOURCE_CODE_URL "github.com/MarlinFirmware/Marlin"
#define SOURCE_CODE_URL "https://github.com/InsanityAutomation/Marlin/tree/CR-6Devel"
/**
* Default generic printer UUID.
@@ -65,7 +65,7 @@
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
//#define WEBSITE_URL "marlinfw.org"
#define WEBSITE_URL "tinymachines3d.com"
/**
* Set the vendor info the serial USB interface, if changable
-103
View File
@@ -1,103 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Custom Bitmap for splashscreen
*
* You may use one of the following tools to generate the C++ bitmap array from
* a black and white image:
*
* - http://www.marlinfw.org/tools/u8glib/converter.html
* - http://www.digole.com/tools/PicturetoC_Hex_converter.php
*/
#include <avr/pgmspace.h>
#define CUSTOM_BOOTSCREEN_TIMEOUT 2500
#define CUSTOM_BOOTSCREEN_BMPWIDTH 125
//#define CUSTOM_BOOTSCREEN_INVERTED
const unsigned char custom_start_bmp[] PROGMEM = {
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................................##................................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................................##.##.............................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ................................................................#...#...........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xE7,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ................................................................###..###........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x71,0x80,0x00,0x00,0x00,0x00,0x00,0x00, // .................................................................###...##.......................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x40,0x00,0x00,0x00,0x00,0x00,0x00, // ..................................................................##.....#......................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // ..................................................................####....#.....................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x20,0x00,0x00,0x00,0x00,0x00,0x00, // ................................................................########..#.....................................................
0x00,0x00,0x00,0x00,0x00,0x01,0xF8,0x00,0x87,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, // ...............................................######...........#....########...................................................
0x00,0x00,0x00,0x00,0x00,0x03,0x0C,0x00,0x83,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................##....##..........#.....#####.....................................................
0x00,0x00,0x00,0x00,0x00,0x06,0x0C,0x00,0x81,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, // .............................................##.....##..........#......###......................................................
0x00,0x00,0x00,0x00,0x00,0x0C,0x06,0x00,0x80,0xE3,0x00,0x00,0x00,0x00,0x00,0x00, // ............................................##.......##.........#.......###...##................................................
0x00,0x00,0x00,0x00,0x00,0x18,0x06,0x00,0x80,0x6F,0x80,0x00,0x00,0x00,0x00,0x00, // ...........................................##........##.........#........##.#####...............................................
0x00,0x00,0x00,0x00,0x1C,0x38,0x02,0x00,0x80,0x3C,0xC0,0x00,0x00,0x00,0x00,0x00, // ...................................###....###.........#.........#.........####..##..............................................
0x00,0x00,0x00,0x00,0x1F,0x30,0x03,0x00,0xC0,0x3C,0x60,0x00,0x00,0x00,0x00,0x00, // ...................................#####..##..........##........##........####...##.............................................
0x00,0x00,0x00,0x00,0x77,0xB0,0x02,0xFF,0x60,0x3C,0x30,0x00,0x00,0x00,0x00,0x00, // .................................###.####.##..........#.########.##.......####....##............................................
0x00,0x00,0x00,0x00,0xE0,0xF8,0x06,0xFF,0xB0,0x3C,0x18,0x00,0x00,0x00,0x00,0x00, // ................................###.....#####........##.#########.##......####.....##...........................................
0x00,0x00,0x00,0x00,0xC0,0xD8,0x0D,0x81,0x98,0x1C,0x08,0x00,0x00,0x00,0x00,0x00, // ................................##......##.##.......##.##......##..##......###......#...........................................
0x00,0x00,0x00,0x03,0x80,0xD8,0x09,0x80,0xDC,0xFC,0x08,0x00,0x00,0x00,0x00,0x00, // ..............................###.......##.##.......#..##.......##.###..######......#...........................................
0x00,0x00,0x00,0x02,0x00,0xD8,0x1B,0x00,0x6F,0xE4,0x0C,0x00,0x00,0x00,0x00,0x00, // ..............................#.........##.##......##.##.........##.#######..#......##..........................................
0x00,0x00,0x00,0x02,0x00,0xDF,0xFB,0x00,0x37,0x06,0x0C,0x00,0x00,0x00,0x00,0x00, // ..............................#.........##.##########.##..........##.###.....##.....##..........................................
0x00,0x00,0x00,0x06,0x00,0xE7,0xF6,0x00,0x18,0x03,0x04,0x00,0x00,0x00,0x00,0x00, // .............................##.........###..#######.##............##.........##.....#..........................................
0x00,0x00,0x00,0x06,0x00,0xE0,0x0E,0x00,0x18,0x0F,0x04,0x00,0x00,0x00,0x00,0x00, // .............................##.........###.........###............##.......####.....#..........................................
0x00,0x00,0x00,0x06,0x00,0xC0,0x2E,0x00,0x1B,0xFF,0xC6,0x00,0x00,0x00,0x00,0x00, // .............................##.........##........#.###............##.############...##.........................................
0x3F,0xFC,0x1F,0xF6,0x7D,0x81,0xE6,0x00,0x1B,0xC7,0xC6,0x00,0x00,0x00,0x00,0x00, // ..############.....#########.##..#####.##......####..##............##.####...#####...##.........................................
0x7F,0xFE,0x3F,0xFF,0x1F,0x8F,0xC3,0xFF,0xFF,0xFF,0xFC,0x1F,0xFF,0x38,0x03,0xC0, // .##############...##############...######...######....################################.....#############..###.........####......
0xFF,0xFF,0xFF,0xFF,0x8F,0x1F,0xC7,0xFF,0xFF,0xFF,0xF8,0xFF,0xFF,0x3C,0x03,0xE0, // #################################...####...#######...################################...################..####........#####.....
0x10,0x0F,0xF0,0x0F,0x8F,0xFF,0x83,0xFF,0xF7,0xFF,0xF8,0xFF,0xFC,0x3C,0x03,0xE0, // ...#........########........#####...#############.....##############.################...##############....####........#####.....
0x00,0x0F,0xF0,0x07,0xFF,0xFF,0x01,0x9E,0x27,0xFC,0xC2,0xF8,0x00,0x3E,0x03,0xE0, // ............########.........###################.......##..####...#..#########..##....#.#####.............#####.......#####.....
0x0F,0xFF,0xF0,0x03,0xDF,0xFE,0x01,0xCE,0x6C,0xFC,0x47,0xF8,0x00,0x3F,0xFF,0xE0, // ....################..........####.############........###..###..##.##..######...#...########.............#################.....
0x1F,0xFF,0xF0,0x03,0xC3,0xFC,0x00,0xFF,0xCC,0xFF,0xFF,0xF0,0x00,0x3F,0xFF,0xE0, // ...#################..........####....########..........##########..##..####################..............#################.....
0x1F,0xFF,0xF0,0x03,0xC3,0xFC,0x00,0x0E,0x1C,0xFF,0xF9,0xE0,0x00,0x3F,0xFF,0xE0, // ...#################..........####....########..............###....###..#############..####...............#################.....
0x00,0x0F,0xF0,0x0F,0xC7,0xFC,0x00,0x0E,0x1C,0xFF,0xF1,0xE0,0x00,0x3F,0xFF,0xE0, // ............########........######...#########..............###....###..############...####...............#################.....
0x00,0x0F,0xF8,0x0F,0x87,0xFE,0x00,0x0E,0x0C,0xF8,0xF0,0xF0,0x00,0x3C,0x03,0xE0, // ............#########.......#####....##########.............###.....##..#####...####....####..............####........#####.....
0x7F,0xFF,0xFF,0xFF,0xBF,0x8F,0x00,0x3F,0xE6,0xF8,0xE0,0xFC,0x00,0x3C,0x03,0xE0, // .################################.#######...####..........#########..##.#####...###.....######............####........#####.....
0x7F,0xFF,0xFF,0xFF,0xFF,0x07,0xC0,0xFF,0xE7,0xFF,0xFC,0xFF,0xFF,0x3C,0x03,0xE0, // .#######################################.....#####......###########..#################..################..####........#####.....
0xFF,0xFF,0xFF,0xFF,0xFE,0x03,0xE0,0x8E,0x33,0xFF,0xFC,0x1F,0xFF,0x3C,0x03,0xE0, // #######################################.......#####.....#...###...##..################.....#############..####........#####.....
0x7F,0xFC,0x3F,0xF0,0x3C,0x01,0xF1,0x9E,0x31,0xFF,0xF9,0x0F,0xFE,0x3C,0x03,0xC0, // .#############....##########......####.........#####...##..####...##...##############..#....###########...####........####......
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x19,0xFF,0xC1,0x00,0x00,0x00,0x00,0x00, // ......................................................##...........##..###########.....#........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0xE0,0xC1,0x00,0x00,0x00,0x00,0x00, // ......................................................##............##..###.....##.....#........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0C,0x00,0x42,0x00,0x00,0x00,0x00,0x00, // .....................................................##.............##...........#....#.........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x01,0x62,0x00,0x00,0x00,0x00,0x00, // .....................................................##..............##........#.##...#.........................................
0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x06,0x3F,0x62,0x00,0x00,0x00,0x00,0x00, // ....................................................##...............##...######.##...#.........................................
0x00,0x00,0x00,0x00,0x00,0x38,0x0E,0x00,0x0D,0xFD,0xEE,0x00,0x00,0x00,0x00,0x00, // ..........................................###.......###.............##.#######.####.###.........................................
0x00,0x00,0x00,0x00,0x00,0x7F,0xE6,0x00,0x19,0x81,0xFC,0x00,0x00,0x00,0x00,0x00, // .........................................##########..##............##..##......#######..........................................
0x00,0x00,0x00,0x00,0x00,0xEF,0xF7,0x00,0x1B,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, // ........................................###.########.###...........##.##.......#####............................................
0x00,0x00,0x00,0x00,0x00,0xC0,0x33,0x00,0x33,0x01,0xC8,0x00,0x00,0x00,0x00,0x00, // ........................................##........##..##..........##..##.......###..#...........................................
0x00,0x00,0x00,0x00,0x00,0x80,0x1B,0x00,0x36,0x01,0x98,0x00,0x00,0x00,0x00,0x00, // ........................................#..........##.##..........##.##........##..##...........................................
0x00,0x00,0x00,0x00,0x01,0x80,0x0D,0xFF,0xEC,0x01,0xF0,0x00,0x00,0x00,0x00,0x00, // .......................................##...........##.############.##.........#####............................................
0x00,0x00,0x00,0x00,0x01,0x00,0x0E,0xFF,0xD8,0x01,0xE0,0x00,0x00,0x00,0x00,0x00, // .......................................#............###.##########.##..........####.............................................
0x00,0x00,0x00,0x01,0xF1,0x80,0x06,0x60,0x38,0x07,0xA0,0x00,0x00,0x00,0x00,0x00, // ...............................#####...##............##..##.......###........####.#.............................................
0x00,0x00,0x00,0x01,0xFD,0x80,0x03,0x00,0x18,0x05,0x40,0x00,0x00,0x00,0x00,0x00, // ...............................#######.##.............##...........##........#.#.#..............................................
0x00,0x00,0x00,0x01,0x8F,0xC0,0x06,0xFF,0xDC,0x0A,0x80,0x00,0x00,0x00,0x00,0x00, // ...............................##...######...........##.##########.###......#.#.#...............................................
0x00,0x00,0x00,0x00,0x81,0xE0,0x0C,0xFF,0xCC,0x1F,0x00,0x00,0x00,0x00,0x00,0x00, // ................................#......####.........##..##########..##.....#####................................................
0x00,0x00,0x00,0x00,0x81,0xF0,0x0D,0x80,0x6C,0xFE,0x00,0x00,0x00,0x00,0x00,0x00, // ................................#......#####........##.##........##.##..#######.................................................
0x00,0x00,0x00,0x00,0x40,0xFE,0x1B,0x00,0x67,0x8C,0x00,0x00,0x00,0x00,0x00,0x00, // .................................#......#######....##.##.........##..####...##..................................................
0x00,0x00,0x00,0x00,0x20,0x7F,0xF6,0x00,0x20,0x18,0x00,0x00,0x00,0x00,0x00,0x00, // ..................................#......###########.##...........#........##...................................................
0x00,0x00,0x00,0x00,0x10,0x30,0x6E,0x00,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, // ...................................#......##.....##.###...........##########....................................................
0x00,0x00,0x00,0x00,0x04,0x30,0x0E,0x00,0xFF,0xA0,0x00,0x00,0x00,0x00,0x00,0x00, // .....................................#....##........###.........#########.#.....................................................
0x00,0x00,0x00,0x00,0x03,0x30,0x06,0x00,0xE1,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ......................................##..##.........##.........###....#........................................................
0x00,0x00,0x00,0x00,0x01,0xF0,0x03,0x03,0xE2,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .......................................#####..........##......#####...#.........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xFF,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // .......................................................##########...#...........................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // ..............................................................#...##............................................................
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 // .............................................................###................................................................
};
-72
View File
@@ -1,72 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (C) 2016 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (C) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
/**
* Custom Status Screen bitmap
*
* Place this file in the root with your configuration files
* and enable CUSTOM_STATUS_SCREEN_IMAGE in Configuration.h.
*
* Use the Marlin Bitmap Converter to make your own:
* http://marlinfw.org/tools/u8glib/converter.html
*/
//
// Status Screen Logo bitmap
//
#define STATUS_LOGO_Y 1
#define STATUS_LOGO_WIDTH 32
const unsigned char status_logo_bmp[] PROGMEM = {
0x00,0x00,0x00,0x00, // ................................
0x00,0x00,0x00,0x00, // ................................
0x00,0x00,0x00,0x00, // ................................
0x00,0x00,0x10,0x00, // ...................#............
0x00,0x00,0x06,0x00, // .....................##.........
0x00,0x00,0x00,0x00, // ................................
0x01,0x00,0x00,0x00, // .......#........................
0x08,0x00,0x01,0x00, // ....#..................#........
0x01,0x00,0x41,0x00, // .......#.........#.....#........
0x01,0x00,0x02,0x00, // .......#..............#.........
0x00,0xE0,0x00,0x00, // ........###.....................
0x80,0x08,0x10,0x80, // #...........#......#....#.......
0x04,0x00,0x00,0x40, // .....#...................#......
0x08,0x00,0x08,0x00, // ....#...............#...........
0x10,0x04,0x00,0x00, // ...#.........#..................
0x00,0x00,0x00,0x30, // ..........................##....
0x00,0x00,0x00,0x20, // ..........................#.....
0x00,0x01,0xE8,0x20, // ...............####.#.....#.....
0x00,0x00,0x00,0x60, // .........................##.....
0x00,0x00,0x02,0x00, // ......................#.........
0x00,0x08,0x00,0x00, // ............#...................
0x00,0x00,0x01,0x20, // .......................#..#.....
0x02,0xE8,0x10,0x60, // ......#.###.#......#.....##.....
0x00,0x00,0x00,0x40, // .........................#......
0x00,0x03,0xC0,0x60, // ..............####.......##.....
0x64,0x00,0x10,0x00, // .##..#.............#............
0x04,0x03,0xC0,0x00, // .....#........####..............
0x02,0x00,0x20,0x00, // ......#...........#.............
0x00,0x28,0x00,0x00, // ..........#.#...................
0x00,0x08,0x20,0x00, // ............#.....#.............
0x00,0x00,0x40,0x00, // .................#..............
0x00,0x00,0x00,0x00 // ................................
};
+1 -1
View File
@@ -25,7 +25,7 @@
#include "HAL.h"
#ifdef USBCON
DefaultSerial1 MSerial0(false, Serial);
DefaultSerial MSerial(false, Serial);
#ifdef BLUETOOTH
BTSerial btSerial(false, bluetoothSerial);
#endif
+7 -7
View File
@@ -83,25 +83,25 @@ typedef int8_t pin_t;
// Serial ports
#ifdef USBCON
#include "../../core/serial_hook.h"
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
extern DefaultSerial1 MSerial0;
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
#ifdef BLUETOOTH
typedef ForwardSerial1Class< decltype(bluetoothSerial) > BTSerial;
typedef ForwardSerial0Type< decltype(bluetoothSerial) > BTSerial;
extern BTSerial btSerial;
#endif
#define MYSERIAL1 TERN(BLUETOOTH, btSerial, MSerial0)
#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."
#endif
#define MYSERIAL1 customizedSerial1
#define MYSERIAL0 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
#define MYSERIAL2 customizedSerial2
#define MYSERIAL1 customizedSerial2
#endif
#endif
@@ -117,7 +117,7 @@ typedef int8_t pin_t;
#error "LCD_SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#define LCD_SERIAL lcdSerial
#if HAS_DGUS_LCD
#if HAS_DGUS_LCD || ENABLED(DGUS_LCD_UI_CREALITY_TOUCH)
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free()
#endif
#endif
+2 -2
View File
@@ -566,7 +566,7 @@ ISR(SERIAL_REGNAME(USART, SERIAL_PORT, _UDRE_vect)) {
MarlinSerial<MarlinSerialCfg<SERIAL_PORT>>::_tx_udr_empty_irq();
}
// Because of the template definition above, it's required to instantiate the template to have all methods generated
// 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);
@@ -612,7 +612,7 @@ MSerialT customizedSerial1(MSerialT::HasEmergencyParser);
template class MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> >;
MSerialT4 lcdSerial(MSerialT4::HasEmergencyParser);
#if HAS_DGUS_LCD
#if HAS_DGUS_LCD || ENABLED(DGUS_LCD_UI_CREALITY_TOUCH)
template<typename Cfg>
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
+28 -17
View File
@@ -212,7 +212,7 @@
static ring_buffer_pos_t available();
static size_t write(const uint8_t c);
static void flushTX();
#if HAS_DGUS_LCD
#if HAS_DGUS_LCD || ENABLED(DGUS_LCD_UI_CREALITY_TOUCH)
static ring_buffer_pos_t get_tx_buffer_free();
#endif
@@ -238,11 +238,11 @@
static constexpr bool MAX_RX_QUEUED = ENABLED(SERIAL_STATS_MAX_RX_QUEUED);
};
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
extern MSerialT customizedSerial1;
#ifdef SERIAL_PORT_2
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
extern MSerialT2 customizedSerial2;
#endif
@@ -252,17 +252,17 @@
template <uint8_t serial>
struct MMU2SerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = 32;
static constexpr unsigned int TX_SIZE = 32;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = false;
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
static constexpr unsigned int RX_SIZE = 32;
static constexpr unsigned int TX_SIZE = 32;
static constexpr bool RX_OVERRUNS = false;
};
typedef Serial1Class< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialT3;
typedef Serial0Type< MarlinSerial< MMU2SerialCfg<MMU2_SERIAL_PORT> > > MSerialT3;
extern MSerialT3 mmuSerial;
#endif
@@ -270,23 +270,34 @@
template <uint8_t serial>
struct LCDSerialCfg {
static constexpr int PORT = serial;
static constexpr unsigned int RX_SIZE = TERN(HAS_DGUS_LCD, DGUS_RX_BUFFER_SIZE, 64);
static constexpr unsigned int TX_SIZE = TERN(HAS_DGUS_LCD, DGUS_TX_BUFFER_SIZE, 128);
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
static constexpr bool RX_OVERRUNS = BOTH(HAS_DGUS_LCD, SERIAL_STATS_RX_BUFFER_OVERRUNS);
static constexpr int PORT = serial;
static constexpr bool XONOFF = false;
static constexpr bool EMERGENCYPARSER = ENABLED(EMERGENCY_PARSER);
static constexpr bool DROPPED_RX = false;
static constexpr bool RX_FRAMING_ERRORS = false;
static constexpr bool MAX_RX_QUEUED = false;
#if HAS_DGUS_LCD || ENABLED(DGUS_LCD_UI_CREALITY_TOUCH)
static constexpr unsigned int RX_SIZE = DGUS_RX_BUFFER_SIZE;
static constexpr unsigned int TX_SIZE = DGUS_TX_BUFFER_SIZE;
static constexpr bool RX_OVERRUNS = ENABLED(SERIAL_STATS_RX_BUFFER_OVERRUNS);
#elif EITHER(ANYCUBIC_LCD_I3MEGA, ANYCUBIC_LCD_CHIRON)
static constexpr unsigned int RX_SIZE = 64;
static constexpr unsigned int TX_SIZE = 128;
static constexpr bool RX_OVERRUNS = false;
#else
static constexpr unsigned int RX_SIZE = 64;
static constexpr unsigned int TX_SIZE = 128;
static constexpr bool RX_OVERRUNS = false
#endif
};
typedef Serial1Class< MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> > > MSerialT4;
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)
typedef Serial1Class<HardwareSerial> MSerialT5;
typedef Serial0Type<HardwareSerial> MSerialT5;
extern MSerialT5 bluetoothSerial;
#endif
+1 -1
View File
@@ -285,7 +285,7 @@ enum ClockSource2 : char {
*/
// Determine which harware PWMs are already in use
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN || P == COOLER_AUTO_FAN_PIN)
#define _PWM_CHK_FAN_B(P) (P == E0_AUTO_FAN_PIN || P == E1_AUTO_FAN_PIN || P == E2_AUTO_FAN_PIN || P == E3_AUTO_FAN_PIN || P == E4_AUTO_FAN_PIN || P == E5_AUTO_FAN_PIN || P == E6_AUTO_FAN_PIN || P == E7_AUTO_FAN_PIN || P == CHAMBER_AUTO_FAN_PIN)
#if PIN_EXISTS(CONTROLLER_FAN)
#define PWM_CHK_FAN_B(P) (_PWM_CHK_FAN_B(P) || P == CONTROLLER_FAN_PIN)
#else
-7
View File
@@ -56,10 +56,3 @@
#if BOTH(HAS_TMC_SW_SERIAL, MONITOR_DRIVER_STATUS)
#error "MONITOR_DRIVER_STATUS causes performance issues when used with SoftwareSerial-connected drivers. Disable MONITOR_DRIVER_STATUS or use hardware serial to continue."
#endif
/**
* Postmortem debugging
*/
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not supported on AVR boards."
#endif
+342
View File
@@ -0,0 +1,342 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../core/macros.h"
#include "../../core/serial.h"
#include "../shared/backtrace/unwinder.h"
#include "../shared/backtrace/unwmemaccess.h"
#include <stdarg.h>
// Debug monitor that dumps to the Programming port all status when
// an exception or WDT timeout happens - And then resets the board
// All the Monitor routines must run with interrupts disabled and
// under an ISR execution context. That is why we cannot reuse the
// Serial interrupt routines or any C runtime, as we don't know the
// state we are when running them
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
// (re)initialize UART0 as a monitor output to 250000,n,8,1
static void TXBegin() {
// Disable UART interrupt in NVIC
NVIC_DisableIRQ( UART_IRQn );
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
__DSB();
__ISB();
// Disable clock
pmc_disable_periph_clk( ID_UART );
// Configure PMC
pmc_enable_periph_clk( ID_UART );
// Disable PDC channel
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
// Reset and disable receiver and transmitter
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
// Configure mode: 8bit, No parity, 1 bit stop
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
// Enable receiver and transmitter
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
}
// Send character through UART with no interrupts
static void TX(char c) {
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
UART->UART_THR = c;
}
// Send String through UART
static void TX(const char* s) {
while (*s) TX(*s++);
}
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number thru UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number thru UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
// Dump a backtrace entry
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
int* p = (int*)ctx;
(*p)++;
TX('#'); TXDec(*p); TX(" : ");
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
TX('+'); TXDec(bte->address - bte->function);
TX(" PC:");TXHex(bte->address); TX('\n');
return true;
}
#ifdef UNW_DEBUG
void UnwPrintf(const char* format, ...) {
char dest[256];
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
}
#endif
/* Table of function pointers for passing to the unwinder */
static const UnwindCallbacks UnwCallbacks = {
UnwReportOut,
UnwReadW,
UnwReadH,
UnwReadB
#ifdef UNW_DEBUG
, UnwPrintf
#endif
};
/**
* HardFaultHandler_C:
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
extern "C"
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
static const char* causestr[] = {
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
};
UnwindFrame btf;
// Dump report to the Programming port (interrupts are DISABLED)
TXBegin();
TX("\n\n## Software Fault detected ##\n");
TX("Cause: "); TX(causestr[cause]); TX('\n');
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
// Hard Fault Status Register
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
// Debug Fault Status Register
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
// Auxiliary Fault Status Register
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
// Bus Fault Address Register
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
TX("ExcLR: "); TXHex(lr); TX('\n');
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
btf.fp = btf.sp;
btf.lr = ((unsigned long)sp[5]);
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
TX("\nBacktrace:\n\n");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
// Disable all NVIC interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
// Relocate VTOR table to default position
SCB->VTOR = 0;
// Disable USB
otg_disable();
// Restart watchdog
WDT_Restart(WDT);
// Reset controller
NVIC_SystemReset();
for (;;) WDT_Restart(WDT);
}
__attribute__((naked)) void NMI_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#0")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void HardFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#1")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void MemManage_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#2")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void BusFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#3")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void UsageFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#4")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void DebugMon_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#5")
A("b HardFault_HandlerC")
);
}
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
__attribute__((naked)) void WDT_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#6")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void RSTC_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#7")
A("b HardFault_HandlerC")
);
}
#endif // ARDUINO_ARCH_SAM
+6 -16
View File
@@ -40,8 +40,6 @@ uint16_t HAL_adc_result;
// Public functions
// ------------------------
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
// HAL initialization task
void HAL_init() {
// Initialize the USB stack
@@ -49,7 +47,6 @@ void HAL_init() {
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
usb_task_init();
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
// HAL idle task
@@ -105,18 +102,11 @@ uint16_t HAL_adc_get_result() {
return HAL_adc_result;
}
// Forward the default serial ports
#if ANY_SERIAL_IS(0)
DefaultSerial1 MSerial0(false, Serial);
#endif
#if ANY_SERIAL_IS(1)
DefaultSerial2 MSerial1(false, Serial1);
#endif
#if ANY_SERIAL_IS(2)
DefaultSerial3 MSerial2(false, Serial2);
#endif
#if ANY_SERIAL_IS(3)
DefaultSerial4 MSerial3(false, Serial3);
#endif
// 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
+14 -13
View File
@@ -37,33 +37,34 @@
#include <stdint.h>
#include "../../core/serial_hook.h"
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
extern DefaultSerial1 MSerial0;
extern DefaultSerial2 MSerial1;
extern DefaultSerial3 MSerial2;
extern DefaultSerial4 MSerial3;
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 MSerial0 MSerial
// Define MYSERIAL1/2 before MarlinSerial includes!
// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL1 customizedSerial1
#define MYSERIAL0 customizedSerial1
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1 || ENABLED(EMERGENCY_PARSER)
#define MYSERIAL2 customizedSerial2
#define MYSERIAL1 customizedSerial2
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
-91
View File
@@ -1,91 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef ARDUINO_ARCH_SAM
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include <stdarg.h>
static void TXBegin() {
// Disable UART interrupt in NVIC
NVIC_DisableIRQ( UART_IRQn );
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
__DSB();
__ISB();
// Disable clock
pmc_disable_periph_clk( ID_UART );
// Configure PMC
pmc_enable_periph_clk( ID_UART );
// Disable PDC channel
UART->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS;
// Reset and disable receiver and transmitter
UART->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX | UART_CR_RXDIS | UART_CR_TXDIS;
// Configure mode: 8bit, No parity, 1 bit stop
UART->UART_MR = UART_MR_CHMODE_NORMAL | US_MR_CHRL_8_BIT | US_MR_NBSTOP_1_BIT | UART_MR_PAR_NO;
// Configure baudrate (asynchronous, no oversampling) to BAUDRATE bauds
UART->UART_BRGR = (SystemCoreClock / (BAUDRATE << 4));
// Enable receiver and transmitter
UART->UART_CR = UART_CR_RXEN | UART_CR_TXEN;
}
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
static void TX(char c) {
while (!(UART->UART_SR & UART_SR_TXRDY)) { WDT_Restart(WDT); sw_barrier(); };
UART->UART_THR = c;
}
void install_min_serial() {
HAL_min_serial_init = &TXBegin;
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE)
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // ARDUINO_ARCH_SAM
+2 -2
View File
@@ -141,11 +141,11 @@ struct MarlinSerialCfg {
};
#if SERIAL_PORT >= 0
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT> > > MSerialT;
extern MSerialT customizedSerial1;
#endif
#if defined(SERIAL_PORT_2) && SERIAL_PORT_2 >= 0
typedef Serial1Class< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
typedef Serial0Type< MarlinSerial< MarlinSerialCfg<SERIAL_PORT_2> > > MSerialT2;
extern MSerialT2 customizedSerial2;
#endif
+6 -5
View File
@@ -92,11 +92,12 @@ int MarlinSerialUSB::read() {
return c;
}
int MarlinSerialUSB::available() {
if (pending_char > 0) return pending_char;
return pending_char == 0 ||
// or USB CDC enumerated and configured on the PC side and some bytes where sent to us */
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
bool MarlinSerialUSB::available() {
/* If Pending chars */
return pending_char >= 0 ||
/* or USB CDC enumerated and configured on the PC side and some
bytes where sent to us */
(usb_task_cdc_isenabled() && udi_cdc_is_rx_ready());
}
void MarlinSerialUSB::flush() { }
+2 -2
View File
@@ -39,7 +39,7 @@ struct MarlinSerialUSB {
int peek();
int read();
void flush();
int available();
bool available();
size_t write(const uint8_t c);
#if ENABLED(SERIAL_STATS_DROPPED_RX)
@@ -50,7 +50,7 @@ struct MarlinSerialUSB {
FORCE_INLINE int rxMaxEnqueued() { return 0; }
#endif
};
typedef Serial1Class<MarlinSerialUSB> MSerialT;
typedef Serial0Type<MarlinSerialUSB> MSerialT;
#if SERIAL_PORT == -1
extern MSerialT customizedSerial1;
+1 -1
View File
@@ -57,5 +57,5 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on the DUE platform."
#error "TMC220x Software Serial is not supported on this platform."
#endif
@@ -20,10 +20,11 @@
*
*/
#ifdef ARDUINO_ARCH_ESP32
#include "FlushableHardwareSerial.h"
Serial1Class<FlushableHardwareSerial> flushableSerial(false, 0);
#ifdef ARDUINO_ARCH_ESP32
#endif
Serial0Type<FlushableHardwareSerial> flushableSerial(false, 0);
#endif // ARDUINO_ARCH_ESP32
@@ -21,9 +21,9 @@
*/
#pragma once
#include <HardwareSerial.h>
#ifdef ARDUINO_ARCH_ESP32
#include "../shared/Marduino.h"
#include <HardwareSerial.h>
#include "../../core/serial_hook.h"
class FlushableHardwareSerial : public HardwareSerial {
@@ -31,4 +31,6 @@ public:
FlushableHardwareSerial(int uart_nr) : HardwareSerial(uart_nr) {}
};
extern Serial1Class<FlushableHardwareSerial> flushableSerial;
extern Serial0Type<FlushableHardwareSerial> flushableSerial;
#endif // ARDUINO_ARCH_ESP32
+1 -2
View File
@@ -41,7 +41,7 @@
#endif
#if ENABLED(ESP3D_WIFISUPPORT)
DefaultSerial1 MSerial0(false, Serial2Socket);
DefaultSerial MSerial(false, Serial2Socket);
#endif
// ------------------------
@@ -185,7 +185,6 @@ void HAL_adc_init() {
TERN_(HAS_TEMP_ADC_7, adc3_set_attenuation(get_channel(TEMP_7_PIN), ADC_ATTEN_11db));
TERN_(HAS_HEATED_BED, adc1_set_attenuation(get_channel(TEMP_BED_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_CHAMBER, adc1_set_attenuation(get_channel(TEMP_CHAMBER_PIN), ADC_ATTEN_11db));
TERN_(HAS_TEMP_COOLER, adc1_set_attenuation(get_channel(TEMP_COOLER_PIN), ADC_ATTEN_11db));
TERN_(FILAMENT_WIDTH_SENSOR, adc1_set_attenuation(get_channel(FILWIDTH_PIN), ADC_ATTEN_11db));
// Note that adc2 is shared with the WiFi module, which has higher priority, so the conversion may fail.
+5 -5
View File
@@ -51,15 +51,15 @@
extern portMUX_TYPE spinlock;
#define MYSERIAL1 flushableSerial
#define MYSERIAL0 flushableSerial
#if EITHER(WIFISUPPORT, ESP3D_WIFISUPPORT)
#if ENABLED(ESP3D_WIFISUPPORT)
typedef ForwardSerial1Class< decltype(Serial2Socket) > DefaultSerial1;
extern DefaultSerial1 MSerial0;
#define MYSERIAL2 MSerial0
typedef ForwardSerial0Type< decltype(Serial2Socket) > DefaultSerial;
extern DefaultSerial MSerial;
#define MYSERIAL1 MSerial
#else
#define MYSERIAL2 webSocketSerial
#define MYSERIAL1 webSocketSerial
#endif
#endif
+1 -1
View File
@@ -81,5 +81,5 @@ public:
#endif
};
typedef Serial1Class<WebSocketSerial> MSerialT;
typedef Serial0Type<WebSocketSerial> MSerialT;
extern MSerialT webSocketSerial;
+1 -5
View File
@@ -30,13 +30,9 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on ESP32."
#error "TMC220x Software Serial is not supported on this platform."
#endif
#if BOTH(WIFISUPPORT, ESP3D_WIFISUPPORT)
#error "Only enable one WiFi option, either WIFISUPPORT or ESP3D_WIFISUPPORT."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on ESP32."
#endif
+6
View File
@@ -29,6 +29,12 @@
#include HAL_PATH(.,HAL.h)
#ifdef SERIAL_PORT_2
#define NUM_SERIAL 2
#else
#define NUM_SERIAL 1
#endif
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
#ifndef I2C_ADDRESS
+1 -1
View File
@@ -61,7 +61,7 @@ uint8_t _getc();
#define SHARED_SERVOS HAS_SERVOS
extern MSerialT usb_serial;
#define MYSERIAL1 usb_serial
#define MYSERIAL0 usb_serial
#define ST7920_DELAY_1 DELAY_NS(600)
#define ST7920_DELAY_2 DELAY_NS(750)
+1 -5
View File
@@ -35,9 +35,5 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on LINUX."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on LINUX."
#error "TMC220x Software Serial is not supported on this platform."
#endif
+1 -1
View File
@@ -115,4 +115,4 @@ struct HalSerial {
volatile bool host_connected;
};
typedef Serial1Class<HalSerial> MSerialT;
typedef Serial0Type<HalSerial> MSerialT;
+2 -2
View File
@@ -105,8 +105,8 @@ int main() {
std::thread write_serial (write_serial_thread);
std::thread read_serial (read_serial_thread);
#ifdef MYSERIAL1
MYSERIAL1.begin(BAUDRATE);
#ifdef MYSERIAL0
MYSERIAL0.begin(BAUDRATE);
SERIAL_ECHOLNPGM("x86_64 Initialized");
SERIAL_FLUSHTX();
#endif
+322
View File
@@ -0,0 +1,322 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "../../core/macros.h"
#include "../../core/serial.h"
#include <stdarg.h>
#include "../shared/backtrace/unwinder.h"
#include "../shared/backtrace/unwmemaccess.h"
#include "watchdog.h"
#include <debug_frmwrk.h>
// Debug monitor that dumps to the Programming port all status when
// an exception or WDT timeout happens - And then resets the board
// All the Monitor routines must run with interrupts disabled and
// under an ISR execution context. That is why we cannot reuse the
// Serial interrupt routines or any C runtime, as we don't know the
// state we are when running them
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
// (re)initialize UART0 as a monitor output to 250000,n,8,1
static void TXBegin() {
}
// Send character through UART with no interrupts
static void TX(char c) {
_DBC(c);
}
// Send String through UART
static void TX(const char* s) {
while (*s) TX(*s++);
}
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number thru UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number thru UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
// Dump a backtrace entry
static bool UnwReportOut(void* ctx, const UnwReport* bte) {
int* p = (int*)ctx;
(*p)++;
TX('#'); TXDec(*p); TX(" : ");
TX(bte->name?bte->name:"unknown"); TX('@'); TXHex(bte->function);
TX('+'); TXDec(bte->address - bte->function);
TX(" PC:");TXHex(bte->address); TX('\n');
return true;
}
#ifdef UNW_DEBUG
void UnwPrintf(const char* format, ...) {
char dest[256];
va_list argptr;
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
TX(&dest[0]);
}
#endif
/* Table of function pointers for passing to the unwinder */
static const UnwindCallbacks UnwCallbacks = {
UnwReportOut,
UnwReadW,
UnwReadH,
UnwReadB
#ifdef UNW_DEBUG
,UnwPrintf
#endif
};
/**
* HardFaultHandler_C:
* This is called from the HardFault_HandlerAsm with a pointer the Fault stack
* as the parameter. We can then read the values from the stack and place them
* into local variables for ease of reading.
* We then read the various Fault Status and Address Registers to help decode
* cause of the fault.
* The function ends with a BKPT instruction to force control back into the debugger
*/
extern "C"
void HardFault_HandlerC(unsigned long *sp, unsigned long lr, unsigned long cause) {
static const char* causestr[] = {
"NMI","Hard","Mem","Bus","Usage","Debug","WDT","RSTC"
};
UnwindFrame btf;
// Dump report to the Programming port (interrupts are DISABLED)
TXBegin();
TX("\n\n## Software Fault detected ##\n");
TX("Cause: "); TX(causestr[cause]); TX('\n');
TX("R0 : "); TXHex(((unsigned long)sp[0])); TX('\n');
TX("R1 : "); TXHex(((unsigned long)sp[1])); TX('\n');
TX("R2 : "); TXHex(((unsigned long)sp[2])); TX('\n');
TX("R3 : "); TXHex(((unsigned long)sp[3])); TX('\n');
TX("R12 : "); TXHex(((unsigned long)sp[4])); TX('\n');
TX("LR : "); TXHex(((unsigned long)sp[5])); TX('\n');
TX("PC : "); TXHex(((unsigned long)sp[6])); TX('\n');
TX("PSR : "); TXHex(((unsigned long)sp[7])); TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
TX("CFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED28)))); TX('\n');
// Hard Fault Status Register
TX("HFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED2C)))); TX('\n');
// Debug Fault Status Register
TX("DFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED30)))); TX('\n');
// Auxiliary Fault Status Register
TX("AFSR : "); TXHex((*((volatile unsigned long *)(0xE000ED3C)))); TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
TX("MMAR : "); TXHex((*((volatile unsigned long *)(0xE000ED34)))); TX('\n');
// Bus Fault Address Register
TX("BFAR : "); TXHex((*((volatile unsigned long *)(0xE000ED38)))); TX('\n');
TX("ExcLR: "); TXHex(lr); TX('\n');
TX("ExcSP: "); TXHex((unsigned long)sp); TX('\n');
btf.sp = ((unsigned long)sp) + 8*4; // The original stack pointer
btf.fp = btf.sp;
btf.lr = ((unsigned long)sp[5]);
btf.pc = ((unsigned long)sp[6]) | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
TX("\nBacktrace:\n\n");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
// Disable all NVIC interrupts
NVIC->ICER[0] = 0xFFFFFFFF;
NVIC->ICER[1] = 0xFFFFFFFF;
// Relocate VTOR table to default position
SCB->VTOR = 0;
// Clear cause of reset to prevent entering smoothie bootstrap
HAL_clear_reset_source();
// Restart watchdog
#if ENABLED(USE_WATCHDOG)
//WDT_Restart(WDT);
watchdog_init();
#endif
// Reset controller
NVIC_SystemReset();
// Nothing below here is compiled because NVIC_SystemReset loops forever
for (;;) { TERN_(USE_WATCHDOG, watchdog_init()); }
}
extern "C" {
__attribute__((naked)) void NMI_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#0")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void HardFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#1")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void MemManage_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#2")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void BusFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#3")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void UsageFault_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#4")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void DebugMon_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#5")
A("b HardFault_HandlerC")
);
}
/* This is NOT an exception, it is an interrupt handler - Nevertheless, the framing is the same */
__attribute__((naked)) void WDT_IRQHandler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#6")
A("b HardFault_HandlerC")
);
}
__attribute__((naked)) void RSTC_Handler() {
__asm__ __volatile__ (
".syntax unified" "\n\t"
A("tst lr, #4")
A("ite eq")
A("mrseq r0, msp")
A("mrsne r0, psp")
A("mov r1,lr")
A("mov r2,#7")
A("b HardFault_HandlerC")
);
}
}
#endif // TARGET_LPC1768
+1 -1
View File
@@ -29,7 +29,7 @@
#include "watchdog.h"
#endif
DefaultSerial1 USBSerial(false, UsbSerial);
DefaultSerial USBSerial(false, UsbSerial);
uint32_t HAL_adc_reading = 0;
+7 -6
View File
@@ -60,25 +60,26 @@ extern "C" volatile uint32_t _millis;
#define ST7920_DELAY_3 DELAY_NS(750)
#endif
typedef ForwardSerial1Class< decltype(UsbSerial) > DefaultSerial1;
extern DefaultSerial1 USBSerial;
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 MYSERIAL1 USBSerial
#define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 USBSerial
#define MYSERIAL1 USBSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
-50
View File
@@ -1,50 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef TARGET_LPC1768
#include "HAL.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include <debug_frmwrk.h>
static void TX(char c) { _DBC(c); }
void install_min_serial() { HAL_min_serial_out = &TX; }
#if DISABLED(DYNAMIC_VECTORTABLE)
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // TARGET_LPC1768
+8 -34
View File
@@ -25,46 +25,20 @@
#include "MarlinSerial.h"
#if ANY_SERIAL_IS(0)
MarlinSerial _MSerial(LPC_UART0);
MSerialT MSerial0(true, _MSerial);
extern "C" void UART0_IRQHandler() { _MSerial.IRQHandler(); }
MSerialT MSerial(true, LPC_UART0);
extern "C" void UART0_IRQHandler() { MSerial.IRQHandler(); }
#endif
#if ANY_SERIAL_IS(1)
MarlinSerial _MSerial1((LPC_UART_TypeDef *) LPC_UART1);
MSerialT MSerial1(true, _MSerial1);
extern "C" void UART1_IRQHandler() { _MSerial1.IRQHandler(); }
MSerialT MSerial1(true, (LPC_UART_TypeDef *) LPC_UART1);
extern "C" void UART1_IRQHandler() { MSerial1.IRQHandler(); }
#endif
#if ANY_SERIAL_IS(2)
MarlinSerial _MSerial2(LPC_UART2);
MSerialT MSerial2(true, _MSerial2);
extern "C" void UART2_IRQHandler() { _MSerial2.IRQHandler(); }
MSerialT MSerial2(true, LPC_UART2);
extern "C" void UART2_IRQHandler() { MSerial2.IRQHandler(); }
#endif
#if ANY_SERIAL_IS(3)
MarlinSerial _MSerial3(LPC_UART3);
MSerialT MSerial3(true, _MSerial3);
extern "C" void UART3_IRQHandler() { _MSerial3.IRQHandler(); }
#endif
#if ENABLED(EMERGENCY_PARSER)
bool MarlinSerial::recv_callback(const char c) {
// Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro)
if (false) {}
#if ANY_SERIAL_IS(0)
else if (this == &_MSerial) emergency_parser.update(MSerial0.emergency_state, c);
#endif
#if ANY_SERIAL_IS(1)
else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c);
#endif
#if ANY_SERIAL_IS(2)
else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c);
#endif
#if ANY_SERIAL_IS(3)
else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c);
#endif
return true;
}
MSerialT MSerial3(true, LPC_UART3);
extern "C" void UART3_IRQHandler() { MSerial3.IRQHandler(); }
#endif
#endif // TARGET_LPC1768
+6 -12
View File
@@ -47,21 +47,15 @@ public:
void end() {}
#if ENABLED(EMERGENCY_PARSER)
bool recv_callback(const char c) override;
bool recv_callback(const char c) override {
emergency_parser.update(static_cast<Serial0Type<MarlinSerial> *>(this)->emergency_state, c);
return true; // do not discard character
}
#endif
};
// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads
// of 'available' and 'read' method are not used in this multiple inheritance scenario.
// Instead, use a ForwardSerial here that adapts the interface.
typedef ForwardSerial1Class<MarlinSerial> MSerialT;
extern MSerialT MSerial0;
typedef Serial0Type<MarlinSerial> MSerialT;
extern MSerialT MSerial;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
// Consequently, we can't use a RuntimeSerial either. The workaround would be to use a RuntimeSerial<ForwardSerial<MarlinSerial>> type here
// Right now, let's ignore this until it's actually required.
#if ENABLED(SERIAL_RUNTIME_HOOK)
#error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x."
#endif
+4 -3
View File
@@ -83,13 +83,14 @@ bool PersistentStore::access_finish() {
static void debug_rw(const bool write, int &pos, const uint8_t *value, const size_t size, const FRESULT s, const size_t total=0) {
PGM_P const rw_str = write ? PSTR("write") : PSTR("read");
SERIAL_CHAR(' ');
SERIAL_ECHOPGM_P(rw_str);
serialprintPGM(rw_str);
SERIAL_ECHOLNPAIR("_data(", pos, ",", value, ",", size, ", ...)");
if (total) {
SERIAL_ECHOPGM(" f_");
SERIAL_ECHOPGM_P(rw_str);
serialprintPGM(rw_str);
SERIAL_ECHOPAIR("()=", s, "\n size=", size, "\n bytes_");
SERIAL_ECHOLNPAIR_P(write ? PSTR("written=") : PSTR("read="), total);
serialprintPGM(write ? PSTR("written=") : PSTR("read="));
SERIAL_ECHOLN(total);
}
else
SERIAL_ECHOLNPAIR(" f_lseek()=", s);
@@ -30,5 +30,6 @@
// 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
+2 -2
View File
@@ -270,7 +270,7 @@ static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported o
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on LPC176x."
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x."
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#endif
+3 -5
View File
@@ -46,8 +46,6 @@ extern "C" {
void SysTick_Callback() { disk_timerproc(); }
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
void HAL_init() {
// Init LEDs
@@ -125,7 +123,9 @@ void HAL_init() {
delay(1000); // Give OS time to notice
USB_Connect(true);
TERN_(HAS_SD_HOST_DRIVE, MSC_SD_Init(0)); // Enable USB SD card access
#if HAS_SD_HOST_DRIVE
MSC_SD_Init(0); // Enable USB SD card access
#endif
const millis_t usb_timeout = millis() + 2000;
while (!USB_Configuration && PENDING(millis(), usb_timeout)) {
@@ -137,8 +137,6 @@ void HAL_init() {
}
HAL_timer_init();
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
}
// HAL idle task
@@ -8,7 +8,9 @@ from __future__ import print_function
target_filename = "FIRMWARE.CUR"
target_drive = "REARM"
import os,getpass,platform
import os
import getpass
import platform
current_OS = platform.system()
Import("env")
@@ -31,8 +33,9 @@ try:
#
# platformio.ini will accept this for a Windows upload port designation: 'upload_port = L:'
# Windows - doesn't care about the disk's name, only cares about the drive letter
import subprocess,string
import subprocess
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
+2 -2
View File
@@ -29,8 +29,8 @@
EmergencyParser::State emergency_state;
bool CDC_RecvCallback(const char c) {
emergency_parser.update(emergency_state, c);
bool CDC_RecvCallback(const char buffer) {
emergency_parser.update(emergency_state, buffer);
return true;
}
+2 -29
View File
@@ -25,21 +25,8 @@
#include <wiring_private.h>
#ifdef ADAFRUIT_GRAND_CENTRAL_M4
#if ANY_SERIAL_IS(-1)
DefaultSerial1 MSerial0(false, Serial);
#endif
#if ANY_SERIAL_IS(0)
DefaultSerial2 MSerial1(false, Serial1);
#endif
#if ANY_SERIAL_IS(1)
DefaultSerial3 MSerial2(false, Serial2);
#endif
#if ANY_SERIAL_IS(2)
DefaultSerial4 MSerial3(false, Serial3);
#endif
#if ANY_SERIAL_IS(3)
DefaultSerial5 MSerial4(false, Serial4);
#endif
DefaultSerial MSerial(false, Serial);
DefaultSerial1 MSerial1(false, Serial1);
#endif
// ------------------------
@@ -57,7 +44,6 @@
#define GET_PROBE_ADC() TERN(HAS_TEMP_PROBE, PIN_TO_ADC(TEMP_PROBE_PIN), -1)
#define GET_BED_ADC() TERN(HAS_TEMP_ADC_BED, PIN_TO_ADC(TEMP_BED_PIN), -1)
#define GET_CHAMBER_ADC() TERN(HAS_TEMP_ADC_CHAMBER, PIN_TO_ADC(TEMP_CHAMBER_PIN), -1)
#define GET_COOLER_ADC() TERN(HAS_TEMP_ADC_COOLER, PIN_TO_ADC(TEMP_COOLER_PIN), -1)
#define GET_FILAMENT_WIDTH_ADC() TERN(FILAMENT_WIDTH_SENSOR, PIN_TO_ADC(FILWIDTH_PIN), -1)
#define GET_BUTTONS_ADC() TERN(HAS_ADC_BUTTONS, PIN_TO_ADC(ADC_KEYPAD_PIN), -1)
@@ -67,7 +53,6 @@
|| GET_PROBE_ADC() == n \
|| GET_BED_ADC() == n \
|| GET_CHAMBER_ADC() == n \
|| GET_COOLER_ADC() == n \
|| GET_FILAMENT_WIDTH_ADC() == n \
|| GET_BUTTONS_ADC() == n \
)
@@ -146,9 +131,6 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 0
TEMP_CHAMBER_PIN,
#endif
#if GET_COOLER_ADC() == 0
TEMP_COOLER_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
FILWIDTH_PIN,
#endif
@@ -189,9 +171,6 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 1
TEMP_CHAMBER_PIN,
#endif
#if GET_COOLER_ADC() == 1
TEMP_COOLER_PIN,
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
FILWIDTH_PIN,
#endif
@@ -240,9 +219,6 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_COOLER_ADC() == 0
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 0
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
@@ -292,9 +268,6 @@ uint16_t HAL_adc_result;
#if GET_CHAMBER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_CHAMBER_PIN) },
#endif
#if GET_COOLER_ADC() == 1
{ PIN_TO_INPUTCTRL(TEMP_COOLER_PIN) },
#endif
#if GET_FILAMENT_WIDTH_ADC() == 1
{ PIN_TO_INPUTCTRL(FILWIDTH_PIN) },
#endif
+11 -17
View File
@@ -32,36 +32,30 @@
#include "MarlinSerial_AGCM4.h"
// Serial ports
typedef ForwardSerial1Class< decltype(Serial) > DefaultSerial1;
typedef ForwardSerial1Class< decltype(Serial1) > DefaultSerial2;
typedef ForwardSerial1Class< decltype(Serial2) > DefaultSerial3;
typedef ForwardSerial1Class< decltype(Serial3) > DefaultSerial4;
typedef ForwardSerial1Class< decltype(Serial4) > DefaultSerial5;
extern DefaultSerial1 MSerial0;
extern DefaultSerial2 MSerial1;
extern DefaultSerial3 MSerial2;
extern DefaultSerial4 MSerial3;
extern DefaultSerial5 MSerial4;
typedef ForwardSerial0Type< decltype(Serial) > DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type< decltype(Serial1) > DefaultSerial1;
extern DefaultSerial1 MSerial1;
// MYSERIAL1 required before MarlinSerial includes!
// MYSERIAL0 required before MarlinSerial includes!
#define __MSERIAL(X) MSerial##X
#define _MSERIAL(X) __MSERIAL(X)
#define MSERIAL(X) _MSERIAL(INCREMENT(X))
#if SERIAL_PORT == -1
#define MYSERIAL1 MSerial0
#define MYSERIAL0 MSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 MSerial0
#define MYSERIAL1 MSerial
#elif WITHIN(SERIAL_PORT_2, 0, 3)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
@@ -69,7 +63,7 @@
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial0
#define MMU2_SERIAL MSerial
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
@@ -79,7 +73,7 @@
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL MSerial0
#define LCD_SERIAL MSerial
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
+1 -1
View File
@@ -22,7 +22,7 @@
#include "../../core/serial_hook.h"
typedef Serial1Class<Uart> UartT;
typedef Serial0Type<Uart> UartT;
extern UartT Serial2;
extern UartT Serial3;
-4
View File
@@ -50,7 +50,3 @@
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_FREQUENCY
#error "Features requiring Hardware PWM (FAST_PWM_FAN, SPINDLE_LASER_FREQUENCY) are not yet supported on SAMD51."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on AGCM4."
#endif
+1 -11
View File
@@ -29,7 +29,7 @@
#include "../shared/Delay.h"
#ifdef USBCON
DefaultSerial1 MSerial0(false, SerialUSB);
DefaultSerial MSerial(false, SerialUSB);
#endif
#if ENABLED(SRAM_EEPROM_EMULATION)
@@ -57,18 +57,10 @@ uint16_t HAL_adc_result;
// Public functions
// ------------------------
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
// HAL initialization task
void HAL_init() {
FastIO_init();
// Ensure F_CPU is a constant expression.
// If the compiler breaks here, it means that delay code that should compute at compile time will not work.
// So better safe than sorry here.
constexpr int cpuFreq = F_CPU;
UNUSED(cpuFreq);
#if ENABLED(SDSUPPORT) && DISABLED(SDIO_SUPPORT) && (defined(SDSS) && SDSS != -1)
OUT_WRITE(SDSS, HIGH); // Try to set SDSS inactive before any other SPI users start up
#endif
@@ -91,8 +83,6 @@ void HAL_init() {
USB_Hook_init();
#endif
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
#if HAS_SD_HOST_DRIVE
MSC_SD_init(); // Enable USB SD card access
#endif
+9 -9
View File
@@ -40,8 +40,8 @@
#ifdef USBCON
#include <USBSerial.h>
#include "../../core/serial_hook.h"
typedef ForwardSerial1Class< decltype(SerialUSB) > DefaultSerial1;
extern DefaultSerial1 MSerial0;
typedef ForwardSerial0Type< decltype(SerialUSB) > DefaultSerial;
extern DefaultSerial MSerial;
#endif
// ------------------------
@@ -51,18 +51,18 @@
#define MSERIAL(X) _MSERIAL(X)
#if SERIAL_PORT == -1
#define MYSERIAL1 MSerial0
#define MYSERIAL0 MSerial
#elif WITHIN(SERIAL_PORT, 1, 6)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 MSerial0
#define MYSERIAL1 MSerial
#elif WITHIN(SERIAL_PORT_2, 1, 6)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be -1 or from 1 to 6. Please update your configuration."
#endif
@@ -70,7 +70,7 @@
#ifdef MMU2_SERIAL_PORT
#if MMU2_SERIAL_PORT == -1
#define MMU2_SERIAL MSerial0
#define MMU2_SERIAL MSerial
#elif WITHIN(MMU2_SERIAL_PORT, 1, 6)
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
#else
@@ -80,13 +80,13 @@
#ifdef LCD_SERIAL_PORT
#if LCD_SERIAL_PORT == -1
#define LCD_SERIAL MSerial0
#define LCD_SERIAL MSerial
#elif WITHIN(LCD_SERIAL_PORT, 1, 6)
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
#else
#error "LCD_SERIAL_PORT must be -1 or from 1 to 6. Please update your configuration."
#endif
#if HAS_DGUS_LCD
#if HAS_DGUS_LCD || ENABLED(DGUS_LCD_UI_CREALITY_TOUCH)
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
#endif
#endif
-152
View File
@@ -1,152 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2017 Victor Perez
*
* 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 "../../inc/MarlinConfigPre.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include "watchdog.h"
/* Instruction Synchronization Barrier */
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
/* Data Synchronization Barrier */
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
// Dumb mapping over the registers of a USART device on STM32
struct USARTMin {
volatile uint32_t SR;
volatile uint32_t DR;
volatile uint32_t BRR;
volatile uint32_t CR1;
volatile uint32_t CR2;
};
#if WITHIN(SERIAL_PORT, 1, 6)
// Depending on the CPU, the serial port is different for USART1
static const uintptr_t regsAddr[] = {
TERN(STM32F1xx, 0x40013800, 0x40011000), // USART1
0x40004400, // USART2
0x40004800, // USART3
0x40004C00, // UART4_BASE
0x40005000, // UART5_BASE
0x40011400 // USART6
};
static USARTMin * regs = (USARTMin*)regsAddr[SERIAL_PORT - 1];
#endif
static void TXBegin() {
#if !WITHIN(SERIAL_PORT, 1, 6)
#warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error."
#warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port."
#else
// This is common between STM32F1/STM32F2 and STM32F4
const int nvicUART[] = { /* NVIC_USART1 */ 37, /* NVIC_USART2 */ 38, /* NVIC_USART3 */ 39, /* NVIC_UART4 */ 52, /* NVIC_UART5 */ 53, /* NVIC_USART6 */ 71 };
int nvicIndex = nvicUART[SERIAL_PORT - 1];
struct NVICMin {
volatile uint32_t ISER[32];
volatile uint32_t ICER[32];
};
NVICMin * nvicBase = (NVICMin*)0xE000E100;
nvicBase->ICER[nvicIndex / 32] |= _BV32(nvicIndex % 32);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
dsb();
isb();
// Example for USART1 disable: (RCC->APB2ENR &= ~(RCC_APB2ENR_USART1EN))
// Too difficult to reimplement here, let's query the STM32duino macro here
#if SERIAL_PORT == 1
__HAL_RCC_USART1_CLK_DISABLE();
__HAL_RCC_USART1_CLK_ENABLE();
#elif SERIAL_PORT == 2
__HAL_RCC_USART2_CLK_DISABLE();
__HAL_RCC_USART2_CLK_ENABLE();
#elif SERIAL_PORT == 3
__HAL_RCC_USART3_CLK_DISABLE();
__HAL_RCC_USART3_CLK_ENABLE();
#elif SERIAL_PORT == 4
__HAL_RCC_UART4_CLK_DISABLE(); // BEWARE: UART4 and not USART4 here
__HAL_RCC_UART4_CLK_ENABLE();
#elif SERIAL_PORT == 5
__HAL_RCC_UART5_CLK_DISABLE(); // BEWARE: UART5 and not USART5 here
__HAL_RCC_UART5_CLK_ENABLE();
#elif SERIAL_PORT == 6
__HAL_RCC_USART6_CLK_DISABLE();
__HAL_RCC_USART6_CLK_ENABLE();
#endif
uint32_t brr = regs->BRR;
regs->CR1 = 0; // Reset the USART
regs->CR2 = 0; // 1 stop bit
// If we don't touch the BRR (baudrate register), we don't need to recompute.
regs->BRR = brr;
regs->CR1 = _BV(3) | _BV(13); // 8 bits, no parity, 1 stop bit (TE | UE)
#endif
}
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
static void TX(char c) {
#if WITHIN(SERIAL_PORT, 1, 6)
constexpr uint32_t usart_sr_txe = _BV(7);
while (!(regs->SR & usart_sr_txe)) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
sw_barrier();
}
regs->DR = c;
#else
// Let's hope a mystical guru will fix this, one day by writting interrupt-free USB CDC ACM code (or, at least, by polling the registers since interrupt will be queued but will never trigger)
// For now, it's completely lost to oblivion.
#endif
}
void install_min_serial() {
HAL_min_serial_init = &TXBegin;
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't jump to a symbol that's too far from the current function, so we work around this in exception_arm.cpp
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) HardFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) BusFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) UsageFault_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) MemManage_Handler();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) NMI_Handler();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // ARDUINO_ARCH_STM32
+1 -1
View File
@@ -42,7 +42,7 @@ protected:
usart_rx_callback_t _rx_callback;
};
typedef Serial1Class<MarlinSerial> MSerialT;
typedef Serial0Type<MarlinSerial> MSerialT;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
extern MSerialT MSerial3;
+1 -1
View File
@@ -48,7 +48,7 @@
#include "stm32_def.h"
#define DEBUG_OUT ENABLED(EEPROM_CHITCHAT)
#include "../../core/debug_out.h"
#include "src/core/debug_out.h"
#ifndef MARLIN_EEPROM_SIZE
#define MARLIN_EEPROM_SIZE 0x1000 // 4KB
@@ -24,9 +24,3 @@
#if defined(USBD_USE_CDC_MSC) && DISABLED(NO_SD_HOST_DRIVE)
#define HAS_SD_HOST_DRIVE 1
#endif
// Fix F_CPU not being a compile-time constant in STSTM32 framework
#ifdef BOARD_F_CPU
#undef F_CPU
#define F_CPU BOARD_F_CPU
#endif
+2 -2
View File
@@ -47,9 +47,9 @@
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on STM32."
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on STM32."
#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)
+3 -3
View File
@@ -207,12 +207,12 @@ void TFT_SPI::Transmit(uint16_t Data) {
while ((SPIx.Instance->SR & SPI_FLAG_BSY) == SPI_FLAG_BSY) {}
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
__HAL_SPI_CLEAR_OVRFLAG(&SPIx); /* Clear overrun flag in 2 Lines communication mode because received is not read */
}
void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Count) {
// Wait last dma finish, to start another
while (isBusy()) { /* nada */ }
while(isBusy()) { }
DMAtx.Init.MemInc = MemoryIncrease;
HAL_DMA_Init(&DMAtx);
@@ -225,7 +225,7 @@ void TFT_SPI::TransmitDMA(uint32_t MemoryIncrease, uint16_t *Data, uint16_t Coun
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
SET_BIT(SPIx.Instance->CR2, SPI_CR2_TXDMAEN); /* Enable Tx DMA Request */
HAL_DMA_PollForTransfer(&DMAtx, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
Abort();
+2 -14
View File
@@ -84,7 +84,7 @@
#if defined(SERIAL_USB) && !HAS_SD_HOST_DRIVE
USBSerial SerialUSB;
DefaultSerial1 MSerial0(true, SerialUSB);
DefaultSerial MSerial(true, SerialUSB);
#if ENABLED(EMERGENCY_PARSER)
#include "../libmaple/usb/stm32f1/usb_reg_map.h"
@@ -107,7 +107,7 @@
len = usb_cdcacm_peek(buf, total);
for (uint32 i = 0; i < len; i++)
emergency_parser.update(MSerial0.emergency_state, buf[i + total - len]);
emergency_parser.update(MSerial.emergency_state, buf[i + total - len]);
}
#endif
#endif
@@ -132,9 +132,6 @@ const uint8_t adc_pins[] = {
#if HAS_TEMP_CHAMBER
TEMP_CHAMBER_PIN,
#endif
#if HAS_TEMP_COOLER
TEMP_COOLER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1_PIN,
#endif
@@ -192,9 +189,6 @@ enum TempPinIndex : char {
#if HAS_TEMP_CHAMBER
TEMP_CHAMBER,
#endif
#if HAS_TEMP_COOLER
TEMP_COOLER_PIN,
#endif
#if HAS_TEMP_ADC_1
TEMP_1,
#endif
@@ -278,8 +272,6 @@ static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) {
} }
#endif
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
void HAL_init() {
NVIC_SetPriorityGrouping(0x3);
#if PIN_EXISTS(LED)
@@ -295,7 +287,6 @@ void HAL_init() {
delay(1000); // Give OS time to notice
OUT_WRITE(USB_CONNECT_PIN, USB_CONNECT_INVERTING);
#endif
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the minimal serial handler
}
// HAL idle task
@@ -391,9 +382,6 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if HAS_TEMP_CHAMBER
case TEMP_CHAMBER_PIN: pin_index = TEMP_CHAMBER; break;
#endif
#if HAS_TEMP_COOLER
case TEMP_COOLER_PIN: pin_index = TEMP_COOLER; break;
#endif
#if HAS_TEMP_ADC_1
case TEMP_1_PIN: pin_index = TEMP_1; break;
#endif
+8 -8
View File
@@ -61,11 +61,11 @@
#endif
#ifdef SERIAL_USB
typedef ForwardSerial1Class< USBSerial > DefaultSerial1;
extern DefaultSerial1 MSerial0;
typedef ForwardSerial0Type< USBSerial > DefaultSerial;
extern DefaultSerial MSerial;
#if !HAS_SD_HOST_DRIVE
#define UsbSerial MSerial0
#define UsbSerial MSerial
#else
#define UsbSerial MarlinCompositeSerial
#endif
@@ -81,9 +81,9 @@
#endif
#if SERIAL_PORT == -1
#define MYSERIAL1 UsbSerial
#define MYSERIAL0 UsbSerial
#elif WITHIN(SERIAL_PORT, 1, NUM_UARTS)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#elif NUM_UARTS == 5
#error "SERIAL_PORT must be -1 or from 1 to 5. Please update your configuration."
#else
@@ -92,9 +92,9 @@
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 UsbSerial
#define MYSERIAL1 UsbSerial
#elif WITHIN(SERIAL_PORT_2, 1, NUM_UARTS)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#elif NUM_UARTS == 5
#error "SERIAL_PORT_2 must be -1 or from 1 to 5. Please update your configuration."
#else
@@ -124,7 +124,7 @@
#else
#error "LCD_SERIAL_PORT must be -1 or from 1 to 3. Please update your configuration."
#endif
#if HAS_DGUS_LCD
#if HAS_DGUS_LCD || ENABLED(DGUS_LCD_UI_CREALITY_TOUCH)
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
#endif
#endif
-118
View File
@@ -1,118 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2017 Victor Perez
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#ifdef __STM32F1__
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
#include "../shared/HAL_MinSerial.h"
#include "watchdog.h"
#include <libmaple/usart.h>
#include <libmaple/rcc.h>
#include <libmaple/nvic.h>
/* Instruction Synchronization Barrier */
#define isb() __asm__ __volatile__ ("isb" : : : "memory")
/* Data Synchronization Barrier */
#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
static void TXBegin() {
#if !WITHIN(SERIAL_PORT, 1, 6)
#warning "Using POSTMORTEM_DEBUGGING requires a physical U(S)ART hardware in case of severe error."
#warning "Disabling the severe error reporting feature currently because the used serial port is not a HW port."
#else
// We use MYSERIAL1 here, so we need to figure out how to get the linked register
struct usart_dev* dev = MYSERIAL1.c_dev();
// Or use this if removing libmaple
// int irq = dev->irq_num;
// int nvicUART[] = { NVIC_USART1 /* = 37 */, NVIC_USART2 /* = 38 */, NVIC_USART3 /* = 39 */, NVIC_UART4 /* = 52 */, NVIC_UART5 /* = 53 */ };
// Disabling irq means setting the bit in the NVIC ICER register located at
// Disable UART interrupt in NVIC
nvic_irq_disable(dev->irq_num);
// Use this if removing libmaple
//NVIC_BASE->ICER[1] |= _BV(irq - 32);
// We NEED memory barriers to ensure Interrupts are actually disabled!
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
dsb();
isb();
rcc_clk_disable(dev->clk_id);
rcc_clk_enable(dev->clk_id);
usart_reg_map *regs = dev->regs;
regs->CR1 = 0; // Reset the USART
regs->CR2 = 0; // 1 stop bit
// If we don't touch the BRR (baudrate register), we don't need to recompute. Else we would need to call
usart_set_baud_rate(dev, 0, BAUDRATE);
regs->CR1 = (USART_CR1_TE | USART_CR1_UE); // 8 bits, no parity, 1 stop bit
#endif
}
// A SW memory barrier, to ensure GCC does not overoptimize loops
#define sw_barrier() __asm__ volatile("": : :"memory");
static void TX(char c) {
#if WITHIN(SERIAL_PORT, 1, 6)
struct usart_dev* dev = MYSERIAL1.c_dev();
while (!(dev->regs->SR & USART_SR_TXE)) {
TERN_(USE_WATCHDOG, HAL_watchdog_refresh());
sw_barrier();
}
dev->regs->DR = c;
#endif
}
void install_min_serial() {
HAL_min_serial_init = &TXBegin;
HAL_min_serial_out = &TX;
}
#if DISABLED(DYNAMIC_VECTORTABLE) && DISABLED(STM32F0xx) // Cortex M0 can't branch to a symbol that's too far, so we have a specific hack for them
extern "C" {
__attribute__((naked)) void JumpHandler_ASM() {
__asm__ __volatile__ (
"b CommonHandler_ASM\n"
);
}
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_hardfault();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_busfault();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_usagefault();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_memmanage();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __exc_nmi();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception7();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception8();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception9();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception10();
void __attribute__((naked, alias("JumpHandler_ASM"), nothrow)) __stm32reservedexception13();
}
#endif
#endif // POSTMORTEM_DEBUGGING
#endif // __STM32F1__
+3 -3
View File
@@ -134,12 +134,12 @@ constexpr bool IsSerialClassAllowed(const HardwareSerial&) { return false; }
// If you encounter this error, replace SerialX with MSerialX, for example MSerial3.
// Non-TMC ports were already validated in HAL.h, so do not require verbose error messages.
#ifdef MYSERIAL0
CHECK_CFG_SERIAL(MYSERIAL0);
#endif
#ifdef MYSERIAL1
CHECK_CFG_SERIAL(MYSERIAL1);
#endif
#ifdef MYSERIAL2
CHECK_CFG_SERIAL(MYSERIAL2);
#endif
#ifdef LCD_SERIAL
CHECK_CFG_SERIAL(LCD_SERIAL);
#endif
+1 -1
View File
@@ -47,7 +47,7 @@ struct MarlinSerial : public HardwareSerial {
#endif
};
typedef Serial1Class<MarlinSerial> MSerialT;
typedef Serial0Type<MarlinSerial> MSerialT;
extern MSerialT MSerial1;
extern MSerialT MSerial2;
+1 -1
View File
@@ -40,7 +40,7 @@ void eeprom_init() { BL24CXX::init(); }
// Public functions
// ------------------------
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
const unsigned eeprom_address = (unsigned)pos;
return BL24CXX::writeOneByte(eeprom_address, value);
}
+2 -2
View File
@@ -34,9 +34,9 @@
#endif
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on the STM32F1 platform."
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on this platform."
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
#error "SERIAL_STATS_DROPPED_RX is not supported on the STM32F1 platform."
#error "SERIAL_STATS_DROPPED_RX is not supported on this platform."
#endif
#if ENABLED(NEOPIXEL_LED)
+18 -19
View File
@@ -24,7 +24,7 @@
#define PRODUCT_ID 0x29
USBMassStorage MarlinMSC;
Serial1Class<USBCompositeSerial> MarlinCompositeSerial(true);
Serial0Type<USBCompositeSerial> MarlinCompositeSerial(true);
#include "../../inc/MarlinConfig.h"
@@ -43,27 +43,26 @@ Serial1Class<USBCompositeSerial> MarlinCompositeSerial(true);
#if ENABLED(EMERGENCY_PARSER)
// The original callback is not called (no way to retrieve address).
// That callback detects a special STM32 reset sequence: this functionality is not essential
// as M997 achieves the same.
void my_rx_callback(unsigned int, void*) {
// max length of 16 is enough to contain all emergency commands
uint8 buf[16];
// The original callback is not called (no way to retrieve address).
// That callback detects a special STM32 reset sequence: this functionality is not essential
// as M997 achieves the same.
void my_rx_callback(unsigned int, void*) {
// max length of 16 is enough to contain all emergency commands
uint8 buf[16];
//rx is usbSerialPart.endpoints[2]
uint16 len = usb_get_ep_rx_count(usbSerialPart.endpoints[2].address);
uint32 total = composite_cdcacm_data_available();
//rx is usbSerialPart.endpoints[2]
uint16 len = usb_get_ep_rx_count(usbSerialPart.endpoints[2].address);
uint32 total = composite_cdcacm_data_available();
if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf)))
return;
if (len == 0 || total == 0 || !WITHIN(total, len, COUNT(buf)))
return;
// cannot get character by character due to bug in composite_cdcacm_peek_ex
len = composite_cdcacm_peek(buf, total);
for (uint32 i = 0; i < len; i++)
emergency_parser.update(MarlinCompositeSerial.emergency_state, buf[i+total-len]);
}
// cannot get character by character due to bug in composite_cdcacm_peek_ex
len = composite_cdcacm_peek(buf, total);
for (uint32 i = 0; i < len; i++)
emergency_parser.update(MarlinCompositeSerial.emergency_state, buf[i+total-len]);
}
#endif
void MSC_SD_init() {
@@ -88,7 +87,7 @@ void MSC_SD_init() {
MarlinCompositeSerial.registerComponent();
USBComposite.begin();
#if ENABLED(EMERGENCY_PARSER)
composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, my_rx_callback);
composite_cdcacm_set_hooks(USBHID_CDCACM_HOOK_RX, my_rx_callback);
#endif
}
+1 -1
View File
@@ -21,6 +21,6 @@
#include "../../core/serial_hook.h"
extern USBMassStorage MarlinMSC;
extern Serial1Class<USBCompositeSerial> MarlinCompositeSerial;
extern Serial0Type<USBCompositeSerial> MarlinCompositeSerial;
void MSC_SD_init();
+1 -5
View File
@@ -31,11 +31,7 @@
#include <Wire.h>
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
DefaultSerial MSerial(false);
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result;
+6 -11
View File
@@ -51,24 +51,19 @@
#endif
#include "../../core/serial_hook.h"
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
typedef Serial0Type<decltype(Serial)> DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL1 USBSerial
#define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#endif
#define HAL_SERVO_LIB libServo
+1 -5
View File
@@ -34,9 +34,5 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on Teensy 3.1/3.2."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 3.1/3.2."
#error "TMC220x Software Serial is not supported on this platform."
#endif
+1 -6
View File
@@ -31,12 +31,7 @@
#include <Wire.h>
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
DefaultSerial MSerial(false);
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result, HAL_adc_select;
+6 -11
View File
@@ -54,24 +54,19 @@
#endif
#include "../../core/serial_hook.h"
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
typedef Serial0Type<decltype(Serial)> DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL1 USBSerial
#define MYSERIAL0 USBSerial
#elif WITHIN(SERIAL_PORT, 0, 3)
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#endif
#define HAL_SERVO_LIB libServo
+1 -5
View File
@@ -34,9 +34,5 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on Teensy 3.5/3.6."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 3.5/3.6."
#error "TMC220x Software Serial is not supported on this platform."
#endif
+1 -5
View File
@@ -32,11 +32,7 @@
#include <Wire.h>
#define _IMPLEMENT_SERIAL(X) DefaultSerial##X MSerial##X(false, Serial##X)
#define IMPLEMENT_SERIAL(X) _IMPLEMENT_SERIAL(X)
#if WITHIN(SERIAL_PORT, 0, 3)
IMPLEMENT_SERIAL(SERIAL_PORT);
#endif
DefaultSerial MSerial(false);
USBSerialType USBSerial(false, SerialUSB);
uint16_t HAL_adc_result, HAL_adc_select;
+9 -13
View File
@@ -56,34 +56,30 @@
#endif
#include "../../core/serial_hook.h"
#define Serial0 Serial
#define _DECLARE_SERIAL(X) \
typedef ForwardSerial1Class<decltype(Serial##X)> DefaultSerial##X; \
extern DefaultSerial##X MSerial##X
#define DECLARE_SERIAL(X) _DECLARE_SERIAL(X)
typedef ForwardSerial1Class<decltype(SerialUSB)> USBSerialType;
typedef Serial0Type<decltype(Serial)> DefaultSerial;
extern DefaultSerial MSerial;
typedef ForwardSerial0Type<decltype(SerialUSB)> USBSerialType;
extern USBSerialType USBSerial;
#define _MSERIAL(X) MSerial##X
#define MSERIAL(X) _MSERIAL(X)
#define MSerial0 MSerial
#if SERIAL_PORT == -1
#define MYSERIAL1 SerialUSB
#define MYSERIAL0 SerialUSB
#elif WITHIN(SERIAL_PORT, 0, 8)
DECLARE_SERIAL(SERIAL_PORT);
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
#define MYSERIAL0 MSERIAL(SERIAL_PORT)
#else
#error "The required SERIAL_PORT must be from -1 to 8. Please update your configuration."
#endif
#ifdef SERIAL_PORT_2
#if SERIAL_PORT_2 == -1
#define MYSERIAL2 usbSerial
#define MYSERIAL1 usbSerial
#elif SERIAL_PORT_2 == -2
#define MYSERIAL2 ethernet.telnetClient
#define MYSERIAL1 ethernet.telnetClient
#elif WITHIN(SERIAL_PORT_2, 0, 8)
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
#define MYSERIAL1 MSERIAL(SERIAL_PORT_2)
#else
#error "SERIAL_PORT_2 must be from -2 to 8. Please update your configuration."
#endif
+1 -5
View File
@@ -34,9 +34,5 @@
#endif
#if HAS_TMC_SW_SERIAL
#error "TMC220x Software Serial is not supported on Teensy 4.0/4.1."
#endif
#if ENABLED(POSTMORTEM_DEBUGGING)
#error "POSTMORTEM_DEBUGGING is not yet supported on Teensy 4.0/4.1."
#error "TMC220x Software Serial is not supported on this platform."
#endif
+9 -6
View File
@@ -51,7 +51,7 @@
// Use hardware cycle counter instead, it's much safer
void delay_dwt(uint32_t count) {
// Reuse the ASM_CYCLES_PER_ITERATION variable to avoid wasting another useless variable
uint32_t start = HW_REG(_DWT_CYCCNT) - ASM_CYCLES_PER_ITERATION, elapsed;
register uint32_t start = HW_REG(_DWT_CYCCNT) - ASM_CYCLES_PER_ITERATION, elapsed;
do {
elapsed = HW_REG(_DWT_CYCCNT) - start;
} while (elapsed < count);
@@ -109,12 +109,12 @@
void dump_delay_accuracy_check() {
auto report_call_time = [](PGM_P const name, PGM_P const unit, const uint32_t cycles, const uint32_t total, const bool do_flush=true) {
SERIAL_ECHOPGM("Calling ");
SERIAL_ECHOPGM_P(name);
serialprintPGM(name);
SERIAL_ECHOLNPAIR(" for ", cycles);
SERIAL_ECHOPGM_P(unit);
serialprintPGM(unit);
SERIAL_ECHOLNPAIR(" took: ", total);
SERIAL_ECHOPGM_P(unit);
if (do_flush) SERIAL_FLUSHTX();
serialprintPGM(unit);
if (do_flush) SERIAL_FLUSH();
};
uint32_t s, e;
@@ -169,7 +169,10 @@
void calibrate_delay_loop() {}
#if ENABLED(MARLIN_DEV_MODE)
void dump_delay_accuracy_check() { SERIAL_ECHOPGM_P(PSTR("N/A on this platform")); }
void dump_delay_accuracy_check() {
static PGMSTR(none, "N/A on this platform");
serialprintPGM(none);
}
#endif
#endif
-33
View File
@@ -1,33 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "HAL_MinSerial.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
void HAL_min_serial_init_default() {}
void HAL_min_serial_out_default(char ch) { SERIAL_CHAR(ch); }
void (*HAL_min_serial_init)() = &HAL_min_serial_init_default;
void (*HAL_min_serial_out)(char) = &HAL_min_serial_out_default;
bool MinSerial::force_using_default_output = false;
#endif
-79
View File
@@ -1,79 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include "../../core/serial.h"
#include <stdint.h>
// Serial stuff here
// Inside an exception handler, the CPU state is not safe, we can't expect the handler to resume
// and the software to continue. UART communication can't rely on later callback/interrupt as it might never happen.
// So, you need to provide some method to send one byte to the usual UART with the interrupts disabled
// By default, the method uses SERIAL_CHAR but it's 100% guaranteed to break (couldn't be worse than nothing...)7
extern void (*HAL_min_serial_init)();
extern void (*HAL_min_serial_out)(char ch);
struct MinSerial {
static bool force_using_default_output;
// Serial output
static void TX(char ch) {
if (force_using_default_output)
SERIAL_CHAR(ch);
else
HAL_min_serial_out(ch);
}
// Send String through UART
static void TX(const char* s) { while (*s) TX(*s++); }
// Send a digit through UART
static void TXDigit(uint32_t d) {
if (d < 10) TX((char)(d+'0'));
else if (d < 16) TX((char)(d+'A'-10));
else TX('?');
}
// Send Hex number through UART
static void TXHex(uint32_t v) {
TX("0x");
for (uint8_t i = 0; i < 8; i++, v <<= 4)
TXDigit((v >> 28) & 0xF);
}
// Send Decimal number through UART
static void TXDec(uint32_t v) {
if (!v) {
TX('0');
return;
}
char nbrs[14];
char *p = &nbrs[0];
while (v != 0) {
*p++ = '0' + (v % 10);
v /= 10;
}
do {
p--;
TX(*p);
} while (p != &nbrs[0]);
}
static void init() { if (!force_using_default_output) HAL_min_serial_init(); }
};
+10 -18
View File
@@ -25,7 +25,7 @@
#include "unwinder.h"
#include "unwmemaccess.h"
#include "../HAL_MinSerial.h"
#include "../../../core/serial.h"
#include <stdarg.h>
// Dump a backtrace entry
@@ -34,12 +34,10 @@ static bool UnwReportOut(void* ctx, const UnwReport* bte) {
(*p)++;
const uint32_t a = bte->address, f = bte->function;
MinSerial::TX('#'); MinSerial::TXDec(*p); MinSerial::TX(" : ");
MinSerial::TX(bte->name?:"unknown"); MinSerial::TX('@'); MinSerial::TXHex(f);
MinSerial::TX('+'); MinSerial::TXDec(a - f);
MinSerial::TX(" PC:"); MinSerial::TXHex(a);
MinSerial::TX('\n');
SERIAL_CHAR('#'); SERIAL_ECHO(*p); SERIAL_ECHOPGM(" : ");
SERIAL_ECHOPGM(bte->name ? bte->name : "unknown"); SERIAL_ECHOPGM("@0x"); SERIAL_PRINT(bte->function, PrintBase::Hex);
SERIAL_CHAR('+'); SERIAL_ECHO(bte->address - bte->function);
SERIAL_ECHOPGM(" PC:"); SERIAL_PRINT(bte->address, PrintBase::Hex); SERIAL_CHAR('\n');
return true;
}
@@ -50,7 +48,7 @@ static bool UnwReportOut(void* ctx, const UnwReport* bte) {
va_start(argptr, format);
vsprintf(dest, format, argptr);
va_end(argptr);
MinSerial::TX(&dest[0]);
TX(&dest[0]);
}
#endif
@@ -65,10 +63,10 @@ static const UnwindCallbacks UnwCallbacks = {
#endif
};
// Perform a backtrace to the serial port
void backtrace() {
unsigned long sp = 0, lr = 0, pc = 0;
UnwindFrame btf;
uint32_t sp = 0, lr = 0, pc = 0;
// Capture the values of the registers to perform the traceback
__asm__ __volatile__ (
@@ -81,12 +79,6 @@ void backtrace() {
::
);
backtrace_ex(sp, lr, pc);
}
void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc) {
UnwindFrame btf;
// Fill the traceback structure
btf.sp = sp;
btf.fp = btf.sp;
@@ -94,7 +86,7 @@ void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc) {
btf.pc = pc | 1; // Force Thumb, as CORTEX only support it
// Perform a backtrace
MinSerial::TX("Backtrace:");
SERIAL_ERROR_MSG("Backtrace:");
int ctr = 0;
UnwindStart(&btf, &UnwCallbacks, &ctr);
}
@@ -103,4 +95,4 @@ void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc) {
void backtrace() {}
#endif // __arm__ || __thumb__
#endif
@@ -23,6 +23,3 @@
// Perform a backtrace to the serial port
void backtrace();
// Perform a backtrace to the serial port
void backtrace_ex(unsigned long sp, unsigned long lr, unsigned long pc);
@@ -41,16 +41,27 @@
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00080000
#elif 0
// For STM32F103CBT6
// SRAM (0x20000000 - 0x20005000) (20kb)
// FLASH (0x00000000 - 0x00020000) (128kb)
//
#define START_SRAM_ADDR 0x20000000
#define END_SRAM_ADDR 0x20005000
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00020000
#elif defined(__STM32F1__) || defined(STM32F1xx) || defined(STM32F0xx)
// For STM32F103ZET6/STM32F103VET6/STM32F0xx
// SRAM (0x20000000 - 0x20010000) (64kb)
// FLASH (0x08000000 - 0x08080000) (512kb)
// FLASH (0x00000000 - 0x00080000) (512kb)
//
#define START_SRAM_ADDR 0x20000000
#define END_SRAM_ADDR 0x20010000
#define START_FLASH_ADDR 0x08000000
#define END_FLASH_ADDR 0x08080000
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00080000
#elif defined(STM32F4) || defined(STM32F4xx)
@@ -131,57 +142,20 @@
#define START_FLASH_ADDR 0x00000000
#define END_FLASH_ADDR 0x00100000
#else
// Generic ARM code, that's testing if an access to the given address would cause a fault or not
// It can't guarantee an address is in RAM or Flash only, but we usually don't care
#define NVIC_FAULT_STAT 0xE000ED28 // Configurable Fault Status Reg.
#define NVIC_CFG_CTRL 0xE000ED14 // Configuration Control Register
#define NVIC_FAULT_STAT_BFARV 0x00008000 // BFAR is valid
#define NVIC_CFG_CTRL_BFHFNMIGN 0x00000100 // Ignore bus fault in NMI/fault
#define HW_REG(X) (*((volatile unsigned long *)(X)))
static bool validate_addr(uint32_t read_address) {
bool works = true;
uint32_t intDisabled = 0;
// Read current interrupt state
__asm__ __volatile__ ("MRS %[result], PRIMASK\n\t" : [result]"=r"(intDisabled) :: ); // 0 is int enabled, 1 for disabled
// Clear bus fault indicator first (write 1 to clear)
HW_REG(NVIC_FAULT_STAT) |= NVIC_FAULT_STAT_BFARV;
// Ignore bus fault interrupt
HW_REG(NVIC_CFG_CTRL) |= NVIC_CFG_CTRL_BFHFNMIGN;
// Disable interrupts if not disabled previously
if (!intDisabled) __asm__ __volatile__ ("CPSID f");
// Probe address
*(volatile uint32_t*)read_address;
// Check if a fault happened
if ((HW_REG(NVIC_FAULT_STAT) & NVIC_FAULT_STAT_BFARV) != 0)
works = false;
// Enable interrupts again if previously disabled
if (!intDisabled) __asm__ __volatile__ ("CPSIE f");
// Enable fault interrupt flag
HW_REG(NVIC_CFG_CTRL) &= ~NVIC_CFG_CTRL_BFHFNMIGN;
return works;
}
#endif
#ifdef START_SRAM_ADDR
static bool validate_addr(uint32_t addr) {
static bool validate_addr(uint32_t addr) {
// Address must be in SRAM range
if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR)
return true;
// Address must be in SRAM range
if (addr >= START_SRAM_ADDR && addr < END_SRAM_ADDR)
return true;
// Or in FLASH range
if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR)
return true;
// Or in FLASH range
if (addr >= START_FLASH_ADDR && addr < END_FLASH_ADDR)
return true;
return false;
}
#endif
return false;
}
bool UnwReadW(const uint32_t a, uint32_t *v) {
if (!validate_addr(a))
@@ -1,379 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
* Copyright (c) 2020 Cyril Russo
*
* 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/>.
*
*/
/***************************************************************************
* ARM CPU Exception handler
***************************************************************************/
#if defined(__arm__) || defined(__thumb__)
/*
On ARM CPUs exception handling is quite powerful.
By default, upon a crash, the CPU enters the handlers that have a higher priority than any other interrupts,
so, in effect, no (real) interrupt can "interrupt" the handler (it's acting like if interrupts were disabled).
If the handler is not called as re-entrant (that is, if the crash is not happening inside an interrupt or an handler),
then it'll patch the return address to a dumping function (resume_from_fault) and save the crash state.
The CPU will exit the handler and, as such, re-allow the other interrupts, and jump to the dumping function.
In this function, the usual serial port (USB / HW) will be used to dump the crash (no special configuration required).
The only case where it requires hardware UART is when it's crashing in an interrupt or a crash handler.
In that case, instead of returning to the resume_from_fault function (and thus, re-enabling interrupts),
it jumps to this function directly (so with interrupts disabled), after changing the behavior of the serial output
wrapper to use the HW uart (and in effect, calling MinSerial::init which triggers a warning if you are using
a USB serial port).
In the case you have a USB serial port, this part will be disabled, and only that part (so that's the reason for
the warning).
This means that you can't have a crash report if the crash happens in an interrupt or an handler if you are using
a USB serial port since it's physically impossible.
You will get a crash report in all other cases.
*/
#include "exception_hook.h"
#include "../backtrace/backtrace.h"
#include "../HAL_MinSerial.h"
#define HW_REG(X) (*((volatile unsigned long *)(X)))
// Default function use the CPU VTOR register to get the vector table.
// Accessing the CPU VTOR register is done in assembly since it's the only way that's common to all current tool
unsigned long get_vtor() { return HW_REG(0xE000ED08); } // Even if it looks like an error, it is not an error
void * hook_get_hardfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x03); }
void * hook_get_memfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x04); }
void * hook_get_busfault_vector_address(unsigned vtor) { return (void*)(vtor + 0x05); }
void * hook_get_usagefault_vector_address(unsigned vtor) { return (void*)(vtor + 0x06); }
void * hook_get_reserved_vector_address(unsigned vtor) { return (void*)(vtor + 0x07); }
// Common exception frame for ARM, should work for all ARM CPU
// Described here (modified for convenience): https://interrupt.memfault.com/blog/cortex-m-fault-debug
struct __attribute__((packed)) ContextStateFrame {
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r12;
uint32_t lr;
uint32_t pc;
uint32_t xpsr;
};
struct __attribute__((packed)) ContextSavedFrame {
uint32_t R0;
uint32_t R1;
uint32_t R2;
uint32_t R3;
uint32_t R12;
uint32_t LR;
uint32_t PC;
uint32_t XPSR;
uint32_t CFSR;
uint32_t HFSR;
uint32_t DFSR;
uint32_t AFSR;
uint32_t MMAR;
uint32_t BFAR;
uint32_t ESP;
uint32_t ELR;
};
#if DISABLED(STM32F0xx)
extern "C"
__attribute__((naked)) void CommonHandler_ASM() {
__asm__ __volatile__ (
// Bit 2 of LR tells which stack pointer to use (either main or process, only main should be used anyway)
"tst lr, #4\n"
"ite eq\n"
"mrseq r0, msp\n"
"mrsne r0, psp\n"
// Save the LR in use when being interrupted
"mov r1, lr\n"
// Get the exception number from the ICSR register
"ldr r2, =0xE000ED00\n"
"ldr r2, [r2, #4]\n"
"b CommonHandler_C\n"
);
}
#else // Cortex M0 does not support conditional mov and testing with a constant, so let's have a specific handler for it
extern "C"
__attribute__((naked)) void CommonHandler_ASM() {
__asm__ __volatile__ (
".syntax unified\n"
// Save the LR in use when being interrupted
"mov r1, lr\n"
// Get the exception number from the ICSR register
"ldr r2, =0xE000ED00\n"
"ldr r2, [r2, #4]\n"
"movs r0, #4\n"
"tst r1, r0\n"
"beq _MSP\n"
"mrs r0, psp\n"
"b CommonHandler_C\n"
"_MSP:\n"
"mrs r0, msp\n"
"b CommonHandler_C\n"
);
}
#if DISABLED(DYNAMIC_VECTORTABLE) // Cortex M0 requires the handler's address to be within 32kB to the actual function to be able to branch to it
extern "C" {
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_hardfault();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_busfault();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_usagefault();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_memmanage();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __exc_nmi();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception7();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception8();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception9();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception10();
void __attribute__((naked, alias("CommonHandler_ASM"), nothrow)) __stm32reservedexception13();
}
//TODO When going off from libmaple, you'll need to replace those by the one from STM32/HAL_MinSerial.cpp
#endif
#endif
// Must be a macro to avoid creating a function frame
#define HALT_IF_DEBUGGING() \
do { \
if (HW_REG(0xE000EDF0) & _BV(0)) { \
__asm("bkpt 1"); \
} \
} while (0)
// Resume from a fault (if possible) so we can still use interrupt based code for serial output
// In that case, we will not jump back to the faulty code, but instead to a dumping code and then a
// basic loop with watchdog calling or manual resetting
static ContextSavedFrame savedFrame;
static uint8_t lastCause;
bool resume_from_fault() {
static const char* causestr[] = { "Thread", "Rsvd", "NMI", "Hard", "Mem", "Bus", "Usage", "7", "8", "9", "10", "SVC", "Dbg", "13", "PendSV", "SysTk", "IRQ" };
// Reinit the serial link (might only work if implemented in each of your boards)
MinSerial::init();
MinSerial::TX("\n\n## Software Fault detected ##\n");
MinSerial::TX("Cause: "); MinSerial::TX(causestr[min(lastCause, (uint8_t)16)]); MinSerial::TX('\n');
MinSerial::TX("R0 : "); MinSerial::TXHex(savedFrame.R0); MinSerial::TX('\n');
MinSerial::TX("R1 : "); MinSerial::TXHex(savedFrame.R1); MinSerial::TX('\n');
MinSerial::TX("R2 : "); MinSerial::TXHex(savedFrame.R2); MinSerial::TX('\n');
MinSerial::TX("R3 : "); MinSerial::TXHex(savedFrame.R3); MinSerial::TX('\n');
MinSerial::TX("R12 : "); MinSerial::TXHex(savedFrame.R12); MinSerial::TX('\n');
MinSerial::TX("LR : "); MinSerial::TXHex(savedFrame.LR); MinSerial::TX('\n');
MinSerial::TX("PC : "); MinSerial::TXHex(savedFrame.PC); MinSerial::TX('\n');
MinSerial::TX("PSR : "); MinSerial::TXHex(savedFrame.XPSR); MinSerial::TX('\n');
// Configurable Fault Status Register
// Consists of MMSR, BFSR and UFSR
MinSerial::TX("CFSR : "); MinSerial::TXHex(savedFrame.CFSR); MinSerial::TX('\n');
// Hard Fault Status Register
MinSerial::TX("HFSR : "); MinSerial::TXHex(savedFrame.HFSR); MinSerial::TX('\n');
// Debug Fault Status Register
MinSerial::TX("DFSR : "); MinSerial::TXHex(savedFrame.DFSR); MinSerial::TX('\n');
// Auxiliary Fault Status Register
MinSerial::TX("AFSR : "); MinSerial::TXHex(savedFrame.AFSR); MinSerial::TX('\n');
// Read the Fault Address Registers. These may not contain valid values.
// Check BFARVALID/MMARVALID to see if they are valid values
// MemManage Fault Address Register
MinSerial::TX("MMAR : "); MinSerial::TXHex(savedFrame.MMAR); MinSerial::TX('\n');
// Bus Fault Address Register
MinSerial::TX("BFAR : "); MinSerial::TXHex(savedFrame.BFAR); MinSerial::TX('\n');
MinSerial::TX("ExcLR: "); MinSerial::TXHex(savedFrame.ELR); MinSerial::TX('\n');
MinSerial::TX("ExcSP: "); MinSerial::TXHex(savedFrame.ESP); MinSerial::TX('\n');
// The stack pointer is pushed by 8 words upon entering an exception, so we need to revert this
backtrace_ex(savedFrame.ESP + 8*4, savedFrame.LR, savedFrame.PC);
// Call the last resort function here
hook_last_resort_func();
const uint32_t start = millis(), end = start + 100; // 100ms should be enough
// We need to wait for the serial buffers to be output but we don't know for how long
// So we'll just need to refresh the watchdog for a while and then stop for the system to reboot
uint32_t last = start;
while (PENDING(last, end)) {
watchdog_refresh();
while (millis() == last) { /* nada */ }
last = millis();
MinSerial::TX('.');
}
// Reset now by reinstantiating the bootloader's vector table
HW_REG(0xE000ED08) = 0;
// Restart watchdog
#if DISABLED(USE_WATCHDOG)
// No watchdog, let's perform ARMv7 reset instead by writing to AIRCR register with VECTKEY set to SYSRESETREQ
HW_REG(0xE000ED0C) = (HW_REG(0xE000ED0C) & 0x0000FFFF) | 0x05FA0004;
#endif
while(1) {} // Bad luck, nothing worked
}
// Make sure the compiler does not optimize the frame argument away
extern "C"
__attribute__((optimize("O0")))
void CommonHandler_C(ContextStateFrame * frame, unsigned long lr, unsigned long cause) {
// If you are using it'll stop here
HALT_IF_DEBUGGING();
// Save the state to backtrace later on (don't call memcpy here since the stack can be corrupted)
savedFrame.R0 = frame->r0;
savedFrame.R1 = frame->r1;
savedFrame.R2 = frame->r2;
savedFrame.R3 = frame->r3;
savedFrame.R12 = frame->r12;
savedFrame.LR = frame->lr;
savedFrame.PC = frame->pc;
savedFrame.XPSR= frame->xpsr;
lastCause = cause & 0x1FF;
volatile uint32_t &CFSR = HW_REG(0xE000ED28);
savedFrame.CFSR = CFSR;
savedFrame.HFSR = HW_REG(0xE000ED2C);
savedFrame.DFSR = HW_REG(0xE000ED30);
savedFrame.AFSR = HW_REG(0xE000ED3C);
savedFrame.MMAR = HW_REG(0xE000ED34);
savedFrame.BFAR = HW_REG(0xE000ED38);
savedFrame.ESP = (unsigned long)frame; // Even on return, this should not be overwritten by the CPU
savedFrame.ELR = lr;
// First check if we can resume from this exception to our own handler safely
// If we can, then we don't need to disable interrupts and the usual serial code
// can be used
//const uint32_t non_usage_fault_mask = 0x0000FFFF;
//const bool non_usage_fault_occurred = (CFSR & non_usage_fault_mask) != 0;
// the bottom 8 bits of the xpsr hold the exception number of the
// executing exception or 0 if the processor is in Thread mode
const bool faulted_from_exception = ((frame->xpsr & 0xFF) != 0);
if (!faulted_from_exception) { // Not sure about the non_usage_fault, we want to try anyway, don't we ? && !non_usage_fault_occurred)
// Try to resume to our handler here
CFSR |= CFSR; // The ARM programmer manual says you must write to 1 all fault bits to clear them so this instruction is correct
// The frame will not be valid when returning anymore, let's clean it
savedFrame.CFSR = 0;
frame->pc = (uint32_t)resume_from_fault; // Patch where to return to
frame->lr = 0xDEADBEEF; // If our handler returns (it shouldn't), let's make it trigger an exception immediately
frame->xpsr = _BV(24); // Need to clean the PSR register to thumb II only
MinSerial::force_using_default_output = true;
return; // The CPU will resume in our handler hopefully, and we'll try to use default serial output
}
// Sorry, we need to emergency code here since the fault is too dangerous to recover from
MinSerial::force_using_default_output = false;
resume_from_fault();
}
void hook_cpu_exceptions() {
#if ENABLED(DYNAMIC_VECTORTABLE)
// On ARM 32bits CPU, the vector table is like this:
// 0x0C => Hardfault
// 0x10 => MemFault
// 0x14 => BusFault
// 0x18 => UsageFault
// Unfortunately, it's usually run from flash, and we can't write to flash here directly to hook our instruction
// We could set an hardware breakpoint, and hook on the fly when it's being called, but this
// is hard to get right and would probably break debugger when attached
// So instead, we'll allocate a new vector table filled with the previous value except
// for the fault we are interested in.
// Now, comes the issue to figure out what is the current vector table size
// There is nothing telling us what is the vector table as it's per-cpu vendor specific.
// BUT: we are being called at the end of the setup, so we assume the setup is done
// Thus, we can read the current vector table until we find an address that's not in flash, and it would mark the
// end of the vector table (skipping the fist entry obviously)
// The position of the program in flash is expected to be at 0x08xxx xxxx on all known platform for ARM and the
// flash size is available via register 0x1FFFF7E0 on STM32 family, but it's not the case for all ARM boards
// (accessing this register might trigger a fault if it's not implemented).
// So we'll simply mask the top 8 bits of the first handler as an hint of being in the flash or not -that's poor and will
// probably break if the flash happens to be more than 128MB, but in this case, we are not magician, we need help from outside.
unsigned long * vecAddr = (unsigned long*)get_vtor();
SERIAL_ECHO("Vector table addr: ");
SERIAL_PRINTLN(get_vtor(), HEX);
#ifdef VECTOR_TABLE_SIZE
uint32_t vec_size = VECTOR_TABLE_SIZE;
alignas(128) static unsigned long vectable[VECTOR_TABLE_SIZE] ;
#else
#ifndef IS_IN_FLASH
#define IS_IN_FLASH(X) (((unsigned long)X & 0xFF000000) == 0x08000000)
#endif
// When searching for the end of the vector table, this acts as a limit not to overcome
#ifndef VECTOR_TABLE_SENTINEL
#define VECTOR_TABLE_SENTINEL 80
#endif
// Find the vector table size
uint32_t vec_size = 1;
while (IS_IN_FLASH(vecAddr[vec_size]) && vec_size < VECTOR_TABLE_SENTINEL)
vec_size++;
// We failed to find a valid vector table size, let's abort hooking up
if (vec_size == VECTOR_TABLE_SENTINEL) return;
// Poor method that's wasting RAM here, but allocating with malloc and alignment would be worst
// 128 bytes alignement is required for writing the VTOR register
alignas(128) static unsigned long vectable[VECTOR_TABLE_SENTINEL];
SERIAL_ECHO("Detected vector table size: ");
SERIAL_PRINTLN(vec_size, HEX);
#endif
uint32_t defaultFaultHandler = vecAddr[(unsigned)7];
// Copy the current vector table into the new table
for (uint32_t i = 0; i < vec_size; i++) {
vectable[i] = vecAddr[i];
// Replace all default handler by our own handler
if (vectable[i] == defaultFaultHandler)
vectable[i] = (unsigned long)&CommonHandler_ASM;
}
// Let's hook now with our functions
vectable[(unsigned long)hook_get_hardfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
vectable[(unsigned long)hook_get_memfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
vectable[(unsigned long)hook_get_busfault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
vectable[(unsigned long)hook_get_usagefault_vector_address(0)] = (unsigned long)&CommonHandler_ASM;
// Finally swap with our own vector table
// This is supposed to be atomic, but let's do that with interrupt disabled
HW_REG(0xE000ED08) = (unsigned long)vectable | _BV32(29); // 29th bit is for telling the CPU the table is now in SRAM (should be present already)
SERIAL_ECHOLN("Installed fault handlers");
#endif
}
#endif // __arm__ || __thumb__
@@ -1,28 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "exception_hook.h"
void * __attribute__((weak)) hook_get_hardfault_vector_address(unsigned) { return 0; }
void * __attribute__((weak)) hook_get_memfault_vector_address(unsigned) { return 0; }
void * __attribute__((weak)) hook_get_busfault_vector_address(unsigned) { return 0; }
void * __attribute__((weak)) hook_get_usagefault_vector_address(unsigned) { return 0; }
void __attribute__((weak)) hook_last_resort_func() {}
@@ -1,54 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
/* Here is the expected behavior of a system producing a CPU exception with this hook installed:
1. Before the system is crashed
1.1 Upon validation (not done yet in this code, but we could be using DEBUG flags here to allow/disallow hooking)
1.2 Install the hook by overwriting the vector table exception handler with the hooked function
2. Upon system crash (for example, by a dereference of a NULL pointer or anything else)
2.1 The CPU triggers its exception and jump into the vector table for the exception type
2.2 Instead of finding the default handler, it finds the updated pointer to our hook
2.3 The CPU jumps into our hook function (likely a naked function to keep all information about crash point intact)
2.4 The hook (naked) function saves the important registers (stack pointer, program counter, current mode) and jumps to a common exception handler (in C)
2.5 The common exception handler dumps the registers on the serial link and perform a backtrace around the crashing point
2.6 Once the backtrace is performed the last resort function is called (platform specific).
On some platform with a LCD screen, this might display the crash information as a QR code or as text for the
user to capture by taking a picture
2.7 The CPU is reset and/or halted by triggering a debug breakpoint if a debugger is attached */
// Hook into CPU exception interrupt table to call the backtracing code upon an exception
// Most platform will simply do nothing here, but those who can will install/overwrite the default exception handler
// with a more performant exception handler
void hook_cpu_exceptions();
// Some platform might deal without a hard fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_hardfault_vector_address(unsigned base_address);
// Some platform might deal without a memory management fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_memfault_vector_address(unsigned base_address);
// Some platform might deal without a bus fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_busfault_vector_address(unsigned base_address);
// Some platform might deal without a usage fault handler, in that case, return 0 in your platform here or skip implementing it
void * __attribute__((weak)) hook_get_usagefault_vector_address(unsigned base_address);
// Last resort function that can be called after the exception handler was called.
void __attribute__((weak)) hook_last_resort_func();
+1 -1
View File
@@ -25,5 +25,5 @@
// EEPROM
//
void eeprom_init();
void eeprom_write_byte(uint8_t *pos, uint8_t value);
void eeprom_write_byte(uint8_t *pos, unsigned char value);
uint8_t eeprom_read_byte(uint8_t *pos);
+10 -15
View File
@@ -32,13 +32,7 @@
#include "eeprom_if.h"
#include <Wire.h>
void eeprom_init() {
Wire.begin(
#if PINS_EXIST(I2C_SCL, I2C_SDA)
uint8_t(I2C_SDA_PIN), uint8_t(I2C_SCL_PIN)
#endif
);
}
void eeprom_init() { Wire.begin(); }
#if ENABLED(USE_SHARED_EEPROM)
@@ -55,15 +49,12 @@ static constexpr uint8_t eeprom_device_address = I2C_ADDRESS(EEPROM_DEVICE_ADDRE
// Public functions
// ------------------------
static void _eeprom_begin(uint8_t * const pos) {
void eeprom_write_byte(uint8_t *pos, unsigned char value) {
const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // Address High
Wire.write(int(eeprom_address & 0xFF)); // Address Low
}
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
_eeprom_begin(pos);
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // MSB
Wire.write(int(eeprom_address & 0xFF)); // LSB
Wire.write(value);
Wire.endTransmission();
@@ -73,7 +64,11 @@ void eeprom_write_byte(uint8_t *pos, uint8_t value) {
}
uint8_t eeprom_read_byte(uint8_t *pos) {
_eeprom_begin(pos);
const unsigned eeprom_address = (unsigned)pos;
Wire.beginTransmission(eeprom_device_address);
Wire.write(int(eeprom_address >> 8)); // MSB
Wire.write(int(eeprom_address & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(eeprom_device_address, (byte)1);
return Wire.available() ? Wire.read() : 0xFF;
+29 -26
View File
@@ -43,41 +43,44 @@ void eeprom_init() {}
#define EEPROM_WRITE_DELAY 7
#endif
static void _eeprom_begin(uint8_t * const pos, const uint8_t cmd) {
const uint8_t eeprom_temp[3] = {
cmd,
(unsigned(pos) >> 8) & 0xFF, // Address High
unsigned(pos) & 0xFF // Address Low
};
WRITE(SPI_EEPROM1_CS, HIGH); // Usually free already
WRITE(SPI_EEPROM1_CS, LOW); // Activate the Bus
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
// Leave the Bus in-use
}
uint8_t eeprom_read_byte(uint8_t* pos) {
_eeprom_begin(pos, CMD_READ); // Set read location and begin transmission
uint8_t v;
uint8_t eeprom_temp[3];
const uint8_t v = spiRec(SPI_CHAN_EEPROM1); // After READ a value sits on the Bus
WRITE(SPI_EEPROM1_CS, HIGH); // Done with device
// set read location
// begin transmission from device
eeprom_temp[0] = CMD_READ;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; // addr High
eeprom_temp[2] = (unsigned)pos& 0xFF; // addr Low
WRITE(SPI_EEPROM1_CS, HIGH);
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
v = spiRec(SPI_CHAN_EEPROM1);
WRITE(SPI_EEPROM1_CS, HIGH);
return v;
}
void eeprom_write_byte(uint8_t *pos, uint8_t value) {
const uint8_t eeprom_temp = CMD_WREN;
void eeprom_write_byte(uint8_t* pos, uint8_t value) {
uint8_t eeprom_temp[3];
/*write enable*/
eeprom_temp[0] = CMD_WREN;
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, &eeprom_temp, 1); // Write Enable
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 1);
WRITE(SPI_EEPROM1_CS, HIGH);
delay(1);
WRITE(SPI_EEPROM1_CS, HIGH); // Done with the Bus
delay(1); // For a small amount of time
/*write addr*/
eeprom_temp[0] = CMD_WRITE;
eeprom_temp[1] = ((unsigned)pos>>8) & 0xFF; //addr High
eeprom_temp[2] = (unsigned)pos & 0xFF; //addr Low
WRITE(SPI_EEPROM1_CS, LOW);
spiSend(SPI_CHAN_EEPROM1, eeprom_temp, 3);
_eeprom_begin(pos, CMD_WRITE); // Set write address and begin transmission
spiSend(SPI_CHAN_EEPROM1, value); // Send the value to be written
WRITE(SPI_EEPROM1_CS, HIGH); // Done with the Bus
delay(EEPROM_WRITE_DELAY); // Give page write time to complete
spiSend(SPI_CHAN_EEPROM1, value);
WRITE(SPI_EEPROM1_CS, HIGH);
delay(EEPROM_WRITE_DELAY); // wait for page write to complete
}
#endif // USE_SHARED_EEPROM
+53 -299
View File
@@ -36,7 +36,6 @@
#include "HAL/shared/Delay.h"
#include "HAL/shared/esp_wifi.h"
#include "HAL/shared/cpu_exception/exception_hook.h"
#ifdef ARDUINO
#include <pins_arduino.h>
@@ -231,10 +230,6 @@
#include "feature/password/password.h"
#endif
#if ENABLED(DGUS_LCD_UI_MKS)
#include "lcd/extui/lib/dgus/DGUSScreenHandler.h"
#endif
PGMSTR(M112_KILL_STR, "M112 Shutdown");
MarlinState marlin_state = MF_INITIALIZING;
@@ -392,7 +387,6 @@ void startOrResumeJob() {
if (queue.enqueue_one_P(PSTR("M1001"))) {
marlin_state = MF_RUNNING;
TERN_(PASSWORD_AFTER_SD_PRINT_END, password.lock_machine());
TERN_(DGUS_LCD_UI_MKS, ScreenHandler.SDPrintingFinished());
}
}
@@ -406,14 +400,13 @@ void startOrResumeJob() {
* - Check if CHDK_PIN needs to go LOW
* - Check for KILL button held down
* - Check for HOME button held down
* - Check for CUSTOM USER button held down
* - Check if cooling fan needs to be switched on
* - Check if an idle but hot extruder needs filament extruded (EXTRUDER_RUNOUT_PREVENT)
* - Pulse FET_SAFETY_PIN if it exists
*/
inline void manage_inactivity(const bool ignore_stepper_queue=false) {
queue.get_available_commands();
if (queue.length < BUFSIZE) queue.get_available_commands();
const millis_t ms = millis();
@@ -499,102 +492,6 @@ inline void manage_inactivity(const bool ignore_stepper_queue=false) {
}
#endif
#if ENABLED(CUSTOM_USER_BUTTONS)
// Handle a custom user button if defined
const bool printer_not_busy = !printingIsActive();
#define HAS_CUSTOM_USER_BUTTON(N) (PIN_EXISTS(BUTTON##N) && defined(BUTTON##N##_HIT_STATE) && defined(BUTTON##N##_GCODE) && defined(BUTTON##N##_DESC))
#define CHECK_CUSTOM_USER_BUTTON(N) do{ \
constexpr millis_t CUB_DEBOUNCE_DELAY_##N = 250UL; \
static millis_t next_cub_ms_##N; \
if (BUTTON##N##_HIT_STATE == READ(BUTTON##N##_PIN) \
&& (ENABLED(BUTTON##N##_WHEN_PRINTING) || printer_not_busy)) { \
const millis_t ms = millis(); \
if (ELAPSED(ms, next_cub_ms_##N)) { \
next_cub_ms_##N = ms + CUB_DEBOUNCE_DELAY_##N; \
if (strlen(BUTTON##N##_DESC)) \
LCD_MESSAGEPGM_P(PSTR(BUTTON##N##_DESC)); \
queue.inject_P(PSTR(BUTTON##N##_GCODE)); \
} \
} \
}while(0)
#if HAS_CUSTOM_USER_BUTTON(1)
CHECK_CUSTOM_USER_BUTTON(1);
#endif
#if HAS_CUSTOM_USER_BUTTON(2)
CHECK_CUSTOM_USER_BUTTON(2);
#endif
#if HAS_CUSTOM_USER_BUTTON(3)
CHECK_CUSTOM_USER_BUTTON(3);
#endif
#if HAS_CUSTOM_USER_BUTTON(4)
CHECK_CUSTOM_USER_BUTTON(4);
#endif
#if HAS_CUSTOM_USER_BUTTON(5)
CHECK_CUSTOM_USER_BUTTON(5);
#endif
#if HAS_CUSTOM_USER_BUTTON(6)
CHECK_CUSTOM_USER_BUTTON(6);
#endif
#if HAS_CUSTOM_USER_BUTTON(7)
CHECK_CUSTOM_USER_BUTTON(7);
#endif
#if HAS_CUSTOM_USER_BUTTON(8)
CHECK_CUSTOM_USER_BUTTON(8);
#endif
#if HAS_CUSTOM_USER_BUTTON(9)
CHECK_CUSTOM_USER_BUTTON(9);
#endif
#if HAS_CUSTOM_USER_BUTTON(10)
CHECK_CUSTOM_USER_BUTTON(10);
#endif
#if HAS_CUSTOM_USER_BUTTON(11)
CHECK_CUSTOM_USER_BUTTON(11);
#endif
#if HAS_CUSTOM_USER_BUTTON(12)
CHECK_CUSTOM_USER_BUTTON(12);
#endif
#if HAS_CUSTOM_USER_BUTTON(13)
CHECK_CUSTOM_USER_BUTTON(13);
#endif
#if HAS_CUSTOM_USER_BUTTON(14)
CHECK_CUSTOM_USER_BUTTON(14);
#endif
#if HAS_CUSTOM_USER_BUTTON(15)
CHECK_CUSTOM_USER_BUTTON(15);
#endif
#if HAS_CUSTOM_USER_BUTTON(16)
CHECK_CUSTOM_USER_BUTTON(16);
#endif
#if HAS_CUSTOM_USER_BUTTON(17)
CHECK_CUSTOM_USER_BUTTON(17);
#endif
#if HAS_CUSTOM_USER_BUTTON(18)
CHECK_CUSTOM_USER_BUTTON(18);
#endif
#if HAS_CUSTOM_USER_BUTTON(19)
CHECK_CUSTOM_USER_BUTTON(19);
#endif
#if HAS_CUSTOM_USER_BUTTON(20)
CHECK_CUSTOM_USER_BUTTON(20);
#endif
#if HAS_CUSTOM_USER_BUTTON(21)
CHECK_CUSTOM_USER_BUTTON(21);
#endif
#if HAS_CUSTOM_USER_BUTTON(22)
CHECK_CUSTOM_USER_BUTTON(22);
#endif
#if HAS_CUSTOM_USER_BUTTON(23)
CHECK_CUSTOM_USER_BUTTON(23);
#endif
#if HAS_CUSTOM_USER_BUTTON(24)
CHECK_CUSTOM_USER_BUTTON(24);
#endif
#if HAS_CUSTOM_USER_BUTTON(25)
CHECK_CUSTOM_USER_BUTTON(25);
#endif
#endif
TERN_(USE_CONTROLLER_FAN, controllerFan.update()); // Check if fan should be turned on to cool stepper drivers down
TERN_(AUTO_POWER_CONTROL, powerManager.check());
@@ -889,8 +786,8 @@ void stop() {
print_job_timer.stop();
#if EITHER(PROBING_FANS_OFF, ADVANCED_PAUSE_FANS_PAUSE)
thermalManager.set_fans_paused(false); // Un-pause fans for safety
#if ENABLED(PROBING_FANS_OFF)
if (thermalManager.fans_paused) thermalManager.set_fans_paused(false); // put things back the way they were
#endif
if (IsRunning()) {
@@ -953,97 +850,25 @@ inline void tmc_standby_setup() {
}
/**
* Marlin Firmware entry-point. Abandon Hope All Ye Who Enter Here.
* Setup before the program loop:
*
* - Call any special pre-init set for the board
* - Put TMC drivers into Low Power Standby mode
* - Init the serial ports (so setup can be debugged)
* - Set up the kill and suicide pins
* - Prepare (disable) board JTAG and Debug ports
* - Init serial for a connected MKS TFT with WiFi
* - Install Marlin custom Exception Handlers, if set.
* - Init Marlin's HAL interfaces (for SPI, i2c, etc.)
* - Init some optional hardware and features:
* • MAX Thermocouple pins
* • Duet Smart Effector
* • Filament Runout Sensor
* • TMC220x Stepper Drivers (Serial)
* • PSU control
* • Power-loss Recovery
* • L64XX Stepper Drivers (SPI)
* • Stepper Driver Reset: DISABLE
* • TMC Stepper Drivers (SPI)
* • Run BOARD_INIT if defined
* • ESP WiFi
* - Get the Reset Reason and report it
* Marlin entry-point: Set up before the program loop
* - Set up the kill pin, filament runout, power hold
* - Start the serial port
* - Print startup messages and diagnostics
* - Calibrate the HAL DELAY for precise timing
* - Init the buzzer, possibly a custom timer
* - Init more optional hardware:
* • Color LED illumination
* • Neopixel illumination
* • Controller Fan
* • Creality DWIN LCD (show boot image)
* • Tare the Probe if possible
* - Mount the (most likely external) SD Card
* - Load settings from EEPROM (or use defaults)
* - Init the Ethernet Port
* - Init Touch Buttons (for emulated DOGLCD)
* - Adjust the (certainly wrong) current position by the home offset
* - Init the Planner::position (steps) based on current (native) position
* - Initialize more managers and peripherals:
* • Temperatures
* • Print Job Timer
* • Endstops and Endstop Interrupts
* • Stepper ISR - Kind of Important!
* • Servos
* • Servo-based Probe
* • Photograph Pin
* • Laser/Spindle tool Power / PWM
* • Coolant Control
* • Bed Probe
* • Stepper Driver Reset: ENABLE
* • Digipot I2C - Stepper driver current control
* • Stepper DAC - Stepper driver current control
* • Solenoid (probe, or for other use)
* • Home Pin
* • Custom User Buttons
* • Red/Blue Status LEDs
* • Case Light
* • Prusa MMU filament changer
* • Fan Multiplexer
* • Mixing Extruder
* • BLTouch Probe
* • I2C Position Encoders
* • Custom I2C Bus handlers
* • Enhanced tools or extruders:
* • Switching Extruder
* • Switching Nozzle
* • Parking Extruder
* • Magnetic Parking Extruder
* • Switching Toolhead
* • Electromagnetic Switching Toolhead
* • Watchdog Timer - Also Kind of Important!
* • Closed Loop Controller
* - Run Startup Commands, if defined
* - Tell host to close Host Prompts
* - Test Trinamic driver connections
* - Init Prusa MMU2 filament changer
* - Init and test BL24Cxx EEPROM
* - Init Creality DWIN encoder, show faux progress bar
* - Reset Status Message / Show Service Messages
* - Init MAX7219 LED Matrix
* - Init Direct Stepping (Klipper-style motion control)
* - Init TFT LVGL UI (with 3D Graphics)
* - Apply Password Lock - Hold for Authentication
* - Open Touch Screen Calibration screen, if not calibrated
* - Set Marlin to RUNNING State
* - Get EEPROM or default settings
* - Initialize managers for:
* • temperature
* • planner
* • watchdog
* • stepper
* • photo pin
* • servos
* • LCD controller
* • Digipot I2C
* • Z probe sled
* • status LEDs
* • Max7219
*/
void setup() {
#ifdef BOARD_PREINIT
BOARD_PREINIT(); // Low-level init (before serial init)
#endif
tmc_standby_setup(); // TMC Low Power Standby pins must be set early or they're not usable
@@ -1051,7 +876,8 @@ void setup() {
auto log_current_ms = [&](PGM_P const msg) {
SERIAL_ECHO_START();
SERIAL_CHAR('['); SERIAL_ECHO(millis()); SERIAL_ECHOPGM("] ");
SERIAL_ECHOLNPGM_P(msg);
serialprintPGM(msg);
SERIAL_EOL();
};
#define SETUP_LOG(M) log_current_ms(PSTR(M))
#else
@@ -1059,14 +885,14 @@ void setup() {
#endif
#define SETUP_RUN(C) do{ SETUP_LOG(STRINGIFY(C)); C; }while(0)
MYSERIAL1.begin(BAUDRATE);
MYSERIAL0.begin(BAUDRATE);
millis_t serial_connect_timeout = millis() + 1000UL;
while (!MYSERIAL1.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
while (!MYSERIAL0.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#if HAS_MULTI_SERIAL && !HAS_ETHERNET
MYSERIAL2.begin(BAUDRATE);
MYSERIAL1.begin(BAUDRATE);
serial_connect_timeout = millis() + 1000UL;
while (!MYSERIAL2.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
while (!MYSERIAL1.connected() && PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
SERIAL_ECHOLNPGM("start");
@@ -1085,6 +911,12 @@ void setup() {
OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif
#if ENABLED(PSU_CONTROL)
SETUP_LOG("PSU_CONTROL");
powersupply_on = ENABLED(PSU_DEFAULT_OFF);
if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
#endif
#if EITHER(DISABLE_DEBUG, DISABLE_JTAG)
// Disable any hardware debug to free up pins for IO
#if ENABLED(DISABLE_DEBUG) && defined(JTAGSWD_DISABLE)
@@ -1103,8 +935,6 @@ void setup() {
while (/*!WIFISERIAL && */PENDING(millis(), serial_connect_timeout)) { /*nada*/ }
#endif
TERN_(DYNAMIC_VECTORTABLE, hook_cpu_exceptions()); // If supported, install Marlin exception handlers at runtime
SETUP_RUN(HAL_init());
// Init and disable SPI thermocouples; this is still needed
@@ -1115,6 +945,10 @@ void setup() {
OUT_WRITE(MAX6675_SS2_PIN, HIGH); // Disable
#endif
#if HAS_L64XX
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#endif
#if ENABLED(DUET_SMART_EFFECTOR) && PIN_EXISTS(SMART_EFFECTOR_MOD)
OUT_WRITE(SMART_EFFECTOR_MOD_PIN, LOW); // Put Smart Effector into NORMAL mode
#endif
@@ -1123,22 +957,12 @@ void setup() {
SETUP_RUN(runout.setup());
#endif
#if HAS_TMC220x
SETUP_RUN(tmc_serial_begin());
#endif
#if ENABLED(PSU_CONTROL)
SETUP_LOG("PSU_CONTROL");
powersupply_on = ENABLED(PSU_DEFAULT_OFF);
if (ENABLED(PSU_DEFAULT_OFF)) PSU_OFF(); else PSU_ON();
#endif
#if ENABLED(POWER_LOSS_RECOVERY)
SETUP_RUN(recovery.setup());
#endif
#if HAS_L64XX
SETUP_RUN(L64xxManager.init()); // Set up SPI, init drivers
#if HAS_TMC220x
SETUP_RUN(tmc_serial_begin());
#endif
#if HAS_STEPPER_RESET
@@ -1168,7 +992,7 @@ void setup() {
if (mcu & RST_SOFTWARE) SERIAL_ECHOLNPGM(STR_SOFTWARE_RESET);
HAL_clear_reset_source();
SERIAL_ECHOPGM_P(GET_TEXT(MSG_MARLIN));
serialprintPGM(GET_TEXT(MSG_MARLIN));
SERIAL_CHAR(' ');
SERIAL_ECHOLNPGM(SHORT_BUILD_VERSION);
SERIAL_EOL();
@@ -1297,95 +1121,19 @@ void setup() {
SET_INPUT_PULLUP(HOME_PIN);
#endif
#if ENABLED(CUSTOM_USER_BUTTONS)
#define INIT_CUSTOM_USER_BUTTON_PIN(N) do{ SET_INPUT(BUTTON##N##_PIN); WRITE(BUTTON##N##_PIN, !BUTTON##N##_HIT_STATE); }while(0)
#if HAS_CUSTOM_USER_BUTTON(1)
INIT_CUSTOM_USER_BUTTON_PIN(1);
#endif
#if HAS_CUSTOM_USER_BUTTON(2)
INIT_CUSTOM_USER_BUTTON_PIN(2);
#endif
#if HAS_CUSTOM_USER_BUTTON(3)
INIT_CUSTOM_USER_BUTTON_PIN(3);
#endif
#if HAS_CUSTOM_USER_BUTTON(4)
INIT_CUSTOM_USER_BUTTON_PIN(4);
#endif
#if HAS_CUSTOM_USER_BUTTON(5)
INIT_CUSTOM_USER_BUTTON_PIN(5);
#endif
#if HAS_CUSTOM_USER_BUTTON(6)
INIT_CUSTOM_USER_BUTTON_PIN(6);
#endif
#if HAS_CUSTOM_USER_BUTTON(7)
INIT_CUSTOM_USER_BUTTON_PIN(7);
#endif
#if HAS_CUSTOM_USER_BUTTON(8)
INIT_CUSTOM_USER_BUTTON_PIN(8);
#endif
#if HAS_CUSTOM_USER_BUTTON(9)
INIT_CUSTOM_USER_BUTTON_PIN(9);
#endif
#if HAS_CUSTOM_USER_BUTTON(10)
INIT_CUSTOM_USER_BUTTON_PIN(10);
#endif
#if HAS_CUSTOM_USER_BUTTON(11)
INIT_CUSTOM_USER_BUTTON_PIN(11);
#endif
#if HAS_CUSTOM_USER_BUTTON(12)
INIT_CUSTOM_USER_BUTTON_PIN(12);
#endif
#if HAS_CUSTOM_USER_BUTTON(13)
INIT_CUSTOM_USER_BUTTON_PIN(13);
#endif
#if HAS_CUSTOM_USER_BUTTON(14)
INIT_CUSTOM_USER_BUTTON_PIN(14);
#endif
#if HAS_CUSTOM_USER_BUTTON(15)
INIT_CUSTOM_USER_BUTTON_PIN(15);
#endif
#if HAS_CUSTOM_USER_BUTTON(16)
INIT_CUSTOM_USER_BUTTON_PIN(16);
#endif
#if HAS_CUSTOM_USER_BUTTON(17)
INIT_CUSTOM_USER_BUTTON_PIN(17);
#endif
#if HAS_CUSTOM_USER_BUTTON(18)
INIT_CUSTOM_USER_BUTTON_PIN(18);
#endif
#if HAS_CUSTOM_USER_BUTTON(19)
INIT_CUSTOM_USER_BUTTON_PIN(19);
#endif
#if HAS_CUSTOM_USER_BUTTON(20)
INIT_CUSTOM_USER_BUTTON_PIN(20);
#endif
#if HAS_CUSTOM_USER_BUTTON(21)
INIT_CUSTOM_USER_BUTTON_PIN(21);
#endif
#if HAS_CUSTOM_USER_BUTTON(22)
INIT_CUSTOM_USER_BUTTON_PIN(22);
#endif
#if HAS_CUSTOM_USER_BUTTON(23)
INIT_CUSTOM_USER_BUTTON_PIN(23);
#endif
#if HAS_CUSTOM_USER_BUTTON(24)
INIT_CUSTOM_USER_BUTTON_PIN(24);
#endif
#if HAS_CUSTOM_USER_BUTTON(25)
INIT_CUSTOM_USER_BUTTON_PIN(25);
#endif
#endif
#if PIN_EXISTS(STAT_LED_RED)
OUT_WRITE(STAT_LED_RED_PIN, LOW); // OFF
#endif
#if PIN_EXISTS(STAT_LED_BLUE)
OUT_WRITE(STAT_LED_BLUE_PIN, LOW); // OFF
#endif
#if ENABLED(CASE_LIGHT_ENABLE)
SETUP_RUN(caselight.init());
#if DISABLED(CASE_LIGHT_USE_NEOPIXEL)
if (PWM_PIN(CASE_LIGHT_PIN)) SET_PWM(CASE_LIGHT_PIN); else SET_OUTPUT(CASE_LIGHT_PIN);
#endif
SETUP_RUN(caselight.update_brightness());
#endif
#if HAS_PRUSA_MMU1
@@ -1432,13 +1180,19 @@ void setup() {
#endif
#endif
#if ENABLED(MAGNETIC_PARKING_EXTRUDER)
SETUP_RUN(mpe_settings_init());
#endif
#if ENABLED(PARKING_EXTRUDER)
SETUP_RUN(pe_solenoid_init());
#elif ENABLED(MAGNETIC_PARKING_EXTRUDER)
SETUP_RUN(mpe_settings_init());
#elif ENABLED(SWITCHING_TOOLHEAD)
#endif
#if ENABLED(SWITCHING_TOOLHEAD)
SETUP_RUN(swt_init());
#elif ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
#endif
#if ENABLED(ELECTROMAGNETIC_SWITCHING_TOOLHEAD)
SETUP_RUN(est_init());
#endif
+1 -3
View File
@@ -126,7 +126,6 @@
#define BOARD_EINSY_RAMBO 1203 // Einsy Rambo
#define BOARD_EINSY_RETRO 1204 // Einsy Retro
#define BOARD_SCOOVO_X9H 1205 // abee Scoovo X9H
#define BOARD_RAMBO_THINKERV2 1206 // ThinkerV2
//
// Other ATmega1280, ATmega2560
@@ -279,7 +278,6 @@
#define BOARD_ARCHIM2 3024 // UltiMachine Archim2 (with TMC2130 drivers)
#define BOARD_ALLIGATOR 3025 // Alligator Board R2
#define BOARD_CNCONTROLS_15D 3026 // Cartesio CN Controls V15 on DUE
#define BOARD_KRATOS32 3027 // K.3D Kratos32 (Arduino Due Shield)
//
// SAM3X8C ARM Cortex M3
@@ -329,7 +327,7 @@
#define BOARD_LONGER3D_LK 4034 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
#define BOARD_CCROBOT_MEEB_3DP 4035 // ccrobot-online.com MEEB_3DP (STM32F103RC)
#define BOARD_CHITU3D_V5 4036 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CHITU3D_V6 4037 // Chitu3D TronXY X5SA V6 Board
#define BOARD_CHITU3D_V6 4037 // Chitu3D TronXY X5SA V5 Board
#define BOARD_CREALITY_V4 4038 // Creality v4.x (STM32F103RE)
#define BOARD_CREALITY_V427 4039 // Creality v4.2.7 (STM32F103RE)
#define BOARD_CREALITY_V4210 4040 // Creality v4.2.10 (STM32F103RE) as found in the CR-30
-37
View File
@@ -1,37 +0,0 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Copyright (c) 2021 X-Ryl669 [https://blog.cyril.by]
*
* 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
// We need SERIAL_ECHOPAIR and macros.h
#include "serial.h"
#if ENABLED(POSTMORTEM_DEBUGGING)
// Useful macro for stopping the CPU on an unexpected condition
// This is used like SERIAL_ECHOPAIR, that is: a key-value call of the local variables you want
// to dump to the serial port before stopping the CPU.
#define BUG_ON(V...) do { SERIAL_ECHOPAIR(ONLY_FILENAME, __LINE__, ": "); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); *(char*)0 = 42; } while(0)
#elif ENABLED(MARLIN_DEV_MODE)
// Don't stop the CPU here, but at least dump the bug on the serial port
#define BUG_ON(V...) do { SERIAL_ECHOPAIR(ONLY_FILENAME, __LINE__, ": BUG!\n"); SERIAL_ECHOLNPAIR(V); SERIAL_FLUSHTX(); } while(0)
#else
// Release mode, let's ignore the bug
#define BUG_ON(V...) NOOP
#endif
+3 -3
View File
@@ -27,7 +27,7 @@
//
#undef DEBUG_SECTION
#undef DEBUG_ECHOPGM_P
#undef DEBUG_PRINT_P
#undef DEBUG_ECHO_START
#undef DEBUG_ERROR_START
#undef DEBUG_CHAR
@@ -59,7 +59,7 @@
#include "debug_section.h"
#define DEBUG_SECTION(N,S,D) SectionLog N(PSTR(S),D)
#define DEBUG_ECHOPGM_P(P) SERIAL_ECHOPGM_P(P)
#define DEBUG_PRINT_P(P) serialprintPGM(P)
#define DEBUG_ECHO_START SERIAL_ECHO_START
#define DEBUG_ERROR_START SERIAL_ERROR_START
#define DEBUG_CHAR SERIAL_CHAR
@@ -89,7 +89,7 @@
#else
#define DEBUG_SECTION(...) NOOP
#define DEBUG_ECHOPGM_P(P) NOOP
#define DEBUG_PRINT_P(P) NOOP
#define DEBUG_ECHO_START() NOOP
#define DEBUG_ERROR_START() NOOP
#define DEBUG_CHAR(...) NOOP
+2 -2
View File
@@ -38,10 +38,10 @@ private:
bool debug;
void echo_msg(PGM_P const pre) {
SERIAL_ECHOPGM_P(pre);
serialprintPGM(pre);
if (the_msg) {
SERIAL_CHAR(' ');
SERIAL_ECHOPGM_P(the_msg);
serialprintPGM(the_msg);
}
SERIAL_CHAR(' ');
print_xyz(current_position);
+1 -4
View File
@@ -131,7 +131,6 @@
#define STR_WATCHDOG_FIRED "Watchdog timeout. Reset required."
#define STR_ERR_KILLED "Printer halted. kill() called!"
#define STR_ERR_STOPPED "Printer stopped due to errors. Fix the error and use M999 to restart. (Temperature is reset. Set it after restarting)"
#define STR_ERR_SERIAL_MISMATCH "Serial status mismatch"
#define STR_BUSY_PROCESSING "busy: processing"
#define STR_BUSY_PAUSED_FOR_USER "busy: paused for user"
#define STR_BUSY_PAUSED_FOR_INPUT "busy: paused for input"
@@ -222,7 +221,7 @@
// temperature.cpp strings
#define STR_PID_AUTOTUNE_START "PID Autotune start"
#define STR_PID_BAD_HEATER_ID "PID Autotune failed! Bad heater id"
#define STR_PID_BAD_EXTRUDER_NUM "PID Autotune failed! Bad extruder number"
#define STR_PID_TEMP_TOO_HIGH "PID Autotune failed! Temperature too high"
#define STR_PID_TIMEOUT "PID Autotune failed! timeout"
#define STR_BIAS " bias: "
@@ -247,8 +246,6 @@
#define STR_HEATER_BED "bed"
#define STR_HEATER_CHAMBER "chamber"
#define STR_COOLER "cooler"
#define STR_LASER_TEMP "laser temperature"
#define STR_STOPPED_HEATER ", system stopped! Heater_ID: "
#define STR_REDUNDANCY "Heater switched off. Temperature difference between temp sensors is too high !"
-26
View File
@@ -104,7 +104,6 @@
#define RADIANS(d) ((d)*float(M_PI)/180.0f)
#define DEGREES(r) ((r)*180.0f/float(M_PI))
#define HYPOT2(x,y) (sq(x)+sq(y))
#define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z))
#define CIRCLE_AREA(R) (float(M_PI) * sq(float(R)))
#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
@@ -350,31 +349,6 @@
#define CALL_IF_EXISTS(Return, That, Method, ...) \
static_cast<Return>(Private::Call_ ## Method(That, ##__VA_ARGS__))
// Compile-time string manipulation
namespace CompileTimeString {
// Simple compile-time parser to find the position of the end of a string
constexpr const char* findStringEnd(const char *str) {
return *str ? findStringEnd(str + 1) : str;
}
// Check whether a string contains a slash
constexpr bool containsSlash(const char *str) {
return *str == '/' ? true : (*str ? containsSlash(str + 1) : false);
}
// Find the last position of the slash
constexpr const char* findLastSlashPos(const char* str) {
return *str == '/' ? (str + 1) : findLastSlashPos(str - 1);
}
// Compile-time evaluation of the last part of a file path
// Typically used to shorten the path to file in compiled strings
// CompileTimeString::baseName(__FILE__) returns "macros.h" and not /path/to/Marlin/src/core/macros.h
constexpr const char* baseName(const char* str) {
return containsSlash(str) ? findLastSlashPos(findStringEnd(str)) : str;
}
}
#define ONLY_FILENAME CompileTimeString::baseName(__FILE__)
#else
#define MIN_2(a,b) ((a)<(b)?(a):(b))
+11 -14
View File
@@ -37,22 +37,19 @@ PGMSTR(SP_A_STR, " A"); PGMSTR(SP_B_STR, " B"); PGMSTR(SP_C_STR, " C");
PGMSTR(SP_X_STR, " X"); PGMSTR(SP_Y_STR, " Y"); PGMSTR(SP_Z_STR, " Z"); PGMSTR(SP_E_STR, " E");
PGMSTR(SP_X_LBL, " X:"); PGMSTR(SP_Y_LBL, " Y:"); PGMSTR(SP_Z_LBL, " Z:"); PGMSTR(SP_E_LBL, " E:");
// Hook Meatpack if it's enabled on the first leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_1)
SerialLeafT1 mpSerial1(false, _SERIAL_LEAF_1);
#endif
#if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
SerialLeafT2 mpSerial2(false, _SERIAL_LEAF_2);
#endif
// Step 2: For multiserial, handle the second serial port as well
#if HAS_MULTI_SERIAL
#if HAS_ETHERNET
// We need a definition here
SerialLeafT2 msSerial2(ethernet.have_telnet_client, MYSERIAL2, false);
#ifdef SERIAL_CATCHALL
SerialOutputT multiSerial(MYSERIAL, SERIAL_CATCHALL);
#else
#if HAS_ETHERNET
// Runtime checking of the condition variable
ConditionalSerial<decltype(MYSERIAL1)> serialOut1(ethernet.have_telnet_client, MYSERIAL1, false); // Takes reference here
#else
// Don't pay for runtime checking a true variable, instead use the output directly
#define serialOut1 MYSERIAL1
#endif
SerialOutputT multiSerial(MYSERIAL0, serialOut1);
#endif
SerialOutputT multiSerial(SERIAL_LEAF_1, SERIAL_LEAF_2);
#endif
void serialprintPGM(PGM_P str) {
+14 -56
View File
@@ -24,10 +24,6 @@
#include "../inc/MarlinConfig.h"
#include "serial_hook.h"
#if HAS_MEATPACK
#include "../feature/meatpack.h"
#endif
// Commonly-used strings in serial output
extern const char NUL_STR[], SP_P_STR[], SP_T_STR[],
X_STR[], Y_STR[], Z_STR[], E_STR[],
@@ -62,66 +58,28 @@ extern uint8_t marlin_debug_flags;
//
// Serial redirection
//
// Step 1: Find what's the first serial leaf
#if BOTH(HAS_MULTI_SERIAL, SERIAL_CATCHALL)
#define _SERIAL_LEAF_1 MYSERIAL
#else
#define _SERIAL_LEAF_1 MYSERIAL1
#endif
// Hook Meatpack if it's enabled on the first leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_1)
typedef MeatpackSerial<decltype(_SERIAL_LEAF_1)> SerialLeafT1;
extern SerialLeafT1 mpSerial1;
#define SERIAL_LEAF_1 mpSerial1
#else
#define SERIAL_LEAF_1 _SERIAL_LEAF_1
#endif
// Step 2: For multiserial, handle the second serial port as well
typedef int8_t serial_index_t;
#define SERIAL_ALL 0x7F
#if HAS_MULTI_SERIAL
#define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p)
#define _PORT_RESTORE(n,p) RESTORE(n)
#define SERIAL_ASSERT(P) if(multiSerial.portMask!=(P)){ debugger(); }
// If we have a catchall, use that directly
#define _PORT_REDIRECT(n,p) REMEMBER(n,multiSerial.portMask,p)
#define SERIAL_ASSERT(P) if(multiSerial.portMask!=(P)){ debugger(); }
#ifdef SERIAL_CATCHALL
#define _SERIAL_LEAF_2 SERIAL_CATCHALL
typedef MultiSerial<decltype(MYSERIAL), decltype(SERIAL_CATCHALL), 0> SerialOutputT;
#else
#if HAS_ETHERNET
// We need to create an instance here
typedef ConditionalSerial<decltype(MYSERIAL2)> SerialLeafT2;
extern SerialLeafT2 msSerial2;
#define _SERIAL_LEAF_2 msSerial2
#else
// Don't create a useless instance here, directly use the existing instance
#define _SERIAL_LEAF_2 MYSERIAL2
#endif
typedef MultiSerial<decltype(MYSERIAL0), TERN(HAS_ETHERNET, ConditionalSerial<decltype(MYSERIAL1)>, decltype(MYSERIAL1)), 0> SerialOutputT;
#endif
// Hook Meatpack if it's enabled on the second leaf
#if ENABLED(MEATPACK_ON_SERIAL_PORT_2)
typedef MeatpackSerial<decltype(_SERIAL_LEAF_2)> SerialLeafT2;
extern SerialLeafT2 mpSerial2;
#define SERIAL_LEAF_2 mpSerial2
#else
#define SERIAL_LEAF_2 _SERIAL_LEAF_2
#endif
typedef MultiSerial<decltype(SERIAL_LEAF_1), decltype(SERIAL_LEAF_2), 0> SerialOutputT;
extern SerialOutputT multiSerial;
#define SERIAL_IMPL multiSerial
extern SerialOutputT multiSerial;
#define SERIAL_IMPL multiSerial
#else
#define _PORT_REDIRECT(n,p) NOOP
#define _PORT_RESTORE(n) NOOP
#define SERIAL_ASSERT(P) NOOP
#define SERIAL_IMPL SERIAL_LEAF_1
#define _PORT_REDIRECT(n,p) NOOP
#define SERIAL_ASSERT(P) NOOP
#define SERIAL_IMPL MYSERIAL0
#endif
#define SERIAL_OUT(WHAT, V...) (void)SERIAL_IMPL.WHAT(V)
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
#define PORT_RESTORE() _PORT_RESTORE(1)
#define SERIAL_PORTMASK(P) SerialMask::from(P)
#define PORT_REDIRECT(p) _PORT_REDIRECT(1,p)
#define SERIAL_PORTMASK(P) _BV(P)
//
// SERIAL_CHAR - Print one or more individual chars
@@ -334,7 +292,7 @@ void serialprintPGM(PGM_P str);
#endif
#define SERIAL_ECHOPGM_P(P) (serialprintPGM(P))
#define SERIAL_ECHOLNPGM_P(P) do{ serialprintPGM(P); SERIAL_EOL(); }while(0)
#define SERIAL_ECHOLNPGM_P(P) (serialprintPGM(P "\n"))
#define SERIAL_ECHOPGM(S) (serialprintPGM(PSTR(S)))
#define SERIAL_ECHOLNPGM(S) (serialprintPGM(PSTR(S "\n")))
+9 -26
View File
@@ -22,31 +22,14 @@
#pragma once
#include "../inc/MarlinConfigPre.h"
#include "macros.h"
#if ENABLED(EMERGENCY_PARSER)
#include "../feature/e_parser.h"
#endif
// Used in multiple places
// You can build it but not manipulate it.
// There are only few places where it's required to access the underlying member: GCodeQueue, SerialMask and MultiSerial
struct serial_index_t {
// A signed index, where -1 is a special case meaning no action (neither output or input)
int8_t index;
// Check if the index is within the range [a ... b]
constexpr inline bool within(const int8_t a, const int8_t b) const { return WITHIN(index, a, b); }
constexpr inline bool valid() const { return WITHIN(index, 0, 7); } // At most, 8 bits
// Construction is either from an index
constexpr serial_index_t(const int8_t index) : index(index) {}
// Default to "no index"
constexpr serial_index_t() : index(-1) {}
};
// flushTX is not implemented in all HAL, so use SFINAE to call the method where it is.
CALL_IF_EXISTS_IMPL(void, flushTX);
CALL_IF_EXISTS_IMPL(void, flushTX );
CALL_IF_EXISTS_IMPL(bool, connected, true);
// In order to catch usage errors in code, we make the base to encode number explicit
@@ -59,14 +42,14 @@ enum class PrintBase {
Bin = 2
};
// A simple forward struct that prevent the compiler to select print(double, int) as a default overload for any type different than
// A simple forward struct that prevent the compiler to select print(double, int) as a default overload for any type different than
// double or float. For double or float, a conversion exists so the call will be transparent
struct EnsureDouble {
double a;
FORCE_INLINE operator double() { return a; }
// If the compiler breaks on ambiguity here, it's likely because you're calling print(X, base) with X not a double or a float, and a
// base that's not one of PrintBase's value. This exact code is made to detect such error, you NEED to set a base explicitely like this:
// SERIAL_PRINT(v, PrintBase::Hex)
// SERIAL_PRINT(v, PrintBase::Hex)
FORCE_INLINE EnsureDouble(double a) : a(a) {}
FORCE_INLINE EnsureDouble(float a) : a(a) {}
};
@@ -96,10 +79,10 @@ struct SerialBase {
void end() { static_cast<Child*>(this)->end(); }
/** Check for available data from the port
@param index The port index, usually 0 */
int available(serial_index_t index = 0) { return static_cast<Child*>(this)->available(index); }
bool available(uint8_t index = 0) { return static_cast<Child*>(this)->available(index); }
/** Read a value from the port
@param index The port index, usually 0 */
int read(serial_index_t index = 0) { return static_cast<Child*>(this)->read(index); }
int read(uint8_t index = 0) { return static_cast<Child*>(this)->read(index); }
// Check if the serial port is connected (usually bypassed)
bool connected() { return static_cast<Child*>(this)->connected(); }
// Redirect flush
@@ -164,13 +147,13 @@ struct SerialBase {
else write('0');
}
void printNumber(signed long n, const uint8_t base) {
if (base == 10 && n < 0) {
if (base == 10 && n < 0) {
n = -n; // This works because all platforms Marlin's builds on are using 2-complement encoding for negative number
// On such CPU, changing the sign of a number is done by inverting the bits and adding one, so if n = 0x80000000 = -2147483648 then
// -n = 0x7FFFFFFF + 1 => 0x80000000 = 2147483648 (if interpreted as unsigned) or -2147483648 if interpreted as signed.
// On non 2-complement CPU, there would be no possible representation for 2147483648.
write('-');
}
write('-');
}
printNumber((unsigned long)n , base);
}
+59 -83
View File
@@ -21,33 +21,9 @@
*/
#pragma once
#include "macros.h"
#include "serial_base.h"
// A mask containing a bitmap of the serial port to act upon
// This is written to ensure a serial index is never used as a serial mask
class SerialMask {
uint8_t mask;
// This constructor is private to ensure you can't convert an index to a mask
// The compiler will stop here if you are mixing index and mask in your code.
// If you need to, you'll have to use the explicit static "from" method here
SerialMask(const serial_index_t);
public:
inline constexpr bool enabled(const SerialMask PortMask) const { return mask & PortMask.mask; }
inline constexpr SerialMask combine(const SerialMask other) const { return SerialMask(mask | other.mask); }
inline constexpr SerialMask operator<< (const int offset) const { return SerialMask(mask << offset); }
static inline SerialMask from(const serial_index_t index) {
if (index.valid()) return SerialMask(_BV(index.index));
return SerialMask(0); // A invalid index mean no output
}
constexpr SerialMask(const uint8_t mask) : mask(mask) {}
constexpr SerialMask(const SerialMask & other) : mask(other.mask) {} // Can't use = default here since not all framework support this
static constexpr uint8_t All = 0xFF;
};
// The most basic serial class: it dispatch to the base serial class with no hook whatsoever. This will compile to nothing but the base serial class
template <class SerialT>
struct BaseSerial : public SerialBase< BaseSerial<SerialT> >, public SerialT {
@@ -59,9 +35,8 @@ struct BaseSerial : public SerialBase< BaseSerial<SerialT> >, public SerialT {
void msgDone() {}
// We don't care about indices here, since if one can call us, it's the right index anyway
int available(serial_index_t) { return (int)SerialT::available(); }
int read(serial_index_t) { return (int)SerialT::read(); }
bool available(uint8_t index) { return index == 0 && SerialT::available(); }
int read(uint8_t index) { return index == 0 ? SerialT::read() : -1; }
bool connected() { return CALL_IF_EXISTS(bool, static_cast<SerialT*>(this), connected);; }
void flushTX() { CALL_IF_EXISTS(void, static_cast<SerialT*>(this), flushTX); }
@@ -90,18 +65,18 @@ struct ConditionalSerial : public SerialBase< ConditionalSerial<SerialT> > {
bool & condition;
SerialT & out;
NO_INLINE size_t write(uint8_t c) { if (condition) return out.write(c); return 0; }
void flush() { if (condition) out.flush(); }
void begin(long br) { out.begin(br); }
void end() { out.end(); }
void flush() { if (condition) out.flush(); }
void begin(long br) { out.begin(br); }
void end() { out.end(); }
void msgDone() {}
bool connected() { return CALL_IF_EXISTS(bool, &out, connected); }
void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); }
bool connected() { return CALL_IF_EXISTS(bool, &out, connected); }
void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); }
int available(serial_index_t ) { return (int)out.available(); }
int read(serial_index_t ) { return (int)out.read(); }
int available() { return (int)out.available(); }
int read() { return (int)out.read(); }
bool available(uint8_t index) { return index == 0 && out.available(); }
int read(uint8_t index) { return index == 0 ? out.read() : -1; }
using BaseClassT::available;
using BaseClassT::read;
ConditionalSerial(bool & conditionVariable, SerialT & out, const bool e) : BaseClassT(e), condition(conditionVariable), out(out) {}
};
@@ -122,10 +97,10 @@ struct ForwardSerial : public SerialBase< ForwardSerial<SerialT> > {
bool connected() { return Private::HasMember_connected<SerialT>::value ? CALL_IF_EXISTS(bool, &out, connected) : (bool)out; }
void flushTX() { CALL_IF_EXISTS(void, &out, flushTX); }
int available(serial_index_t) { return (int)out.available(); }
int read(serial_index_t) { return (int)out.read(); }
int available() { return (int)out.available(); }
int read() { return (int)out.read(); }
bool available(uint8_t index) { return index == 0 && out.available(); }
int read(uint8_t index) { return index == 0 ? out.read() : -1; }
bool available() { return out.available(); }
int read() { return out.read(); }
ForwardSerial(const bool e, SerialT & out) : BaseClassT(e), out(out) {}
};
@@ -150,8 +125,8 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial<SerialT> >, public Seria
if (eofHook) eofHook(userPointer);
}
int available(serial_index_t) { return (int)SerialT::available(); }
int read(serial_index_t) { return (int)SerialT::read(); }
bool available(uint8_t index) { return index == 0 && SerialT::available(); }
int read(uint8_t index) { return index == 0 ? SerialT::read() : -1; }
using SerialT::available;
using SerialT::read;
using SerialT::flush;
@@ -182,59 +157,60 @@ struct RuntimeSerial : public SerialBase< RuntimeSerial<SerialT> >, public Seria
// Forward constructor
template <typename... Args>
RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...), writeHook(0), eofHook(0), userPointer(0) {}
RuntimeSerial(const bool e, Args... args) : BaseClassT(e), SerialT(args...) {}
};
// A class that duplicates its output conditionally to 2 serial interfaces
template <class Serial0T, class Serial1T, const uint8_t offset = 0, const uint8_t step = 1>
struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset, step> > {
typedef SerialBase< MultiSerial<Serial0T, Serial1T, offset, step> > BaseClassT;
// A class that's duplicating its output conditionally to 2 serial interface
template <class Serial0T, class Serial1T, const uint8_t offset = 0>
struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset> > {
typedef SerialBase< MultiSerial<Serial0T, Serial1T, offset> > BaseClassT;
SerialMask portMask;
uint8_t portMask;
Serial0T & serial0;
Serial1T & serial1;
static constexpr uint8_t Usage = ((1 << step) - 1); // A bit mask containing as many bits as step
static constexpr uint8_t FirstOutput = (Usage << offset);
static constexpr uint8_t SecondOutput = (Usage << (offset + step));
static constexpr uint8_t Both = FirstOutput | SecondOutput;
enum Masks {
FirstOutputMask = (1 << offset),
SecondOutputMask = (1 << (offset + 1)),
AllMask = FirstOutputMask | SecondOutputMask,
};
NO_INLINE size_t write(uint8_t c) {
size_t ret = 0;
if (portMask.enabled(FirstOutput)) ret = serial0.write(c);
if (portMask.enabled(SecondOutput)) ret = serial1.write(c) | ret;
if (portMask & FirstOutputMask) ret = serial0.write(c);
if (portMask & SecondOutputMask) ret = serial1.write(c) | ret;
return ret;
}
NO_INLINE void msgDone() {
if (portMask.enabled(FirstOutput)) serial0.msgDone();
if (portMask.enabled(SecondOutput)) serial1.msgDone();
if (portMask & FirstOutputMask) serial0.msgDone();
if (portMask & SecondOutputMask) serial1.msgDone();
}
int available(serial_index_t index) {
if (index.within(0 + offset, step + offset - 1))
return serial0.available(index);
else if (index.within(step + offset, 2 * step + offset - 1))
return serial1.available(index);
return false;
bool available(uint8_t index) {
switch(index) {
case 0 + offset: return serial0.available();
case 1 + offset: return serial1.available();
default: return false;
}
}
int read(serial_index_t index) {
if (index.within(0 + offset, step + offset - 1))
return serial0.read(index);
else if (index.within(step + offset, 2 * step + offset - 1))
return serial1.read(index);
return -1;
NO_INLINE int read(uint8_t index) {
switch(index) {
case 0 + offset: return serial0.read();
case 1 + offset: return serial1.read();
default: return -1;
}
}
void begin(const long br) {
if (portMask.enabled(FirstOutput)) serial0.begin(br);
if (portMask.enabled(SecondOutput)) serial1.begin(br);
if (portMask & FirstOutputMask) serial0.begin(br);
if (portMask & SecondOutputMask) serial1.begin(br);
}
void end() {
if (portMask.enabled(FirstOutput)) serial0.end();
if (portMask.enabled(SecondOutput)) serial1.end();
if (portMask & FirstOutputMask) serial0.end();
if (portMask & SecondOutputMask) serial1.end();
}
bool connected() {
bool ret = true;
if (portMask.enabled(FirstOutput)) ret = CALL_IF_EXISTS(bool, &serial0, connected);
if (portMask.enabled(SecondOutput)) ret = ret && CALL_IF_EXISTS(bool, &serial1, connected);
if (portMask & FirstOutputMask) ret = CALL_IF_EXISTS(bool, &serial0, connected);
if (portMask & SecondOutputMask) ret = ret && CALL_IF_EXISTS(bool, &serial1, connected);
return ret;
}
@@ -243,22 +219,22 @@ struct MultiSerial : public SerialBase< MultiSerial<Serial0T, Serial1T, offset,
// Redirect flush
NO_INLINE void flush() {
if (portMask.enabled(FirstOutput)) serial0.flush();
if (portMask.enabled(SecondOutput)) serial1.flush();
if (portMask & FirstOutputMask) serial0.flush();
if (portMask & SecondOutputMask) serial1.flush();
}
NO_INLINE void flushTX() {
if (portMask.enabled(FirstOutput)) CALL_IF_EXISTS(void, &serial0, flushTX);
if (portMask.enabled(SecondOutput)) CALL_IF_EXISTS(void, &serial1, flushTX);
if (portMask & FirstOutputMask) CALL_IF_EXISTS(void, &serial0, flushTX);
if (portMask & SecondOutputMask) CALL_IF_EXISTS(void, &serial1, flushTX);
}
MultiSerial(Serial0T & serial0, Serial1T & serial1, const SerialMask mask = Both, const bool e = false) :
MultiSerial(Serial0T & serial0, Serial1T & serial1, int8_t mask = AllMask, const bool e = false) :
BaseClassT(e),
portMask(mask), serial0(serial0), serial1(serial1) {}
};
// Build the actual serial object depending on current configuration
#define Serial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, BaseSerial)
#define ForwardSerial1Class TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial)
#define Serial0Type TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, BaseSerial)
#define ForwardSerial0Type TERN(SERIAL_RUNTIME_HOOK, RuntimeSerial, ForwardSerial)
#ifdef HAS_MULTI_SERIAL
#define Serial2Class ConditionalSerial
#define Serial1Type ConditionalSerial
#endif
+3 -3
View File
@@ -92,9 +92,9 @@ void safe_delay(millis_t ms) {
SERIAL_ECHOPGM(" (Aligned With");
if (probe.offset_xy.y > 0)
SERIAL_ECHOPGM_P(ENABLED(IS_SCARA) ? PSTR("-Distal") : PSTR("-Back"));
serialprintPGM(ENABLED(IS_SCARA) ? PSTR("-Distal") : PSTR("-Back"));
else if (probe.offset_xy.y < 0)
SERIAL_ECHOPGM_P(ENABLED(IS_SCARA) ? PSTR("-Proximal") : PSTR("-Front"));
serialprintPGM(ENABLED(IS_SCARA) ? PSTR("-Proximal") : PSTR("-Front"));
else if (probe.offset_xy.x != 0)
SERIAL_ECHOPGM("-Center");
@@ -102,7 +102,7 @@ void safe_delay(millis_t ms) {
#endif
SERIAL_ECHOPGM_P(probe.offset.z < 0 ? PSTR("Below") : probe.offset.z > 0 ? PSTR("Above") : PSTR("Same Z as"));
serialprintPGM(probe.offset.z < 0 ? PSTR("Below") : probe.offset.z > 0 ? PSTR("Above") : PSTR("Same Z as"));
SERIAL_ECHOLNPGM(" Nozzle)");
#endif
+1 -1
View File
@@ -98,7 +98,7 @@ TemporaryBedLevelingState::TemporaryBedLevelingState(const bool enable) : saved(
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
void set_z_fade_height(const float &zfh, const bool do_report/*=true*/) {
void set_z_fade_height(const float zfh, const bool do_report/*=true*/) {
if (planner.z_fade_height == zfh) return;
+1 -1
View File
@@ -38,7 +38,7 @@ void set_bed_leveling_enabled(const bool enable=true);
void reset_bed_level();
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
void set_z_fade_height(const float &zfh, const bool do_report=true);
void set_z_fade_height(const float zfh, const bool do_report=true);
#endif
#if EITHER(MESH_BED_LEVELING, PROBE_MANUALLY)

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