Compare commits
48 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1bbae4676f | |||
| 6802260626 | |||
| ed34dbb4b6 | |||
| 721209a898 | |||
| 7c6dfc4ec2 | |||
| 62008024cd | |||
| e09672edac | |||
| 825e0b800c | |||
| 0f489c6584 | |||
| 6ae43349f7 | |||
| f6b52a80d6 | |||
| 38711ed5e6 | |||
| 5a714c76b8 | |||
| 8c1a547f2a | |||
| 16be10d2f3 | |||
| d4dde255ad | |||
| b5c7712531 | |||
| 8dc8361f02 | |||
| 433f3ba3ab | |||
| 78e2aa6eac | |||
| 54da1da13f | |||
| 544765f1a1 | |||
| f261fea59a | |||
| 00785eb14e | |||
| 6713185aea | |||
| 298c3f2344 | |||
| 82c1171028 | |||
| 122b01d253 | |||
| 42e4321b6f | |||
| 87faa73bee | |||
| 666e8c0116 | |||
| 5a0332ddee | |||
| f67a0f847f | |||
| 0f1a5a7434 | |||
| 01df7e11dc | |||
| 9200e8c284 | |||
| 0dcfc91c9e | |||
| acf53d6f84 | |||
| da068d5bb1 | |||
| 7f339f7001 | |||
| 7150d0eb5c | |||
| ca18690349 | |||
| 0316242347 | |||
| 6087ab6347 | |||
| a44871b272 | |||
| bef646d52c | |||
| 4d78a91cbd | |||
| 95bafca9d9 |
+110
-98
@@ -61,14 +61,14 @@
|
||||
// @section info
|
||||
|
||||
// Author info of this build printed to the host during boot and M115
|
||||
#define STRING_CONFIG_H_AUTHOR "(none, default config)" // Who made the changes.
|
||||
#define STRING_CONFIG_H_AUTHOR "InsanityAutomation" // Who made the changes.
|
||||
//#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
|
||||
|
||||
// @section machine
|
||||
|
||||
// Choose the name from boards.h that matches your setup
|
||||
#ifndef MOTHERBOARD
|
||||
#define MOTHERBOARD BOARD_RAMPS_14_EFB
|
||||
#define MOTHERBOARD BOARD_EBAB
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@
|
||||
*
|
||||
* :[-1, 0, 1, 2, 3, 4, 5, 6, 7]
|
||||
*/
|
||||
#define SERIAL_PORT 0
|
||||
#define SERIAL_PORT -1
|
||||
|
||||
/**
|
||||
* Serial Port Baud Rate
|
||||
@@ -101,7 +101,7 @@
|
||||
* 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 1
|
||||
//#define BAUDRATE_2 250000 // :[2400, 9600, 19200, 38400, 57600, 115200, 250000, 500000, 1000000] Enable to override BAUDRATE
|
||||
|
||||
/**
|
||||
@@ -116,7 +116,7 @@
|
||||
//#define BLUETOOTH
|
||||
|
||||
// Name displayed in the LCD "Ready" message and Info menu
|
||||
//#define CUSTOM_MACHINE_NAME "3D Printer"
|
||||
#define CUSTOM_MACHINE_NAME "FatBoy"
|
||||
|
||||
// Printer's unique ID, used by some programs to differentiate between machines.
|
||||
// Choose your own or use a service like https://www.uuidgenerator.net/version4
|
||||
@@ -135,25 +135,25 @@
|
||||
* Options: A4988, A5984, DRV8825, LV8729, TB6560, TB6600, TMC2100,
|
||||
* TMC2130, TMC2130_STANDALONE, TMC2160, TMC2160_STANDALONE,
|
||||
* TMC2208, TMC2208_STANDALONE, TMC2209, TMC2209_STANDALONE,
|
||||
* TMC2660, TMC2660_STANDALONE, TMC5130, TMC5130_STANDALONE,
|
||||
* TMC5160, TMC5160_STANDALONE
|
||||
* :['A4988', 'A5984', 'DRV8825', 'LV8729', 'TB6560', 'TB6600', 'TMC2100', 'TMC2130', 'TMC2130_STANDALONE', 'TMC2160', 'TMC2160_STANDALONE', 'TMC2208', 'TMC2208_STANDALONE', 'TMC2209', 'TMC2209_STANDALONE', 'TMC2660', 'TMC2660_STANDALONE', 'TMC5130', 'TMC5130_STANDALONE', 'TMC5160', 'TMC5160_STANDALONE']
|
||||
* TMC26X, TMC26X_STANDALONE, TMC2660, TMC2660_STANDALONE,
|
||||
* TMC5130, TMC5130_STANDALONE, TMC5160, TMC5160_STANDALONE
|
||||
* :['A4988', 'A5984', 'DRV8825', 'LV8729', '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 TMC5160
|
||||
#define Y_DRIVER_TYPE TMC5160
|
||||
#define Z_DRIVER_TYPE TMC5160_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 Y2_DRIVER_TYPE TMC5160
|
||||
#define Z2_DRIVER_TYPE TMC5160_STANDALONE
|
||||
#define Z3_DRIVER_TYPE TMC5160_STANDALONE
|
||||
#define Z4_DRIVER_TYPE TMC5160_STANDALONE
|
||||
//#define I_DRIVER_TYPE A4988
|
||||
//#define J_DRIVER_TYPE A4988
|
||||
//#define K_DRIVER_TYPE A4988
|
||||
//#define U_DRIVER_TYPE A4988
|
||||
//#define V_DRIVER_TYPE A4988
|
||||
//#define W_DRIVER_TYPE A4988
|
||||
#define E0_DRIVER_TYPE A4988
|
||||
#define E0_DRIVER_TYPE TMC2209
|
||||
//#define E1_DRIVER_TYPE A4988
|
||||
//#define E2_DRIVER_TYPE A4988
|
||||
//#define E3_DRIVER_TYPE A4988
|
||||
@@ -399,20 +399,29 @@
|
||||
//#define MKS_PWC // Using the MKS PWC add-on
|
||||
//#define PS_OFF_CONFIRM // Confirm dialog when power off
|
||||
//#define PS_OFF_SOUND // Beep 1s when power off
|
||||
#define PSU_ACTIVE_STATE LOW // Set 'LOW' for ATX, 'HIGH' for X-Box
|
||||
#define PSU_ACTIVE_STATE HIGH // 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 LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay
|
||||
#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
|
||||
#define PSU_POWERUP_DELAY 750 // (ms) Delay for the PSU to warm up to full power
|
||||
//#define LED_POWEROFF_TIMEOUT 10000 // (ms) Turn off LEDs after power-off, with this amount of delay
|
||||
|
||||
//#define PSU_OFF_REDUNDANT // Second pin for redundant power control
|
||||
//#define PSU_OFF_REDUNDANT_INVERTED // Redundant pin state is the inverse of PSU_ACTIVE_STATE
|
||||
#define PSU_OFF_REDUNDANT // Second pin for redundant power control
|
||||
//#define PSU_OFF_REDUNDANT_OPPOSING // Redundant pin works opposite standard pin
|
||||
#define PS_ON_PIN P4_28 // Redundant Pin
|
||||
#define PS_ON1_PIN P1_03 // Redundant Pin
|
||||
|
||||
//#define PS_ON1_PIN 6 // Redundant pin required to enable power in combination with PS_ON_PIN
|
||||
#define PS_ON_EDM_PIN P4_29 // EDM Pins to monitor feedback on external power control relay. Fault on mismatch.
|
||||
#define PS_ON1_EDM_PIN P1_17
|
||||
#define PS_EDM_RESPONSE 1000 // Time in MS to allow for relay action
|
||||
|
||||
//#define PS_ON_EDM_PIN 8 // External Device Monitoring pins for external power control relay feedback. Fault on mismatch.
|
||||
//#define PS_ON1_EDM_PIN 9
|
||||
#define PS_EDM_RESPONSE 250 // (ms) Time to allow for relay action
|
||||
#define PSU_OFF_REDUNDANT // Second pin for redundant power control
|
||||
//#define PSU_OFF_REDUNDANT_OPPOSING // Redundant pin works opposite standard pin
|
||||
#define PS_ON_PIN P4_28 // Redundant Pin
|
||||
#define PS_ON1_PIN P1_03 // Redundant Pin
|
||||
|
||||
#define PS_ON_EDM_PIN P4_29 // EDM Pins to monitor feedback on external power control relay. Fault on mismatch.
|
||||
#define PS_ON1_EDM_PIN P1_17
|
||||
#define PS_EDM_RESPONSE 1000 // Time in MS to allow for relay action
|
||||
|
||||
//#define POWER_OFF_TIMER // Enable M81 D<seconds> to power off after a delay
|
||||
//#define POWER_OFF_WAIT_FOR_COOLDOWN // Enable M81 S to power off only after cooldown
|
||||
@@ -420,7 +429,7 @@
|
||||
//#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 for fans
|
||||
#define AUTO_POWER_E_FANS // Turn on PSU for E Fans
|
||||
@@ -561,7 +570,7 @@
|
||||
#define TEMP_SENSOR_5 0
|
||||
#define TEMP_SENSOR_6 0
|
||||
#define TEMP_SENSOR_7 0
|
||||
#define TEMP_SENSOR_BED 1
|
||||
#define TEMP_SENSOR_BED 11
|
||||
#define TEMP_SENSOR_PROBE 0
|
||||
#define TEMP_SENSOR_CHAMBER 0
|
||||
#define TEMP_SENSOR_COOLER 0
|
||||
@@ -637,7 +646,7 @@
|
||||
// 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 275
|
||||
#define HEATER_0_MAXTEMP 300
|
||||
#define HEATER_1_MAXTEMP 275
|
||||
#define HEATER_2_MAXTEMP 275
|
||||
#define HEATER_3_MAXTEMP 275
|
||||
@@ -645,7 +654,7 @@
|
||||
#define HEATER_5_MAXTEMP 275
|
||||
#define HEATER_6_MAXTEMP 275
|
||||
#define HEATER_7_MAXTEMP 275
|
||||
#define BED_MAXTEMP 150
|
||||
#define BED_MAXTEMP 120
|
||||
#define CHAMBER_MAXTEMP 60
|
||||
|
||||
/**
|
||||
@@ -654,7 +663,7 @@
|
||||
* (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 HOTEND_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
|
||||
#define BED_OVERSHOOT 10 // (°C) Forbid temperatures over MAXTEMP - OVERSHOOT
|
||||
#define COOLER_OVERSHOOT 2 // (°C) Forbid temperatures closer than OVERSHOOT
|
||||
|
||||
@@ -672,7 +681,7 @@
|
||||
* MPCTEMP : Predictive Model temperature control. (~1.8K without auto-tune)
|
||||
*/
|
||||
#define PIDTEMP // See the PID Tuning Guide at https://reprap.org/wiki/PID_Tuning
|
||||
//#define MPCTEMP // See https://marlinfw.org/docs/features/model_predictive_control.html
|
||||
//#define MPCTEMP // ** EXPERIMENTAL ** See https://marlinfw.org/docs/features/model_predictive_control.html
|
||||
|
||||
#define PID_MAX 255 // Limit hotend current while PID is active (see PID_FUNCTIONAL_RANGE below); 255=full current
|
||||
#define PID_K1 0.95 // Smoothing factor within any PID loop
|
||||
@@ -757,7 +766,7 @@
|
||||
* When set to any value below 255, enables a form of PWM to the bed that acts like a divider
|
||||
* so don't use it unless you are OK with PWM on your bed. (See the comment on enabling PIDTEMPBED)
|
||||
*/
|
||||
#define MAX_BED_POWER 255 // limits duty cycle to bed; 255=full current
|
||||
#define MAX_BED_POWER 180 // limits duty cycle to bed; 255=full current
|
||||
|
||||
/**
|
||||
* PID Bed Heating
|
||||
@@ -771,7 +780,7 @@
|
||||
*
|
||||
* With this option disabled, bang-bang will be used. BED_LIMIT_SWITCHING enables hysteresis.
|
||||
*/
|
||||
//#define PIDTEMPBED
|
||||
#define PIDTEMPBED
|
||||
|
||||
#if ENABLED(PIDTEMPBED)
|
||||
//#define MIN_BED_POWER 0
|
||||
@@ -842,8 +851,8 @@
|
||||
#define PID_FUNCTIONAL_RANGE 10 // If the temperature difference between the target temperature and the actual temperature
|
||||
// is more than PID_FUNCTIONAL_RANGE then the PID will be shut off and the heater will be set to min/max.
|
||||
|
||||
//#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash)
|
||||
//#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
|
||||
#define PID_EDIT_MENU // Add PID editing to the "Advanced Settings" menu. (~700 bytes of flash)
|
||||
#define PID_AUTOTUNE_MENU // Add PID auto-tuning to the "Advanced Settings" menu. (~250 bytes of flash)
|
||||
#endif
|
||||
|
||||
// @section safety
|
||||
@@ -1015,6 +1024,9 @@
|
||||
// Radius around the center where the arm cannot reach
|
||||
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
|
||||
|
||||
#define THETA_HOMING_OFFSET 0 // Calculated from Calibration Guide and M360 / M114. See https://www.morgan3dp.com/morgan-calibration-guide/
|
||||
#define PSI_HOMING_OFFSET 0 // Calculated from Calibration Guide and M364 / M114. See https://www.morgan3dp.com/morgan-calibration-guide/
|
||||
|
||||
#elif ENABLED(MP_SCARA)
|
||||
|
||||
#define SCARA_OFFSET_THETA1 12 // degrees
|
||||
@@ -1033,19 +1045,23 @@
|
||||
#define DEFAULT_SEGMENTS_PER_SECOND 200
|
||||
|
||||
// Length of inner and outer support arms. Measure arm lengths precisely.
|
||||
#define TPARA_LINKAGE_1 120 // (mm)
|
||||
#define TPARA_LINKAGE_2 120 // (mm)
|
||||
#define TPARA_LINKAGE_1 120 // (mm)
|
||||
#define TPARA_LINKAGE_2 120 // (mm)
|
||||
|
||||
// TPARA tower offset (position of Tower relative to bed zero position)
|
||||
// This needs to be reasonably accurate as it defines the printbed position in the TPARA space.
|
||||
#define TPARA_OFFSET_X 0 // (mm)
|
||||
#define TPARA_OFFSET_Y 0 // (mm)
|
||||
#define TPARA_OFFSET_Z 0 // (mm)
|
||||
// SCARA tower offset (position of Tower relative to bed zero position)
|
||||
// This needs to be reasonably accurate as it defines the printbed position in the SCARA space.
|
||||
#define TPARA_OFFSET_X 0 // (mm)
|
||||
#define TPARA_OFFSET_Y 0 // (mm)
|
||||
#define TPARA_OFFSET_Z 0 // (mm)
|
||||
|
||||
#define FEEDRATE_SCALING // Convert XY feedrate from mm/s to degrees/s on the fly
|
||||
|
||||
// Radius around the center where the arm cannot reach
|
||||
#define MIDDLE_DEAD_ZONE_R 0 // (mm)
|
||||
|
||||
// Calculated from Calibration Guide and M360 / M114. See https://www.morgan3dp.com/morgan-calibration-guide/
|
||||
#define THETA_HOMING_OFFSET 0
|
||||
#define PSI_HOMING_OFFSET 0
|
||||
#endif
|
||||
|
||||
// @section polar
|
||||
@@ -1170,9 +1186,9 @@
|
||||
* Endstop "Hit" State
|
||||
* Set to the state (HIGH or LOW) that applies to each endstop.
|
||||
*/
|
||||
#define X_MIN_ENDSTOP_HIT_STATE HIGH
|
||||
#define X_MIN_ENDSTOP_HIT_STATE LOW
|
||||
#define X_MAX_ENDSTOP_HIT_STATE HIGH
|
||||
#define Y_MIN_ENDSTOP_HIT_STATE HIGH
|
||||
#define Y_MIN_ENDSTOP_HIT_STATE LOW
|
||||
#define Y_MAX_ENDSTOP_HIT_STATE HIGH
|
||||
#define Z_MIN_ENDSTOP_HIT_STATE HIGH
|
||||
#define Z_MAX_ENDSTOP_HIT_STATE HIGH
|
||||
@@ -1236,7 +1252,7 @@
|
||||
* Override with M92 (when enabled below)
|
||||
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
|
||||
*/
|
||||
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80, 80, 400, 500 }
|
||||
#define DEFAULT_AXIS_STEPS_PER_UNIT { 40, 40, 200, 425 }
|
||||
|
||||
/**
|
||||
* Enable support for M92. Disable to save at least ~530 bytes of flash.
|
||||
@@ -1261,7 +1277,7 @@
|
||||
* Override with M201
|
||||
* X, Y, Z [, I [, J [, K...]]], E0 [, E1[, E2...]]
|
||||
*/
|
||||
#define DEFAULT_MAX_ACCELERATION { 3000, 3000, 100, 10000 }
|
||||
#define DEFAULT_MAX_ACCELERATION { 12000, 12000, 500, 10000 }
|
||||
|
||||
//#define LIMITED_MAX_ACCEL_EDITING // Limit edit via M201 or LCD to DEFAULT_MAX_ACCELERATION * 2
|
||||
#if ENABLED(LIMITED_MAX_ACCEL_EDITING)
|
||||
@@ -1276,9 +1292,9 @@
|
||||
* M204 R Retract Acceleration
|
||||
* M204 T Travel Acceleration
|
||||
*/
|
||||
#define DEFAULT_ACCELERATION 3000 // X, Y, Z and E acceleration for printing moves
|
||||
#define DEFAULT_ACCELERATION 7000 // 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_TRAVEL_ACCELERATION 7000 // X, Y, Z acceleration for travel (non printing) moves
|
||||
|
||||
/**
|
||||
* Default Jerk limits (mm/s)
|
||||
@@ -1293,7 +1309,6 @@
|
||||
#define DEFAULT_XJERK 10.0
|
||||
#define DEFAULT_YJERK 10.0
|
||||
#define DEFAULT_ZJERK 0.3
|
||||
#define DEFAULT_EJERK 5.0
|
||||
//#define DEFAULT_IJERK 0.3
|
||||
//#define DEFAULT_JJERK 0.3
|
||||
//#define DEFAULT_KJERK 0.3
|
||||
@@ -1309,6 +1324,8 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define DEFAULT_EJERK 5.0 // May be used by Linear Advance
|
||||
|
||||
/**
|
||||
* Junction Deviation Factor
|
||||
*
|
||||
@@ -1330,7 +1347,12 @@
|
||||
*
|
||||
* See https://github.com/synthetos/TinyG/wiki/Jerk-Controlled-Motion-Explained
|
||||
*/
|
||||
//#define S_CURVE_ACCELERATION
|
||||
#define S_CURVE_ACCELERATION
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
// Uncomment to use 4th instead of 6th order motion curve
|
||||
#define S_CURVE_FACTOR 0.35 // Initial and final acceleration factor, ideally 0.1 to 0.4
|
||||
// Shouldn't generally require tuning
|
||||
#endif
|
||||
|
||||
//===========================================================================
|
||||
//============================= Z Probe Options =============================
|
||||
@@ -1346,10 +1368,10 @@
|
||||
* The probe replaces the Z-MIN endstop and is used for Z homing.
|
||||
* (Automatically enables USE_PROBE_FOR_Z_HOMING.)
|
||||
*/
|
||||
#define Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN
|
||||
//#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
|
||||
@@ -1406,7 +1428,7 @@
|
||||
/**
|
||||
* The BLTouch probe uses a Hall effect sensor and emulates a servo.
|
||||
*/
|
||||
//#define BLTOUCH
|
||||
#define BLTOUCH
|
||||
|
||||
/**
|
||||
* MagLev V4 probe by MDD
|
||||
@@ -1448,17 +1470,6 @@
|
||||
//#define BD_SENSOR_PROBE_NO_STOP // Probe bed without stopping at each probe point
|
||||
#endif
|
||||
|
||||
/**
|
||||
* BIQU MicroProbe
|
||||
*
|
||||
* A lightweight, solenoid-driven probe.
|
||||
* For information about this sensor https://github.com/bigtreetech/MicroProbe
|
||||
*
|
||||
* Also requires: PROBE_ENABLE_DISABLE
|
||||
*/
|
||||
//#define BIQU_MICROPROBE_V1 // Triggers HIGH
|
||||
//#define BIQU_MICROPROBE_V2 // Triggers LOW
|
||||
|
||||
// A probe that is deployed and stowed with a solenoid pin (SOL1_PIN)
|
||||
//#define SOLENOID_PROBE
|
||||
|
||||
@@ -1647,7 +1658,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
|
||||
|
||||
/**
|
||||
@@ -1670,7 +1681,7 @@
|
||||
#define Z_PROBE_ERROR_TOLERANCE 3 // (mm) Tolerance for early trigger (<= -probe.offset.z + ZPET)
|
||||
//#define Z_AFTER_PROBING 5 // (mm) Z position after probing is done
|
||||
|
||||
#define Z_PROBE_LOW_POINT -2 // (mm) Farthest distance below the trigger-point to go before stopping
|
||||
#define Z_PROBE_LOW_POINT -5 // (mm) Farthest distance below the trigger-point to go before stopping
|
||||
|
||||
// For M851 provide ranges for adjusting the X, Y, and Z probe offsets
|
||||
//#define PROBE_OFFSET_XMIN -50 // (mm)
|
||||
@@ -1749,9 +1760,9 @@
|
||||
// @section motion
|
||||
|
||||
// Invert the stepper direction. Change (or reverse the motor connector) if an axis goes the wrong way.
|
||||
#define INVERT_X_DIR false
|
||||
#define INVERT_Y_DIR true
|
||||
#define INVERT_Z_DIR false
|
||||
#define INVERT_X_DIR true
|
||||
#define INVERT_Y_DIR false
|
||||
#define INVERT_Z_DIR true
|
||||
//#define INVERT_I_DIR false
|
||||
//#define INVERT_J_DIR false
|
||||
//#define INVERT_K_DIR false
|
||||
@@ -1821,8 +1832,8 @@
|
||||
// @section geometry
|
||||
|
||||
// The size of the printable area
|
||||
#define X_BED_SIZE 200
|
||||
#define Y_BED_SIZE 200
|
||||
#define X_BED_SIZE 1200
|
||||
#define Y_BED_SIZE 1200
|
||||
|
||||
// Travel limits (linear=mm, rotational=°) after homing, corresponding to endstop positions.
|
||||
#define X_MIN_POS 0
|
||||
@@ -1830,7 +1841,7 @@
|
||||
#define Z_MIN_POS 0
|
||||
#define X_MAX_POS X_BED_SIZE
|
||||
#define Y_MAX_POS Y_BED_SIZE
|
||||
#define Z_MAX_POS 200
|
||||
#define Z_MAX_POS 1000
|
||||
//#define I_MIN_POS 0
|
||||
//#define I_MAX_POS 50
|
||||
//#define J_MIN_POS 0
|
||||
@@ -1882,7 +1893,7 @@
|
||||
#endif
|
||||
|
||||
#if ANY(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
|
||||
|
||||
/**
|
||||
@@ -2041,7 +2052,7 @@
|
||||
*/
|
||||
//#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
|
||||
|
||||
@@ -2049,14 +2060,14 @@
|
||||
* Commands to execute at the end of G29 probing.
|
||||
* Useful to retract or move the Z probe out of the way.
|
||||
*/
|
||||
//#define EVENT_GCODE_AFTER_G29 "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10"
|
||||
//#define Z_PROBE_END_SCRIPT "G1 Z10 F12000\nG1 X15 Y330\nG1 Z0.5\nG1 Z10"
|
||||
|
||||
/**
|
||||
* Normally G28 leaves leveling disabled on completion. Enable one of
|
||||
* these options to restore the prior leveling state or to always enable
|
||||
* leveling immediately after G28.
|
||||
*/
|
||||
//#define RESTORE_LEVELING_AFTER_G28
|
||||
#define RESTORE_LEVELING_AFTER_G28
|
||||
//#define ENABLE_LEVELING_AFTER_G28
|
||||
|
||||
/**
|
||||
@@ -2071,7 +2082,7 @@
|
||||
/**
|
||||
* Enable detailed logging of G28, G29, M48, etc.
|
||||
* Turn on with the command 'M111 S32'.
|
||||
* NOTE: Requires a lot of flash!
|
||||
* NOTE: Requires a lot of PROGMEM!
|
||||
*/
|
||||
//#define DEBUG_LEVELING_FEATURE
|
||||
|
||||
@@ -2088,7 +2099,7 @@
|
||||
*/
|
||||
#define ENABLE_LEVELING_FADE_HEIGHT
|
||||
#if ENABLED(ENABLE_LEVELING_FADE_HEIGHT)
|
||||
#define DEFAULT_LEVELING_FADE_HEIGHT 10.0 // (mm) Default fade height.
|
||||
#define DEFAULT_LEVELING_FADE_HEIGHT 0.0 // (mm) Default fade height.
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -2102,7 +2113,7 @@
|
||||
/**
|
||||
* Enable the G26 Mesh Validation Pattern tool.
|
||||
*/
|
||||
//#define G26_MESH_VALIDATION
|
||||
#define G26_MESH_VALIDATION
|
||||
#if ENABLED(G26_MESH_VALIDATION)
|
||||
#define MESH_TEST_NOZZLE_SIZE 0.4 // (mm) Diameter of primary nozzle.
|
||||
#define MESH_TEST_LAYER_HEIGHT 0.2 // (mm) Default layer height for G26.
|
||||
@@ -2118,7 +2129,7 @@
|
||||
#if ANY(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 15
|
||||
#define GRID_MAX_POINTS_Y GRID_MAX_POINTS_X
|
||||
|
||||
// Probe along the Y axis, advancing X after each column
|
||||
@@ -2128,7 +2139,7 @@
|
||||
|
||||
// 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
|
||||
|
||||
//
|
||||
// Subdivision of the grid by Catmull-Rom method.
|
||||
@@ -2204,12 +2215,12 @@
|
||||
* 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 LCD_PROBE_Z_RANGE 8 // (mm) Z Range centered on Z_MIN_POS for LCD Z adjustment
|
||||
#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
|
||||
@@ -2218,7 +2229,7 @@
|
||||
#if ENABLED(LCD_BED_TRAMMING)
|
||||
#define BED_TRAMMING_INSET_LFRB { 30, 30, 30, 30 } // (mm) Left, Front, Right, Back insets
|
||||
#define BED_TRAMMING_HEIGHT 0.0 // (mm) Z height of nozzle at tramming points
|
||||
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z raise between tramming points
|
||||
#define BED_TRAMMING_Z_HOP 4.0 // (mm) Z height of nozzle between tramming points
|
||||
//#define BED_TRAMMING_INCLUDE_CENTER // Move to the center after the last corner
|
||||
//#define BED_TRAMMING_USE_PROBE
|
||||
#if ENABLED(BED_TRAMMING_USE_PROBE)
|
||||
@@ -2271,7 +2282,7 @@
|
||||
* - Allows Z homing only when XY positions are known and trusted.
|
||||
* - If stepper drivers sleep, XY homing may be required again before Z homing.
|
||||
*/
|
||||
//#define Z_SAFE_HOMING
|
||||
#define Z_SAFE_HOMING
|
||||
|
||||
#if ENABLED(Z_SAFE_HOMING)
|
||||
#define Z_SAFE_HOMING_X_POINT X_CENTER // (mm) X point for Z homing
|
||||
@@ -2358,12 +2369,12 @@
|
||||
* M501 - Read settings from EEPROM. (i.e., Throw away unsaved changes)
|
||||
* M502 - Revert settings to "factory" defaults. (Follow with M500 to init the EEPROM.)
|
||||
*/
|
||||
//#define EEPROM_SETTINGS // Persistent storage with M500 and M501
|
||||
#define EEPROM_SETTINGS // Persistent storage with M500 and M501
|
||||
//#define DISABLE_M503 // Saves ~2700 bytes of flash. Disable for release!
|
||||
#define EEPROM_CHITCHAT // Give feedback on EEPROM commands. Disable to save flash.
|
||||
#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.
|
||||
#define EEPROM_AUTO_INIT // Init EEPROM automatically on any errors.
|
||||
//#define EEPROM_INIT_NOW // Init EEPROM on first boot after a new build.
|
||||
#endif
|
||||
|
||||
@@ -2421,11 +2432,11 @@
|
||||
* P1 Raise the nozzle always to Z-park height.
|
||||
* P2 Raise the nozzle by Z-park amount, limited to Z_MAX_POS.
|
||||
*/
|
||||
//#define NOZZLE_PARK_FEATURE
|
||||
#define NOZZLE_PARK_FEATURE
|
||||
|
||||
#if ENABLED(NOZZLE_PARK_FEATURE)
|
||||
// Specify a park position as { X, Y, Z_raise }
|
||||
#define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MAX_POS - 10), 20 }
|
||||
#define NOZZLE_PARK_POINT { (X_MIN_POS + 10), (Y_MIN_POS + 10), 5 }
|
||||
#define NOZZLE_PARK_MOVE 0 // Park motion: 0 = XY Move, 1 = X Only, 2 = Y Only, 3 = X before Y, 4 = Y before X
|
||||
#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)
|
||||
@@ -2636,9 +2647,9 @@
|
||||
#define DISPLAY_CHARSET_HD44780 JAPANESE
|
||||
|
||||
/**
|
||||
* Info Screen Style (0:Classic, 1:Průša, 2:CNC)
|
||||
* Info Screen Style (0:Classic, 1:Průša)
|
||||
*
|
||||
* :[0:'Classic', 1:'Průša', 2:'CNC']
|
||||
* :[0:'Classic', 1:'Průša']
|
||||
*/
|
||||
#define LCD_INFO_SCREEN_STYLE 0
|
||||
|
||||
@@ -2648,7 +2659,7 @@
|
||||
* SD Card support is disabled by default. If your controller has an SD slot,
|
||||
* you must uncomment the following option or it won't work.
|
||||
*/
|
||||
//#define SDSUPPORT
|
||||
#define SDSUPPORT
|
||||
|
||||
/**
|
||||
* SD CARD: ENABLE CRC
|
||||
@@ -2728,7 +2739,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
|
||||
//#define INDIVIDUAL_AXIS_HOMING_SUBMENU
|
||||
|
||||
//
|
||||
@@ -2931,7 +2942,7 @@
|
||||
// RepRapDiscount FULL GRAPHIC Smart Controller
|
||||
// https://reprap.org/wiki/RepRapDiscount_Full_Graphic_Smart_Controller
|
||||
//
|
||||
//#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
|
||||
#define REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER
|
||||
|
||||
//
|
||||
// K.3D Full Graphic Smart Controller
|
||||
@@ -3039,7 +3050,7 @@
|
||||
|
||||
//
|
||||
// Factory display for Creality CR-10 / CR-7 / Ender-3
|
||||
// https://marlinfw.org/docs/hardware/controllers.html#cr10_stockdisplay
|
||||
// https://www.aliexpress.com/item/32833148327.html
|
||||
//
|
||||
// Connect to EXP1 on RAMPS and compatible boards.
|
||||
//
|
||||
@@ -3416,6 +3427,7 @@
|
||||
#define BUTTON_DELAY_MENU 250 // (ms) Button repeat delay for menus
|
||||
|
||||
//#define DISABLE_ENCODER // Disable the click encoder, if any
|
||||
//#define TOUCH_IDLE_SLEEP_MINS 5 // (minutes) Display Sleep after a period of inactivity. Set with M255 S.
|
||||
|
||||
#define TOUCH_SCREEN_CALIBRATION
|
||||
|
||||
|
||||
+112
-116
@@ -307,11 +307,11 @@
|
||||
#define THERMAL_PROTECTION_PERIOD 40 // (seconds)
|
||||
#define THERMAL_PROTECTION_HYSTERESIS 4 // (°C)
|
||||
|
||||
//#define ADAPTIVE_FAN_SLOWING // Slow down the part-cooling fan if the temperature drops
|
||||
#define ADAPTIVE_FAN_SLOWING // Slow down the part-cooling fan if the temperature drops
|
||||
#if ENABLED(ADAPTIVE_FAN_SLOWING)
|
||||
//#define REPORT_ADAPTIVE_FAN_SLOWING // Report fan slowing activity to the console
|
||||
#if ANY(MPCTEMP, PIDTEMP)
|
||||
//#define TEMP_TUNING_MAINTAIN_FAN // Don't slow down the fan speed during M303 or M306 T
|
||||
#define TEMP_TUNING_MAINTAIN_FAN // Don't slow down the fan speed during M303 or M306 T
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -335,7 +335,7 @@
|
||||
* Thermal Protection parameters for the bed are just as above for hotends.
|
||||
*/
|
||||
#if ENABLED(THERMAL_PROTECTION_BED)
|
||||
#define THERMAL_PROTECTION_BED_PERIOD 20 // (seconds)
|
||||
#define THERMAL_PROTECTION_BED_PERIOD 90 // (seconds)
|
||||
#define THERMAL_PROTECTION_BED_HYSTERESIS 2 // (°C)
|
||||
|
||||
/**
|
||||
@@ -459,7 +459,7 @@
|
||||
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
|
||||
|
||||
#else
|
||||
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power-loss due to cooling = Kf * (fan_speed)
|
||||
#define PID_FAN_SCALING_LIN_FACTOR (0) // Power loss due to cooling = Kf * (fan_speed)
|
||||
#define DEFAULT_Kf 10 // A constant value added to the PID-tuner
|
||||
#define PID_FAN_SCALING_MIN_SPEED 10 // Minimum fan speed at which to enable PID_FAN_SCALING
|
||||
#endif
|
||||
@@ -547,10 +547,10 @@
|
||||
* Hotend Idle Timeout
|
||||
* Prevent filament in the nozzle from charring and causing a critical jam.
|
||||
*/
|
||||
//#define HOTEND_IDLE_TIMEOUT
|
||||
#define HOTEND_IDLE_TIMEOUT
|
||||
#if ENABLED(HOTEND_IDLE_TIMEOUT)
|
||||
#define HOTEND_IDLE_TIMEOUT_SEC (5*60) // (seconds) Time without extruder movement to trigger protection
|
||||
#define HOTEND_IDLE_MIN_TRIGGER 180 // (°C) Minimum temperature to enable hotend protection
|
||||
#define HOTEND_IDLE_TIMEOUT_SEC (30*60) // (seconds) Time without extruder movement to trigger protection
|
||||
#define HOTEND_IDLE_MIN_TRIGGER 170 // (°C) Minimum temperature to enable hotend protection
|
||||
#define HOTEND_IDLE_NOZZLE_TARGET 0 // (°C) Safe temperature for the nozzle after timeout
|
||||
#define HOTEND_IDLE_BED_TARGET 0 // (°C) Safe temperature for the bed after timeout
|
||||
#endif
|
||||
@@ -602,8 +602,8 @@
|
||||
* gets it spinning reliably for a short time before setting the requested speed.
|
||||
* (Does not work on Sanguinololu with FAN_SOFT_PWM.)
|
||||
*/
|
||||
//#define FAN_KICKSTART_TIME 100 // (ms)
|
||||
//#define FAN_KICKSTART_POWER 180 // 64-255
|
||||
#define FAN_KICKSTART_TIME 100 // (ms)
|
||||
#define FAN_KICKSTART_POWER 180 // 64-255
|
||||
|
||||
// Some coolers may require a non-zero "off" state.
|
||||
//#define FAN_OFF_PWM 1
|
||||
@@ -931,7 +931,7 @@
|
||||
//#define HOMING_BACKOFF_POST_MM { 2, 2, 2 } // (linear=mm, rotational=°) Backoff from endstops after homing
|
||||
//#define XY_COUNTERPART_BACKOFF_MM 0 // (mm) Backoff X after homing Y, and vice-versa
|
||||
|
||||
//#define QUICK_HOME // If G28 contains XY do a diagonal move first
|
||||
#define QUICK_HOME // If G28 contains XY do a diagonal move first
|
||||
//#define HOME_Y_BEFORE_X // If G28 contains XY home Y before X
|
||||
//#define HOME_Z_FIRST // Home Z first. Requires a real endstop (not a probe).
|
||||
//#define CODEPENDENT_XY_HOMING // If X/Y can't home without homing Y/X first
|
||||
@@ -1020,7 +1020,7 @@
|
||||
* Z Steppers Auto-Alignment
|
||||
* Add the G34 command to align multiple Z steppers using a bed probe.
|
||||
*/
|
||||
//#define Z_STEPPER_AUTO_ALIGN
|
||||
#define Z_STEPPER_AUTO_ALIGN
|
||||
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
|
||||
/**
|
||||
* Define probe X and Y positions for Z1, Z2 [, Z3 [, Z4]]
|
||||
@@ -1185,32 +1185,33 @@
|
||||
* Zero Vibration (ZV) Input Shaping for X and/or Y movements.
|
||||
*
|
||||
* This option uses a lot of SRAM for the step buffer. The buffer size is
|
||||
* calculated automatically from SHAPING_FREQ_[XYZ], DEFAULT_AXIS_STEPS_PER_UNIT,
|
||||
* calculated automatically from SHAPING_FREQ_[XY], DEFAULT_AXIS_STEPS_PER_UNIT,
|
||||
* DEFAULT_MAX_FEEDRATE and ADAPTIVE_STEP_SMOOTHING. The default calculation can
|
||||
* be overridden by setting SHAPING_MIN_FREQ and/or SHAPING_MAX_FEEDRATE.
|
||||
* The higher the frequency and the lower the feedrate, the smaller the buffer.
|
||||
* If the buffer is too small at runtime, input shaping will have reduced
|
||||
* effectiveness during high speed movements.
|
||||
*
|
||||
* Tune with M593 D<factor> F<frequency>
|
||||
* Tune with M593 D<factor> F<frequency>:
|
||||
*
|
||||
* D<factor> Set the zeta/damping factor. If axes (X, Y, etc.) are not specified, set for all axes.
|
||||
* F<frequency> Set the frequency. If axes (X, Y, etc.) are not specified, set for all axes.
|
||||
* T[map] Input Shaping type, 0:ZV, 1:EI, 2:2H EI (not implemented yet)
|
||||
* X<1> Set the given parameters only for the X axis.
|
||||
* Y<1> Set the given parameters only for the Y axis.
|
||||
*/
|
||||
//#define INPUT_SHAPING_X
|
||||
//#define INPUT_SHAPING_Y
|
||||
//#define INPUT_SHAPING_Z
|
||||
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y, INPUT_SHAPING_Z)
|
||||
#if ANY(INPUT_SHAPING_X, INPUT_SHAPING_Y)
|
||||
#if ENABLED(INPUT_SHAPING_X)
|
||||
#define SHAPING_FREQ_X 40.0 // (Hz) The default dominant resonant frequency on the X axis.
|
||||
#define SHAPING_ZETA_X 0.15 // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#define SHAPING_FREQ_X 40 // (Hz) The default dominant resonant frequency on the X axis.
|
||||
#define SHAPING_ZETA_X 0.15f // Damping ratio of the X axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Y)
|
||||
#define SHAPING_FREQ_Y 40.0 // (Hz) The default dominant resonant frequency on the Y axis.
|
||||
#define SHAPING_ZETA_Y 0.15 // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#define SHAPING_FREQ_Y 40 // (Hz) The default dominant resonant frequency on the Y axis.
|
||||
#define SHAPING_ZETA_Y 0.15f // Damping ratio of the Y axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#endif
|
||||
#if ENABLED(INPUT_SHAPING_Z)
|
||||
#define SHAPING_FREQ_Z 40.0 // (Hz) The default dominant resonant frequency on the Z axis.
|
||||
#define SHAPING_ZETA_Z 0.15 // Damping ratio of the Z axis (range: 0.0 = no damping to 1.0 = critical damping).
|
||||
#endif
|
||||
//#define SHAPING_MIN_FREQ 20.0 // (Hz) By default the minimum of the shaping frequencies. Override to affect SRAM usage.
|
||||
//#define SHAPING_MIN_FREQ 20 // By default the minimum of the shaping frequencies. Override to affect SRAM usage.
|
||||
//#define SHAPING_MAX_STEPRATE 10000 // By default the maximum total step rate of the shaped axes. Override to affect SRAM usage.
|
||||
//#define SHAPING_MENU // Add a menu to the LCD to set shaping parameters.
|
||||
#endif
|
||||
@@ -1269,18 +1270,18 @@
|
||||
* XY Frequency limit
|
||||
* Reduce resonance by limiting the frequency of small zigzag infill moves.
|
||||
* See https://hydraraptor.blogspot.com/2010/12/frequency-limit.html
|
||||
* Use M201 F<freq> S<min%> to change limits at runtime.
|
||||
* Use M201 F<freq> G<min%> to change limits at runtime.
|
||||
*/
|
||||
//#define XY_FREQUENCY_LIMIT 10 // (Hz) Maximum frequency of small zigzag infill moves. Set with M201 F<hertz>.
|
||||
#ifdef XY_FREQUENCY_LIMIT
|
||||
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 S<min%>.
|
||||
#define XY_FREQUENCY_MIN_PERCENT 5 // (%) Minimum FR percentage to apply. Set with M201 G<min%>.
|
||||
#endif
|
||||
|
||||
//
|
||||
// Backlash Compensation
|
||||
// Adds extra movement to axes on direction-changes to account for backlash.
|
||||
//
|
||||
//#define BACKLASH_COMPENSATION
|
||||
#define BACKLASH_COMPENSATION
|
||||
#if ENABLED(BACKLASH_COMPENSATION)
|
||||
// Define values for backlash distance and correction.
|
||||
// If BACKLASH_GCODE is enabled these values are the defaults.
|
||||
@@ -1295,7 +1296,7 @@
|
||||
//#define BACKLASH_SMOOTHING_MM 3 // (mm)
|
||||
|
||||
// Add runtime configuration and tuning of backlash values (M425)
|
||||
//#define BACKLASH_GCODE
|
||||
#define BACKLASH_GCODE
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
// Measure the Z backlash when probing (G29) and set with "M425 Z"
|
||||
@@ -1341,7 +1342,7 @@
|
||||
#define CALIBRATION_NOZZLE_TIP_HEIGHT 1.0 // mm
|
||||
#define CALIBRATION_NOZZLE_OUTER_DIAMETER 2.0 // mm
|
||||
|
||||
// Uncomment to enable reporting (required for "G425 V", but consumes flash).
|
||||
// Uncomment to enable reporting (required for "G425 V", but consumes PROGMEM).
|
||||
//#define CALIBRATION_REPORTING
|
||||
|
||||
// The true location and dimension the cube/bolt/washer on the bed.
|
||||
@@ -1385,7 +1386,7 @@
|
||||
* Multi-stepping sends steps in bursts to reduce MCU usage for high step-rates.
|
||||
* This allows higher feedrates than the MCU could otherwise support.
|
||||
*/
|
||||
#define MULTISTEPPING_LIMIT 16 //: [1, 2, 4, 8, 16, 32, 64, 128]
|
||||
#define MULTISTEPPING_LIMIT 32 //: [1, 2, 4, 8, 16, 32, 64, 128]
|
||||
|
||||
/**
|
||||
* Adaptive Step Smoothing increases the resolution of multi-axis moves, particularly at step frequencies
|
||||
@@ -1393,7 +1394,7 @@
|
||||
* vibration and surface artifacts. The algorithm adapts to provide the best possible step smoothing at the
|
||||
* lowest stepping frequencies.
|
||||
*/
|
||||
//#define ADAPTIVE_STEP_SMOOTHING
|
||||
#define ADAPTIVE_STEP_SMOOTHING
|
||||
|
||||
/**
|
||||
* Custom Microstepping
|
||||
@@ -1473,7 +1474,6 @@
|
||||
#if IS_ULTIPANEL
|
||||
#define MANUAL_E_MOVES_RELATIVE // Display extruder move distance rather than "position"
|
||||
#define ULTIPANEL_FEEDMULTIPLY // Encoder sets the feedrate multiplier on the Status Screen
|
||||
//#define ULTIPANEL_FLOWPERCENT // Encoder sets the flow percentage on the Status Screen
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1528,7 +1528,7 @@
|
||||
#endif
|
||||
|
||||
// Include a page of printer information in the LCD Main Menu
|
||||
//#define LCD_INFO_MENU
|
||||
#define LCD_INFO_MENU
|
||||
#if ENABLED(LCD_INFO_MENU)
|
||||
//#define LCD_PRINTER_INFO_IS_BOOTSCREEN // Show bootscreen(s) instead of Printer Info pages
|
||||
#endif
|
||||
@@ -1539,7 +1539,6 @@
|
||||
* Axis moves <= 1/2 the axis length and Extruder moves <= EXTRUDE_MAXLENGTH
|
||||
* will be shown in the move submenus.
|
||||
*/
|
||||
|
||||
#define MANUAL_MOVE_DISTANCE_MM 10, 1.0, 0.1 // (mm)
|
||||
//#define MANUAL_MOVE_DISTANCE_MM 100, 50, 10, 1.0, 0.1 // (mm)
|
||||
//#define MANUAL_MOVE_DISTANCE_MM 500, 100, 50, 10, 1.0, 0.1 // (mm)
|
||||
@@ -1581,9 +1580,9 @@
|
||||
#define BOOT_MARLIN_LOGO_SMALL // Show a smaller Marlin logo on the Boot Screen (saving lots of flash)
|
||||
#endif
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
//#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
|
||||
#define BOOT_MARLIN_LOGO_ANIMATED // Animated Marlin logo. Costs ~3260 (or ~940) bytes of flash.
|
||||
#endif
|
||||
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE, HAS_MARLINUI_HD44780)
|
||||
#if ANY(HAS_MARLINUI_U8GLIB, TOUCH_UI_FTDI_EVE)
|
||||
//#define SHOW_CUSTOM_BOOTSCREEN // Show the bitmap in Marlin/_Bootscreen.h on startup.
|
||||
#endif
|
||||
#endif
|
||||
@@ -1600,10 +1599,10 @@
|
||||
#endif
|
||||
|
||||
// The timeout to return to the status screen from sub-menus
|
||||
//#define LCD_TIMEOUT_TO_STATUS 15000 // (ms)
|
||||
#define LCD_TIMEOUT_TO_STATUS 15000 // (ms)
|
||||
|
||||
// Scroll a longer status message into view
|
||||
//#define STATUS_MESSAGE_SCROLLING
|
||||
#define STATUS_MESSAGE_SCROLLING
|
||||
|
||||
// Apply a timeout to low-priority status messages
|
||||
//#define STATUS_MESSAGE_TIMEOUT_SEC 30 // (seconds)
|
||||
@@ -1655,7 +1654,7 @@
|
||||
#endif
|
||||
|
||||
// Add 'M73' to set print job progress, overrides Marlin's built-in estimate
|
||||
//#define SET_PROGRESS_MANUALLY
|
||||
#define SET_PROGRESS_MANUALLY
|
||||
#if ENABLED(SET_PROGRESS_MANUALLY)
|
||||
#define SET_PROGRESS_PERCENT // Add 'P' parameter to set percentage done
|
||||
#define SET_REMAINING_TIME // Add 'R' parameter to set remaining time
|
||||
@@ -1744,26 +1743,21 @@
|
||||
*/
|
||||
//#define POWER_LOSS_RECOVERY
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
#define PLR_ENABLED_DEFAULT false // Power-Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
|
||||
#define PLR_ENABLED_DEFAULT false // Power Loss Recovery enabled by default. (Set with 'M413 Sn' & M500)
|
||||
//#define PLR_BED_THRESHOLD BED_MAXTEMP // (°C) Skip user confirmation at or above this bed temperature (0 to disable)
|
||||
|
||||
//#define POWER_LOSS_PIN 44 // Pin to detect power-loss. Set to -1 to disable default pin on boards without module, or comment to use board default.
|
||||
//#define POWER_LOSS_STATE HIGH // State of pin indicating power-loss
|
||||
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power loss
|
||||
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power loss with UPS)
|
||||
//#define POWER_LOSS_PIN 44 // Pin to detect power loss. Set to -1 to disable default pin on boards without module.
|
||||
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
|
||||
//#define POWER_LOSS_PULLUP // Set pullup / pulldown as appropriate for your sensor
|
||||
//#define POWER_LOSS_PULLDOWN
|
||||
|
||||
//#define POWER_LOSS_ZRAISE 2 // (mm) Z axis raise on resume (on power-loss with UPS)
|
||||
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
|
||||
//#define POWER_LOSS_PURGE_LEN 20 // (mm) Length of filament to purge on resume
|
||||
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail. Requires backup power.
|
||||
|
||||
// Without a POWER_LOSS_PIN the following option helps reduce wear on the SD card,
|
||||
// especially with "vase mode" printing. Set too high and vases cannot be continued.
|
||||
#define POWER_LOSS_MIN_Z_CHANGE 0.05 // (mm) Minimum Z change before saving power-loss data
|
||||
|
||||
//#define BACKUP_POWER_SUPPLY // Backup power / UPS to move the steppers on power-loss
|
||||
#if ENABLED(BACKUP_POWER_SUPPLY)
|
||||
//#define POWER_LOSS_RETRACT_LEN 10 // (mm) Length of filament to retract on fail
|
||||
#endif
|
||||
|
||||
// Enable if Z homing is needed for proper recovery. 99.9% of the time this should be disabled!
|
||||
//#define POWER_LOSS_RECOVER_ZHOME
|
||||
#if ENABLED(POWER_LOSS_RECOVER_ZHOME)
|
||||
@@ -1812,13 +1806,13 @@
|
||||
|
||||
// Allow international symbols in long filenames. To display correctly, the
|
||||
// LCD's font must contain the characters. Check your selected LCD language.
|
||||
//#define UTF_FILENAME_SUPPORT
|
||||
#define UTF_FILENAME_SUPPORT
|
||||
|
||||
//#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
|
||||
#define LONG_FILENAME_HOST_SUPPORT // Get the long filename of a file/folder with 'M33 <dosname>' and list long filenames with 'M20 L'
|
||||
//#define LONG_FILENAME_WRITE_SUPPORT // Create / delete files with long filenames via M28, M30, and Binary Transfer Protocol
|
||||
//#define M20_TIMESTAMP_SUPPORT // Include timestamps by adding the 'T' flag to M20 commands
|
||||
|
||||
//#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu
|
||||
#define SCROLL_LONG_FILENAMES // Scroll long filenames in the SD card menu
|
||||
|
||||
//#define SD_ABORT_NO_COOLDOWN // Leave the heaters on after Stop Print (not recommended!)
|
||||
|
||||
@@ -1919,7 +1913,7 @@
|
||||
*
|
||||
* :[ 'LCD', 'ONBOARD', 'CUSTOM_CABLE' ]
|
||||
*/
|
||||
//#define SDCARD_CONNECTION LCD
|
||||
#define SDCARD_CONNECTION ONBOARD
|
||||
|
||||
// Enable if SD detect is rendered useless (e.g., by using an SD extender)
|
||||
//#define NO_SD_DETECT
|
||||
@@ -1969,6 +1963,17 @@
|
||||
// Western only. Not available for Cyrillic, Kana, Turkish, Greek, or Chinese.
|
||||
//#define USE_SMALL_INFOFONT
|
||||
|
||||
/**
|
||||
* Graphical Display Sleep
|
||||
*
|
||||
* The U8G library provides sleep / wake functions for SH1106, SSD1306,
|
||||
* SSD1309, and some other DOGM displays.
|
||||
* Enable this option to save energy and prevent OLED pixel burn-in.
|
||||
* Adds the menu item Configuration > LCD Timeout (m) to set a wait period
|
||||
* from 0 (disabled) to 99 minutes.
|
||||
*/
|
||||
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen. Set with M255 S.
|
||||
|
||||
/**
|
||||
* ST7920-based LCDs can emulate a 16 x 4 character display using
|
||||
* the ST7920 character-generator for very fast screen updates.
|
||||
@@ -2217,20 +2222,13 @@
|
||||
//#define TFT_BTOKMENU_COLOR 0x145F // 00010 100010 11111 Cyan
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Display Sleep
|
||||
* Enable this option to save energy and prevent OLED pixel burn-in.
|
||||
*/
|
||||
//#define DISPLAY_SLEEP_MINUTES 2 // (minutes) Timeout before turning off the screen
|
||||
|
||||
/**
|
||||
* LCD Backlight Timeout
|
||||
* Requires a display with a controllable backlight
|
||||
*/
|
||||
//
|
||||
// LCD Backlight Timeout
|
||||
// Requires a display with a controllable backlight
|
||||
//
|
||||
//#define LCD_BACKLIGHT_TIMEOUT_MINS 1 // (minutes) Timeout before turning off the backlight
|
||||
|
||||
#if defined(DISPLAY_SLEEP_MINUTES) || defined(LCD_BACKLIGHT_TIMEOUT_MINS)
|
||||
#define EDITABLE_DISPLAY_TIMEOUT // Edit sleep / backlight timeout with M255 S<minutes> and a menu item
|
||||
#define EDITABLE_DISPLAY_TIMEOUT // Edit timeout with M255 S<minutes> and a menu item
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -2265,18 +2263,18 @@
|
||||
*
|
||||
* Warning: Does not respect endstops!
|
||||
*/
|
||||
//#define BABYSTEPPING
|
||||
#define BABYSTEPPING
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
//#define EP_BABYSTEPPING // M293/M294 babystepping with EMERGENCY_PARSER support
|
||||
//#define BABYSTEP_WITHOUT_HOMING
|
||||
//#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement)
|
||||
#define BABYSTEP_ALWAYS_AVAILABLE // Allow babystepping at all times (not just during movement)
|
||||
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
|
||||
//#define BABYSTEP_INVERT_Z // Enable if Z babysteps should go the other way
|
||||
//#define BABYSTEP_MILLIMETER_UNITS // Specify BABYSTEP_MULTIPLICATOR_(XY|Z) in mm instead of micro-steps
|
||||
#define BABYSTEP_MULTIPLICATOR_Z 1 // (steps or mm) Steps or millimeter distance for each Z babystep
|
||||
#define BABYSTEP_MULTIPLICATOR_Z 25 // (steps or mm) Steps or millimeter distance for each Z babystep
|
||||
#define BABYSTEP_MULTIPLICATOR_XY 1 // (steps or mm) Steps or millimeter distance for each XY babystep
|
||||
|
||||
//#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
|
||||
#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
|
||||
#if ENABLED(DOUBLECLICK_FOR_Z_BABYSTEPPING)
|
||||
#define DOUBLECLICK_MAX_INTERVAL 1250 // Maximum interval between clicks, in milliseconds.
|
||||
// Note: Extra time may be added to mitigate controller latency.
|
||||
@@ -2288,7 +2286,7 @@
|
||||
|
||||
//#define BABYSTEP_DISPLAY_TOTAL // Display total babysteps since last G28
|
||||
|
||||
//#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping
|
||||
#define BABYSTEP_ZPROBE_OFFSET // Combine M851 Z and Babystepping
|
||||
#if ENABLED(BABYSTEP_ZPROBE_OFFSET)
|
||||
//#define BABYSTEP_HOTEND_Z_OFFSET // For multiple hotends, babystep relative Z offsets
|
||||
//#define BABYSTEP_GFX_OVERLAY // Enable graphical overlay on Z-offset editor
|
||||
@@ -2312,7 +2310,7 @@
|
||||
*
|
||||
* See https://marlinfw.org/docs/features/lin_advance.html for full instructions.
|
||||
*/
|
||||
//#define LIN_ADVANCE
|
||||
#define LIN_ADVANCE
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
#define ADVANCE_K { 0.22 } // (mm) Compression length per 1mm/s extruder speed, per extruder
|
||||
@@ -2505,7 +2503,7 @@
|
||||
#endif
|
||||
|
||||
// G5 Bézier Curve Support with XYZE destination and IJPQ offsets
|
||||
//#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes
|
||||
#define BEZIER_CURVE_SUPPORT // Requires ~2666 bytes
|
||||
|
||||
#if ANY(ARC_SUPPORT, BEZIER_CURVE_SUPPORT)
|
||||
//#define CNC_WORKSPACE_PLANES // Allow G2/G3/G5 to operate in XY, ZX, or YZ planes
|
||||
@@ -2566,7 +2564,7 @@
|
||||
*
|
||||
* Override the default value based on the driver type set in Configuration.h.
|
||||
*/
|
||||
//#define MINIMUM_STEPPER_PULSE 2
|
||||
//#define MINIMUM_STEPPER_PULSE 5
|
||||
|
||||
/**
|
||||
* Maximum stepping rate (in Hz) the stepper driver allows
|
||||
@@ -2580,7 +2578,7 @@
|
||||
*
|
||||
* Override the default value based on the driver type set in Configuration.h.
|
||||
*/
|
||||
//#define MAXIMUM_STEPPER_RATE 250000
|
||||
//#define MAXIMUM_STEPPER_RATE 150000
|
||||
|
||||
// @section temperature
|
||||
|
||||
@@ -2597,16 +2595,16 @@
|
||||
#if ALL(HAS_MEDIA, DIRECT_STEPPING)
|
||||
#define BLOCK_BUFFER_SIZE 8
|
||||
#elif HAS_MEDIA
|
||||
#define BLOCK_BUFFER_SIZE 16
|
||||
#define BLOCK_BUFFER_SIZE 32
|
||||
#else
|
||||
#define BLOCK_BUFFER_SIZE 16
|
||||
#define BLOCK_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
// @section serial
|
||||
|
||||
// The ASCII buffer for serial input
|
||||
#define MAX_CMD_SIZE 96
|
||||
#define BUFSIZE 4
|
||||
#define BUFSIZE 16
|
||||
|
||||
// Transmission to Host Buffer Size
|
||||
// To save 386 bytes of flash (and TX_BUFFER_SIZE+3 bytes of RAM) set to 0.
|
||||
@@ -2653,7 +2651,7 @@
|
||||
* Currently handles M108, M112, M410, M876
|
||||
* NOTE: Not yet implemented for all platforms.
|
||||
*/
|
||||
//#define EMERGENCY_PARSER
|
||||
#define EMERGENCY_PARSER
|
||||
|
||||
/**
|
||||
* Realtime Reporting (requires EMERGENCY_PARSER)
|
||||
@@ -2684,7 +2682,7 @@
|
||||
//#define NO_TIMEOUTS 1000 // (ms)
|
||||
|
||||
// Some clients will have this feature soon. This could make the NO_TIMEOUTS unnecessary.
|
||||
//#define ADVANCED_OK
|
||||
#define ADVANCED_OK
|
||||
|
||||
// Printrun may have trouble receiving long strings all at once.
|
||||
// This option inserts short delays between lines of serial output.
|
||||
@@ -2697,7 +2695,7 @@
|
||||
* This feature is EXPERIMENTAL so use with caution and test thoroughly.
|
||||
* Enable this option to receive data on the serial ports via the onboard DMA
|
||||
* controller for more stable and reliable high-speed serial communication.
|
||||
* Support is currently limited to some STM32 MCUs and all HC32 MCUs.
|
||||
* Only some STM32 MCUs are currently supported.
|
||||
* Note: This has no effect on emulated USB serial ports.
|
||||
*/
|
||||
//#define SERIAL_DMA
|
||||
@@ -2886,7 +2884,7 @@
|
||||
*
|
||||
* Enable PARK_HEAD_ON_PAUSE to add the G-code M125 Pause and Park.
|
||||
*/
|
||||
//#define ADVANCED_PAUSE_FEATURE
|
||||
#define ADVANCED_PAUSE_FEATURE
|
||||
#if ENABLED(ADVANCED_PAUSE_FEATURE)
|
||||
#define PAUSE_PARK_RETRACT_FEEDRATE 60 // (mm/s) Initial retract feedrate.
|
||||
#define PAUSE_PARK_RETRACT_LENGTH 2 // (mm) Initial retract.
|
||||
@@ -2926,11 +2924,11 @@
|
||||
//#define FILAMENT_CHANGE_RESUME_ON_INSERT // Automatically continue / load filament when runout sensor is triggered again.
|
||||
//#define PAUSE_REHEAT_FAST_RESUME // Reduce number of waits by not prompting again post-timeout before continuing.
|
||||
|
||||
//#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
|
||||
#define PARK_HEAD_ON_PAUSE // Park the nozzle during pause and filament change.
|
||||
//#define HOME_BEFORE_FILAMENT_CHANGE // If needed, home before parking for filament change
|
||||
|
||||
//#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
|
||||
//#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
|
||||
#define FILAMENT_LOAD_UNLOAD_GCODES // Add M701/M702 Load/Unload G-codes, plus Load/Unload in the LCD Prepare menu.
|
||||
#define FILAMENT_UNLOAD_ALL_EXTRUDERS // Allow M702 to unload all extruders above a minimum target temp (as set by M302)
|
||||
#define CONFIGURE_FILAMENT_CHANGE // Add M603 G-code and menu items. Requires ~1.3K bytes of flash.
|
||||
#endif
|
||||
|
||||
@@ -2952,14 +2950,17 @@
|
||||
* Some boards have simple jumper connections! See your board's documentation.
|
||||
* - These drivers can also be used with Hardware Serial.
|
||||
*
|
||||
* The TMC26XStepper library is required for TMC26X stepper drivers.
|
||||
* https://github.com/MarlinFirmware/TMC26XStepper
|
||||
*
|
||||
* The TMCStepper library is required for other TMC stepper drivers.
|
||||
* https://github.com/teemuatlut/TMCStepper
|
||||
*
|
||||
* @section tmc/config
|
||||
*/
|
||||
#if HAS_TRINAMIC_CONFIG
|
||||
#if HAS_TRINAMIC_CONFIG || HAS_TMC26X
|
||||
|
||||
#define HOLD_MULTIPLIER 0.5 // Scales down the holding current from run current
|
||||
#define HOLD_MULTIPLIER 0.7 // Scales down the holding current from run current
|
||||
|
||||
/**
|
||||
* Interpolate microsteps to 256
|
||||
@@ -2971,7 +2972,7 @@
|
||||
#define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
|
||||
#define X_CURRENT_HOME X_CURRENT // (mA) RMS current for sensorless homing
|
||||
#define X_MICROSTEPS 16 // 0..256
|
||||
#define X_RSENSE 0.11
|
||||
#define X_RSENSE 0.022 // Multiplied x1000 for TMC26X
|
||||
#define X_CHAIN_POS -1 // -1..0: Not chained. 1: MCU MOSI connected. 2: Next in chain, ...
|
||||
//#define X_INTERPOLATE true // Enable to override 'INTERPOLATE' for the X axis
|
||||
//#define X_HOLD_MULTIPLIER 0.5 // Enable to override 'HOLD_MULTIPLIER' for the X axis
|
||||
@@ -2991,7 +2992,7 @@
|
||||
#define Y_CURRENT 800
|
||||
#define Y_CURRENT_HOME Y_CURRENT
|
||||
#define Y_MICROSTEPS 16
|
||||
#define Y_RSENSE 0.11
|
||||
#define Y_RSENSE 0.022
|
||||
#define Y_CHAIN_POS -1
|
||||
//#define Y_INTERPOLATE true
|
||||
//#define Y_HOLD_MULTIPLIER 0.5
|
||||
@@ -3108,7 +3109,7 @@
|
||||
#endif
|
||||
|
||||
#if AXIS_IS_TMC_CONFIG(E0)
|
||||
#define E0_CURRENT 800
|
||||
#define E0_CURRENT 900
|
||||
#define E0_MICROSTEPS 16
|
||||
#define E0_RSENSE 0.11
|
||||
#define E0_CHAIN_POS -1
|
||||
@@ -3213,7 +3214,7 @@
|
||||
* The default SW SPI pins are defined the respective pins files,
|
||||
* but you can override or define them here.
|
||||
*/
|
||||
//#define TMC_USE_SW_SPI
|
||||
#define TMC_USE_SW_SPI
|
||||
//#define TMC_SPI_MOSI -1
|
||||
//#define TMC_SPI_MISO -1
|
||||
//#define TMC_SPI_SCK -1
|
||||
@@ -3273,7 +3274,7 @@
|
||||
* When disabled, Marlin will use spreadCycle stepping mode.
|
||||
*/
|
||||
#if HAS_STEALTHCHOP
|
||||
#define STEALTHCHOP_XY
|
||||
//#define STEALTHCHOP_XY
|
||||
#define STEALTHCHOP_Z
|
||||
#define STEALTHCHOP_I
|
||||
#define STEALTHCHOP_J
|
||||
@@ -3281,7 +3282,7 @@
|
||||
#define STEALTHCHOP_U
|
||||
#define STEALTHCHOP_V
|
||||
#define STEALTHCHOP_W
|
||||
#define STEALTHCHOP_E
|
||||
//#define STEALTHCHOP_E
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -3299,11 +3300,11 @@
|
||||
* Define your own with:
|
||||
* { <off_time[1..15]>, <hysteresis_end[-3..12]>, hysteresis_start[1..8] }
|
||||
*/
|
||||
#define CHOPPER_TIMING CHOPPER_DEFAULT_12V // All axes (override below)
|
||||
//#define CHOPPER_TIMING_X CHOPPER_TIMING // For X Axes (override below)
|
||||
//#define CHOPPER_TIMING CHOPPER_DEFAULT_36V // All axes (override below)
|
||||
#define CHOPPER_TIMING_X CHOPPER_DEFAULT_36V // For X Axes (override below)
|
||||
//#define CHOPPER_TIMING_X2 CHOPPER_TIMING_X
|
||||
//#define CHOPPER_TIMING_Y CHOPPER_TIMING // For Y Axes (override below)
|
||||
//#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
|
||||
#define CHOPPER_TIMING_Y CHOPPER_DEFAULT_36V // For Y Axes (override below)
|
||||
#define CHOPPER_TIMING_Y2 CHOPPER_TIMING_Y
|
||||
//#define CHOPPER_TIMING_Z CHOPPER_TIMING // For Z Axes (override below)
|
||||
//#define CHOPPER_TIMING_Z2 CHOPPER_TIMING_Z
|
||||
//#define CHOPPER_TIMING_Z3 CHOPPER_TIMING_Z
|
||||
@@ -3314,7 +3315,7 @@
|
||||
//#define CHOPPER_TIMING_U CHOPPER_TIMING // For U Axis
|
||||
//#define CHOPPER_TIMING_V CHOPPER_TIMING // For V Axis
|
||||
//#define CHOPPER_TIMING_W CHOPPER_TIMING // For W Axis
|
||||
//#define CHOPPER_TIMING_E CHOPPER_TIMING // For Extruders (override below)
|
||||
#define CHOPPER_TIMING_E CHOPPER_DEFAULT_24V // For Extruders (override below)
|
||||
//#define CHOPPER_TIMING_E1 CHOPPER_TIMING_E
|
||||
//#define CHOPPER_TIMING_E2 CHOPPER_TIMING_E
|
||||
//#define CHOPPER_TIMING_E3 CHOPPER_TIMING_E
|
||||
@@ -3336,12 +3337,12 @@
|
||||
* M912 - Clear stepper driver overtemperature pre-warn condition flag.
|
||||
* M122 - Report driver parameters (Requires TMC_DEBUG)
|
||||
*/
|
||||
//#define MONITOR_DRIVER_STATUS
|
||||
#define MONITOR_DRIVER_STATUS
|
||||
|
||||
#if ENABLED(MONITOR_DRIVER_STATUS)
|
||||
#define CURRENT_STEP_DOWN 50 // [mA]
|
||||
#define REPORT_CURRENT_CHANGE
|
||||
#define STOP_ON_ERROR
|
||||
//#define STOP_ON_ERROR
|
||||
#endif
|
||||
|
||||
// @section tmc/hybrid
|
||||
@@ -3443,7 +3444,7 @@
|
||||
/**
|
||||
* Step on both rising and falling edge signals (as with a square wave).
|
||||
*/
|
||||
//#define EDGE_STEPPING
|
||||
#define EDGE_STEPPING
|
||||
|
||||
/**
|
||||
* Enable M122 debugging command for TMC stepper drivers.
|
||||
@@ -3464,7 +3465,7 @@
|
||||
*/
|
||||
#define TMC_ADV() { }
|
||||
|
||||
#endif // HAS_TRINAMIC_CONFIG
|
||||
#endif // HAS_TRINAMIC_CONFIG || HAS_TMC26X
|
||||
|
||||
// @section i2cbus
|
||||
|
||||
@@ -3557,7 +3558,7 @@
|
||||
* Add the M3, M4, and M5 commands to turn the spindle/laser on and off, and
|
||||
* to set spindle speed, spindle direction, and laser power.
|
||||
*
|
||||
* SuperPID is a router/spindle speed controller used in the CNC milling community.
|
||||
* SuperPid is a router/spindle speed controller used in the CNC milling community.
|
||||
* Marlin can be used to turn the spindle on and off. It can also be used to set
|
||||
* the spindle speed from 5,000 to 30,000 RPM.
|
||||
*
|
||||
@@ -4112,14 +4113,14 @@
|
||||
* Host Prompt Support enables Marlin to use the host for user prompts so
|
||||
* filament runout and other processes can be managed from the host side.
|
||||
*/
|
||||
//#define HOST_ACTION_COMMANDS
|
||||
#define HOST_ACTION_COMMANDS
|
||||
#if ENABLED(HOST_ACTION_COMMANDS)
|
||||
//#define HOST_PAUSE_M76 // Tell the host to pause in response to M76
|
||||
//#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback
|
||||
#define HOST_PROMPT_SUPPORT // Initiate host prompts to get user feedback
|
||||
#if ENABLED(HOST_PROMPT_SUPPORT)
|
||||
//#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications
|
||||
#define HOST_STATUS_NOTIFICATIONS // Send some status messages to the host as notifications
|
||||
#endif
|
||||
//#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
|
||||
#define HOST_START_MENU_ITEM // Add a menu item that tells the host to start
|
||||
//#define HOST_SHUTDOWN_MENU_ITEM // Add a menu item that tells the host to shut down
|
||||
#endif
|
||||
|
||||
@@ -4260,8 +4261,7 @@
|
||||
|
||||
/**
|
||||
* Instant freeze / unfreeze functionality
|
||||
* Potentially useful for rapid stop that allows being resumed. Halts stepper movement.
|
||||
* Note this does NOT pause spindles, lasers, fans, heaters or any other auxiliary device.
|
||||
* Potentially useful for emergency stop that allows being resumed.
|
||||
* @section interface
|
||||
*/
|
||||
//#define FREEZE_FEATURE
|
||||
@@ -4308,7 +4308,6 @@
|
||||
// See class CodeProfiler.
|
||||
//#define MAX7219_DEBUG_MULTISTEPPING 6 // Show multi-stepping 1 to 128 on this LED matrix row.
|
||||
//#define MAX7219_DEBUG_SLOWDOWN 6 // Count (mod 16) how many times SLOWDOWN has reduced print speed.
|
||||
//#define MAX7219_REINIT_ON_POWERUP // Re-initialize MAX7129 when power supply turns on
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -4342,7 +4341,7 @@
|
||||
* Extras for an ESP32-based motherboard with WIFISUPPORT
|
||||
* These options don't apply to add-on WiFi modules based on ESP32 WiFi101.
|
||||
*/
|
||||
#if ANY(WIFISUPPORT, ESP3D_WIFISUPPORT)
|
||||
#if ENABLED(WIFISUPPORT)
|
||||
//#define WEBSUPPORT // Start a webserver (which may include auto-discovery) using SPIFFS
|
||||
//#define OTASUPPORT // Support over-the-air firmware updates
|
||||
//#define WIFI_CUSTOM_COMMAND // Accept feature config commands (e.g., WiFi ESP3D) from the host
|
||||
@@ -4489,7 +4488,7 @@
|
||||
//
|
||||
// M42 - Set pin states
|
||||
//
|
||||
//#define DIRECT_PIN_CONTROL
|
||||
#define DIRECT_PIN_CONTROL
|
||||
|
||||
//
|
||||
// M43 - display pin status, toggle pins, watch pins, watch endstops & toggle LED, test servo probe
|
||||
@@ -4525,6 +4524,3 @@
|
||||
|
||||
// Report uncleaned reset reason from register r2 instead of MCUSR. Supported by Optiboot on AVR.
|
||||
//#define OPTIBOOT_RESET_REASON
|
||||
|
||||
// Shrink the build for smaller boards by sacrificing some serial feedback
|
||||
//#define MARLIN_SMALL_BUILD
|
||||
|
||||
+1
-1
@@ -41,7 +41,7 @@
|
||||
* here we define this default string as the date where the latest release
|
||||
* version was tagged.
|
||||
*/
|
||||
//#define STRING_DISTRIBUTION_DATE "2024-05-29"
|
||||
//#define STRING_DISTRIBUTION_DATE "2024-05-27"
|
||||
|
||||
/**
|
||||
* Defines a generic printer name to be output to the LCD after booting Marlin.
|
||||
|
||||
@@ -141,7 +141,7 @@ typedef Servo hal_servo_t;
|
||||
#error "LCD_SERIAL_PORT must be from 0 to 3."
|
||||
#endif
|
||||
#define LCD_SERIAL lcdSerial
|
||||
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
|
||||
#if HAS_DGUS_LCD
|
||||
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.get_tx_buffer_free()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -629,7 +629,7 @@ MSerialT1 customizedSerial1(MSerialT1::HasEmergencyParser);
|
||||
template class MarlinSerial< LCDSerialCfg<LCD_SERIAL_PORT> >;
|
||||
MSerialLCD lcdSerial(MSerialLCD::HasEmergencyParser);
|
||||
|
||||
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
|
||||
#if HAS_DGUS_LCD
|
||||
template<typename Cfg>
|
||||
typename MarlinSerial<Cfg>::ring_buffer_pos_t MarlinSerial<Cfg>::get_tx_buffer_free() {
|
||||
const ring_buffer_pos_t t = tx_buffer.tail, // next byte to send.
|
||||
|
||||
@@ -205,7 +205,7 @@
|
||||
static ring_buffer_pos_t available();
|
||||
static void write(const uint8_t c);
|
||||
static void flushTX();
|
||||
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
|
||||
#if HAS_DGUS_LCD
|
||||
static ring_buffer_pos_t get_tx_buffer_free();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -53,12 +53,11 @@ typedef uint64_t hal_timer_t;
|
||||
#if ENABLED(I2S_STEPPER_STREAM)
|
||||
#define STEPPER_TIMER_PRESCALE 1
|
||||
#define STEPPER_TIMER_RATE 250000 // 250khz, 4µs pulses of i2s word clock
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs // wrong would be 0.25
|
||||
#else
|
||||
#define STEPPER_TIMER_PRESCALE 40
|
||||
#define STEPPER_TIMER_RATE ((HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE)) // frequency of stepper timer, 2MHz
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
|
||||
#endif
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
|
||||
|
||||
#define STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ extern DefaultSerial1 USBSerial;
|
||||
#else
|
||||
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
|
||||
#if HAS_DGUS_LCD
|
||||
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.available()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../shared/Delay.h"
|
||||
#include "../../../gcode/parser.h"
|
||||
|
||||
DefaultSerial1 USBSerial(false, MCDCSerial0);
|
||||
|
||||
uint32_t MarlinHAL::adc_result = 0;
|
||||
|
||||
// U8glib required functions
|
||||
extern "C" {
|
||||
void u8g_xMicroDelay(uint16_t val) { DELAY_US(val); }
|
||||
void u8g_MicroDelay() { u8g_xMicroDelay(1); }
|
||||
void u8g_10MicroDelay() { u8g_xMicroDelay(10); }
|
||||
void u8g_Delay(uint16_t val) { delay(val); }
|
||||
}
|
||||
|
||||
// return free heap space
|
||||
int freeMemory() {
|
||||
char stack_end;
|
||||
void *heap_start = malloc(sizeof(uint32_t));
|
||||
if (heap_start == 0) return 0;
|
||||
|
||||
uint32_t result = (uint32_t)&stack_end - (uint32_t)heap_start;
|
||||
free(heap_start);
|
||||
return result;
|
||||
}
|
||||
|
||||
void MarlinHAL::reboot() { MCUCore::nvic_system_reset(); }
|
||||
|
||||
uint8_t MarlinHAL::get_reset_source() {
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
if (watchdog_timed_out()) return RST_WATCHDOG;
|
||||
#endif
|
||||
return RST_POWER_ON;
|
||||
}
|
||||
|
||||
void MarlinHAL::clear_reset_source() { watchdog_clear_timeout_flag(); }
|
||||
|
||||
void flashFirmware(const int16_t) {
|
||||
delay(500); // Give OS time to disconnect
|
||||
//USB_Connect(false); // USB clear connection
|
||||
delay(1000); // Give OS time to notice
|
||||
hal.reboot();
|
||||
}
|
||||
|
||||
#if ENABLED(USE_WATCHDOG)
|
||||
|
||||
#define WDT_TIMEOUT TERN(WATCHDOG_DURATION_8S, 8.0f, 4.0f) // 4 or 8 second timeout
|
||||
|
||||
void MarlinHAL::watchdog_init() {
|
||||
#if ENABLED(WATCHDOG_RESET_MANUAL)
|
||||
// We enable the watchdog timer, but only for the interrupt.
|
||||
|
||||
// Configure WDT to only trigger an interrupt
|
||||
// Disable WDT interrupt (just in case, to avoid triggering it!)
|
||||
NVIC_DisableIRQ(WDT_IRQn);
|
||||
|
||||
// We NEED memory barriers to ensure Interrupts are actually disabled!
|
||||
// ( https://dzone.com/articles/nvic-disabling-interrupts-on-arm-cortex-m-and-the )
|
||||
__DSB();
|
||||
__ISB();
|
||||
|
||||
// WDT defaults to trigger an interrupt
|
||||
|
||||
// Configure and enable WDT interrupt.
|
||||
NVIC_ClearPendingIRQ(WDT_IRQn);
|
||||
NVIC_SetPriority(WDT_IRQn, 0); // Use highest priority, so we detect all kinds of lockups
|
||||
NVIC_EnableIRQ(WDT_IRQn);
|
||||
#else
|
||||
MCUI::watchdog_set_timeout_triggers_reset();
|
||||
#endif
|
||||
MCUI::watchdog_set_timeout_in_seconds(WDT_TIMEOUT);
|
||||
MCUI::watchdog_enable();
|
||||
}
|
||||
|
||||
void MarlinHAL::watchdog_refresh() {
|
||||
MCUI::watchdog_feed();
|
||||
#if DISABLED(PINS_DEBUGGING) && PIN_EXISTS(LED)
|
||||
static millis_t next_flash = millis();
|
||||
if (ELAPSED(millis(), next_flash)) {
|
||||
next_flash = millis() + 200;
|
||||
TOGGLE(LED_PIN); // heartbeat indicator
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// Timeout state
|
||||
bool MarlinHAL::watchdog_timed_out() { return MCUI::watchdog_has_triggered(); }
|
||||
void MarlinHAL::watchdog_clear_timeout_flag() { MCUI::watchdog_clear_timeout_flag(); }
|
||||
|
||||
#endif // USE_WATCHDOG
|
||||
|
||||
// For M42/M43, scan command line for pin code
|
||||
// return index into pin map array if found and the pin is valid.
|
||||
// return dval if not found or not a valid pin.
|
||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval) {
|
||||
const uint16_t val = (uint16_t)parser.intval(code, -1), port = val / 100, pin = val % 100;
|
||||
const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2;
|
||||
return ind > -1 ? ind : dval;
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* HAL_LPC1768/HAL.h
|
||||
* Hardware Abstraction Layer for NXP LPC1768
|
||||
*/
|
||||
|
||||
#define CPU_32_BIT
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "../shared/Marduino.h"
|
||||
#include "../shared/Delay.h"
|
||||
#include "../shared/math_32bit.h"
|
||||
#include "../shared/HAL_SPI.h"
|
||||
#include "fastio.h"
|
||||
#include "MarlinSerial.h"
|
||||
|
||||
#include <mcu_interface.h>
|
||||
|
||||
// ------------------------
|
||||
// Serial ports
|
||||
// ------------------------
|
||||
|
||||
typedef ForwardSerial1Class< decltype(MCDCSerial0) > DefaultSerial1;
|
||||
extern DefaultSerial1 USBSerial;
|
||||
|
||||
#define _MSERIAL(X) MSerial##X
|
||||
#define MSERIAL(X) _MSERIAL(X)
|
||||
|
||||
#if SERIAL_PORT == -1
|
||||
#define MYSERIAL1 USBSerial
|
||||
#elif WITHIN(SERIAL_PORT, 0, 3)
|
||||
#define MYSERIAL1 MSERIAL(SERIAL_PORT)
|
||||
#else
|
||||
#error "SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_2
|
||||
#if SERIAL_PORT_2 == -1
|
||||
#define MYSERIAL2 USBSerial
|
||||
#elif WITHIN(SERIAL_PORT_2, 0, 3)
|
||||
#define MYSERIAL2 MSERIAL(SERIAL_PORT_2)
|
||||
#else
|
||||
#error "SERIAL_PORT_2 must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SERIAL_PORT_3
|
||||
#if SERIAL_PORT_3 == -1
|
||||
#define MYSERIAL3 USBSerial
|
||||
#elif WITHIN(SERIAL_PORT_3, 0, 3)
|
||||
#define MYSERIAL3 MSERIAL(SERIAL_PORT_3)
|
||||
#else
|
||||
#error "SERIAL_PORT_3 must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef MMU2_SERIAL_PORT
|
||||
#if MMU2_SERIAL_PORT == -1
|
||||
#define MMU2_SERIAL USBSerial
|
||||
#elif WITHIN(MMU2_SERIAL_PORT, 0, 3)
|
||||
#define MMU2_SERIAL MSERIAL(MMU2_SERIAL_PORT)
|
||||
#else
|
||||
#error "MMU2_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef LCD_SERIAL_PORT
|
||||
#if LCD_SERIAL_PORT == -1
|
||||
#define LCD_SERIAL USBSerial
|
||||
#elif WITHIN(LCD_SERIAL_PORT, 0, 3)
|
||||
#define LCD_SERIAL MSERIAL(LCD_SERIAL_PORT)
|
||||
#else
|
||||
#error "LCD_SERIAL_PORT must be from 0 to 3. You can also use -1 if the board supports Native USB."
|
||||
#endif
|
||||
#if HAS_DGUS_LCD
|
||||
#define SERIAL_GET_TX_BUFFER_FREE() LCD_SERIAL.available()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//
|
||||
// Interrupts
|
||||
//
|
||||
|
||||
#define CRITICAL_SECTION_START() const bool irqon = !MCUCore::primask(); MCUCore::nvic_interrupts_disable()
|
||||
#define CRITICAL_SECTION_END() if (irqon) MCUCore::nvic_interrupts_enable()
|
||||
#define cli() noInterrupts()
|
||||
#define sei() interrupts()
|
||||
//
|
||||
// ADC
|
||||
//
|
||||
|
||||
#define ADC_MEDIAN_FILTER_SIZE (23) // Higher values increase step delay (phase shift),
|
||||
// (ADC_MEDIAN_FILTER_SIZE + 1) / 2 sample step delay (12 samples @ 500Hz: 24ms phase shift)
|
||||
// Memory usage per ADC channel (bytes): (6 * ADC_MEDIAN_FILTER_SIZE) + 16
|
||||
// 8 * ((6 * 23) + 16 ) = 1232 Bytes for 8 channels
|
||||
|
||||
#define ADC_LOWPASS_K_VALUE (2) // Higher values increase rise time
|
||||
// Rise time sample delays for 100% signal convergence on full range step
|
||||
// (1 : 13, 2 : 32, 3 : 67, 4 : 139, 5 : 281, 6 : 565, 7 : 1135, 8 : 2273)
|
||||
// K = 6, 565 samples, 500Hz sample rate, 1.13s convergence on full range step
|
||||
// Memory usage per ADC channel (bytes): 4 (32 Bytes for 8 channels)
|
||||
|
||||
#define HAL_ADC_VREF 3.3 // ADC voltage reference
|
||||
|
||||
#define HAL_ADC_RESOLUTION 12 // 15 bit maximum, raw temperature is stored as int16_t
|
||||
#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
|
||||
|
||||
//
|
||||
// Pin Mapping for M42, M43, M226
|
||||
//
|
||||
|
||||
// Test whether the pin is valid
|
||||
constexpr bool VALID_PIN(const pin_t pin) {
|
||||
return MCUI::pin_is_valid(pin);
|
||||
}
|
||||
|
||||
// Get the analog index for a digital pin
|
||||
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) {
|
||||
return (MCUI::pin_is_valid(pin) && MCUI::pin_has_adc(pin)) ? pin : -1;
|
||||
}
|
||||
|
||||
//
|
||||
// Misc. Functions
|
||||
//
|
||||
#ifndef analogInputToDigitalPin
|
||||
#define analogInputToDigitalPin(p) (p)
|
||||
#endif
|
||||
|
||||
|
||||
// Return the index of a pin number
|
||||
constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
|
||||
return MCUI::pin_index(pin);
|
||||
}
|
||||
|
||||
// Get the pin number at the given index
|
||||
constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
|
||||
return MCUI::pin_index(index);
|
||||
}
|
||||
|
||||
// Parse a G-code word into a pin index
|
||||
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
|
||||
// P0.6 thru P0.9 are for the onboard SD card
|
||||
#define HAL_SENSITIVE_PINS P0_06, P0_07, P0_08, P0_09,
|
||||
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
void flashFirmware(const int16_t);
|
||||
|
||||
#define HAL_CAN_SET_PWM_FREQ // This HAL supports PWM Frequency adjustment
|
||||
|
||||
// Default graphical display delays
|
||||
#define CPU_ST7920_DELAY_1 600
|
||||
#define CPU_ST7920_DELAY_2 750
|
||||
#define CPU_ST7920_DELAY_3 750
|
||||
|
||||
// ------------------------
|
||||
// Free Memory Accessor
|
||||
// ------------------------
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#if GCC_VERSION <= 50000
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
int freeMemory();
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
// ------------------------
|
||||
// MarlinHAL Class
|
||||
// ------------------------
|
||||
|
||||
class MarlinHAL {
|
||||
public:
|
||||
|
||||
// Earliest possible init, before setup()
|
||||
MarlinHAL() {}
|
||||
|
||||
static void init(); // Called early in setup()
|
||||
static void init_board() {} // Called less early in setup()
|
||||
static void reboot(); // Restart the firmware from 0x0
|
||||
|
||||
// Interrupts
|
||||
static bool isr_state() { return MCUCore::primask(); }
|
||||
static void isr_on() { MCUCore::nvic_interrupts_enable(); }
|
||||
static void isr_off() { MCUCore::nvic_interrupts_disable(); }
|
||||
|
||||
static void delay_ms(const int ms) { DELAY_US(ms * 1000); }
|
||||
|
||||
// Watchdog
|
||||
static void watchdog_init() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static void watchdog_refresh() IF_DISABLED(USE_WATCHDOG, {});
|
||||
static bool watchdog_timed_out() IF_DISABLED(USE_WATCHDOG, { return false; });
|
||||
static void watchdog_clear_timeout_flag() IF_DISABLED(USE_WATCHDOG, {});
|
||||
|
||||
// Tasks, called from idle()
|
||||
static void idletask();
|
||||
|
||||
// Reset
|
||||
static uint8_t get_reset_source();
|
||||
static void clear_reset_source();
|
||||
|
||||
// Free SRAM
|
||||
static int freeMemory() { return ::freeMemory(); }
|
||||
|
||||
//
|
||||
// ADC Methods
|
||||
//
|
||||
|
||||
using FilteredADC = MCUI::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
|
||||
|
||||
// Called by Temperature::init once at startup
|
||||
static void adc_init() {
|
||||
// Turn on and initialise ADC in burst mode
|
||||
MCUI::adc_hardware.init();
|
||||
MCUI::adc_hardware.burst_start();
|
||||
}
|
||||
|
||||
// Called by Temperature::init for each sensor at startup
|
||||
static void adc_enable(const pin_t pin) {
|
||||
FilteredADC::enable_channel(pin);
|
||||
}
|
||||
|
||||
// Begin ADC sampling on the given pin. Called from Temperature::isr!
|
||||
static uint32_t adc_result;
|
||||
static void adc_start(const pin_t pin) {
|
||||
adc_result = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
|
||||
}
|
||||
|
||||
// Is the ADC ready for reading?
|
||||
static bool adc_ready() { return true; }
|
||||
|
||||
// The current value of the ADC register
|
||||
static uint16_t adc_value() { return uint16_t(adc_result); }
|
||||
|
||||
/**
|
||||
* Set the PWM duty cycle for the pin to the given value.
|
||||
* Optionally invert the duty cycle [default = false]
|
||||
* Optionally change the scale of the provided value to enable finer PWM duty control [default = 255]
|
||||
*/
|
||||
static void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size=255, const bool invert=false);
|
||||
|
||||
/**
|
||||
* Set the frequency of the timer corresponding to the provided pin
|
||||
* All Hardware PWM pins will run at the same frequency and
|
||||
* All Software PWM pins will run at the same frequency
|
||||
*/
|
||||
static void set_pwm_frequency(const pin_t pin, const uint16_t f_desired);
|
||||
};
|
||||
@@ -0,0 +1,376 @@
|
||||
// /**
|
||||
// * Marlin 3D Printer Firmware
|
||||
// * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
// *
|
||||
// * Based on Sprinter and grbl.
|
||||
// * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
// *
|
||||
// * This program is free software: you can redistribute it and/or modify
|
||||
// * it under the terms of the GNU General Public License as published by
|
||||
// * the Free Software Foundation, either version 3 of the License, or
|
||||
// * (at your option) any later version.
|
||||
// *
|
||||
// * This program is distributed in the hope that it will be useful,
|
||||
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// * GNU General Public License for more details.
|
||||
// *
|
||||
// * You should have received a copy of the GNU General Public License
|
||||
// * along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
// *
|
||||
// */
|
||||
|
||||
// /**
|
||||
// * Software SPI functions originally from Arduino Sd2Card Library
|
||||
// * Copyright (c) 2009 by William Greiman
|
||||
// */
|
||||
|
||||
// /**
|
||||
// * For TARGET_LPC4078
|
||||
// */
|
||||
|
||||
// /**
|
||||
// * Hardware SPI and Software SPI implementations are included in this file.
|
||||
// * The hardware SPI runs faster and has higher throughput but is not compatible
|
||||
// * with some LCD interfaces/adapters.
|
||||
// *
|
||||
// * Control of the slave select pin(s) is handled by the calling routines.
|
||||
// *
|
||||
// * Some of the LCD interfaces/adapters result in the LCD SPI and the SD card
|
||||
// * SPI sharing pins. The SCK, MOSI & MISO pins can NOT be set/cleared with
|
||||
// * WRITE nor digitalWrite when the hardware SPI module within the LPC17xx is
|
||||
// * active. If any of these pins are shared then the software SPI must be used.
|
||||
// *
|
||||
// * A more sophisticated hardware SPI can be found at the following link.
|
||||
// * This implementation has not been fully debugged.
|
||||
// * https://github.com/MarlinFirmware/Marlin/tree/071c7a78f27078fd4aee9a3ef365fcf5e143531e
|
||||
// */
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include <SPI.h>
|
||||
|
||||
// Hardware SPI and SPIClass
|
||||
|
||||
#include "../shared/HAL_SPI.h"
|
||||
|
||||
#define LPC_SOFTWARE_SPI
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
#if ENABLED(LPC_SOFTWARE_SPI)
|
||||
#include "SoftwareSPI.h"
|
||||
|
||||
// Software SPI
|
||||
static uint8_t SPI_speed = SPI_FULL_SPEED;
|
||||
|
||||
static uint8_t spiTransfer(uint8_t b) {
|
||||
return swSpiTransfer(b, SPI_speed, SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
|
||||
}
|
||||
|
||||
void spiBegin() {
|
||||
swSpiBegin(SD_SCK_PIN, SD_MISO_PIN, SD_MOSI_PIN);
|
||||
}
|
||||
|
||||
void spiInit(uint8_t spiRate) {
|
||||
SPI_speed = swSpiInit(spiRate, SD_SCK_PIN, SD_MOSI_PIN);
|
||||
}
|
||||
|
||||
uint8_t spiRec() { return spiTransfer(0xFF); }
|
||||
|
||||
void spiRead(uint8_t*buf, uint16_t nbyte) {
|
||||
for (int i = 0; i < nbyte; i++)
|
||||
buf[i] = spiTransfer(0xFF);
|
||||
}
|
||||
|
||||
void spiSend(uint8_t b) { (void)spiTransfer(b); }
|
||||
|
||||
void spiSend(const uint8_t *buf, size_t nbyte) {
|
||||
for (uint16_t i = 0; i < nbyte; i++)
|
||||
(void)spiTransfer(buf[i]);
|
||||
}
|
||||
|
||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
||||
(void)spiTransfer(token);
|
||||
for (uint16_t i = 0; i < 512; i++)
|
||||
(void)spiTransfer(buf[i]);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#ifdef SD_SPI_SPEED
|
||||
#define INIT_SPI_SPEED SD_SPI_SPEED
|
||||
#else
|
||||
#define INIT_SPI_SPEED SPI_FULL_SPEED
|
||||
#endif
|
||||
|
||||
void spiBegin() { spiInit(INIT_SPI_SPEED); } // Set up SCK, MOSI & MISO pins for SSP0
|
||||
|
||||
void spiInit(uint8_t spiRate) {
|
||||
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
|
||||
SPI.setModule(1);
|
||||
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
|
||||
SPI.setModule(2);
|
||||
#endif
|
||||
SPI.setDataSize(DATA_SIZE_8BIT);
|
||||
SPI.setDataMode(SPI_MODE0);
|
||||
|
||||
SPI.setClock(SPISettings::spiRate2Clock(spiRate));
|
||||
SPI.begin();
|
||||
}
|
||||
|
||||
static uint8_t doio(uint8_t b) {
|
||||
return SPI.transfer(b & 0x00FF) & 0x00FF;
|
||||
}
|
||||
|
||||
void spiSend(uint8_t b) { doio(b); }
|
||||
|
||||
void spiSend(const uint8_t *buf, size_t nbyte) {
|
||||
for (uint16_t i = 0; i < nbyte; i++) doio(buf[i]);
|
||||
}
|
||||
|
||||
void spiSend(uint32_t chan, byte b) {}
|
||||
|
||||
void spiSend(uint32_t chan, const uint8_t *buf, size_t nbyte) {}
|
||||
|
||||
// Read single byte from SPI
|
||||
uint8_t spiRec() { return doio(0xFF); }
|
||||
|
||||
uint8_t spiRec(uint32_t chan) { return 0; }
|
||||
|
||||
// Read from SPI into buffer
|
||||
void spiRead(uint8_t *buf, uint16_t nbyte) {
|
||||
for (uint16_t i = 0; i < nbyte; i++) buf[i] = doio(0xFF);
|
||||
}
|
||||
|
||||
uint8_t spiTransfer(uint8_t b) { return doio(b); }
|
||||
|
||||
// Write from buffer to SPI
|
||||
void spiSendBlock(uint8_t token, const uint8_t *buf) {
|
||||
(void)spiTransfer(token);
|
||||
for (uint16_t i = 0; i < 512; i++)
|
||||
(void)spiTransfer(buf[i]);
|
||||
}
|
||||
|
||||
// Begin SPI transaction, set clock, bit order, data mode
|
||||
void spiBeginTransaction(uint32_t spiClock, uint8_t bitOrder, uint8_t dataMode) {
|
||||
// TODO: Implement this method
|
||||
}
|
||||
|
||||
#endif // LPC_SOFTWARE_SPI
|
||||
|
||||
// /**
|
||||
// * @brief Wait until TXE (tx empty) flag is set and BSY (busy) flag unset.
|
||||
// */
|
||||
static inline void waitSpiTxEnd(void *spi_d) {
|
||||
// while (SSP_GetStatus(spi_d, SSP_STAT_TXFIFO_EMPTY) == RESET) { /* nada */ } // wait until TXE=1
|
||||
// while (SSP_GetStatus(spi_d, SSP_STAT_BUSY) == SET) { /* nada */ } // wait until BSY=0
|
||||
}
|
||||
|
||||
// // Retain the pin init state of the SPI, to avoid init more than once,
|
||||
// // even if more instances of SPIClass exist
|
||||
static bool spiInitialised[BOARD_NR_SPI] = {};
|
||||
|
||||
SPIClass::SPIClass(uint8_t device) {
|
||||
// // Init things specific to each SPI device
|
||||
// // clock divider setup is a bit of hack, and needs to be improved at a later date.
|
||||
|
||||
#if BOARD_NR_SPI >= 1
|
||||
_settings[0].device_id = 0;
|
||||
_settings[0].m_config.pin_miso = BOARD_SPI1_MISO_PIN;
|
||||
_settings[0].m_config.pin_mosi = BOARD_SPI1_MOSI_PIN;
|
||||
_settings[0].m_config.pin_sck = BOARD_SPI1_SCK_PIN;
|
||||
_settings[0].m_config.pin_ssel = BOARD_SPI1_NSS_PIN;
|
||||
_settings[0].m_config.frequency = 100000;
|
||||
_settings[0].m_config.data_bits = 8;
|
||||
_settings[0].m_config.mode = 0;
|
||||
_settings[0].m_config.format = MCUI::SSP::Config::Format::SPI;
|
||||
|
||||
|
||||
// _settings[0].dataMode = SPI_MODE0;
|
||||
// _settings[0].dataSize = DATA_SIZE_8BIT;
|
||||
// _settings[0].clock = SPI_CLOCK_MAX;
|
||||
// //_settings[0].clockDivider = determine_baud_rate(_settings[0].spi_d, _settings[0].clock);
|
||||
#endif
|
||||
|
||||
#if BOARD_NR_SPI >= 2
|
||||
_settings[1].device_id = 2;
|
||||
_settings[1].m_config.pin_miso = BOARD_SPI2_MISO_PIN;
|
||||
_settings[1].m_config.pin_mosi = BOARD_SPI2_MOSI_PIN;
|
||||
_settings[1].m_config.pin_sck = BOARD_SPI2_SCK_PIN;
|
||||
_settings[1].m_config.pin_ssel = BOARD_SPI2_NSS_PIN;
|
||||
// _settings[1].dataMode = SPI_MODE0;
|
||||
// _settings[1].dataSize = DATA_SIZE_8BIT;
|
||||
// _settings[1].clock = SPI_CLOCK_MAX;
|
||||
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
|
||||
#endif
|
||||
|
||||
#if BOARD_NR_SPI >= 3
|
||||
_settings[2].device_id = 1;
|
||||
_settings[2].m_config.pin_miso = BOARD_SPI3_MISO_PIN;
|
||||
_settings[2].m_config.pin_mosi = BOARD_SPI3_MOSI_PIN;
|
||||
_settings[2].m_config.pin_sck = BOARD_SPI3_SCK_PIN;
|
||||
_settings[2].m_config.pin_ssel = BOARD_SPI3_NSS_PIN;
|
||||
// _settings[1].dataMode = SPI_MODE0;
|
||||
// _settings[1].dataSize = DATA_SIZE_8BIT;
|
||||
// _settings[1].clock = SPI_CLOCK_MAX;
|
||||
// //_settings[1].clockDivider = determine_baud_rate(_settings[1].spi_d, _settings[1].clock);
|
||||
#endif
|
||||
|
||||
setModule(device);
|
||||
|
||||
// // Init the GPDMA controller
|
||||
// // TODO: call once in the constructor? or each time?
|
||||
// GPDMA_Init();
|
||||
}
|
||||
|
||||
SPIClass::SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel) {
|
||||
#if BOARD_NR_SPI >= 1
|
||||
if (mosi == BOARD_SPI1_MOSI_PIN) SPIClass(1);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 2
|
||||
if (mosi == BOARD_SPI2_MOSI_PIN) SPIClass(2);
|
||||
#endif
|
||||
#if BOARD_NR_SPI >= 3
|
||||
if (mosi == BOARD_SPI3_MOSI_PIN) SPIClass(3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void SPIClass::begin() {
|
||||
// // Init the SPI pins in the first begin call
|
||||
if ((_currentSetting->device_id == 0 && spiInitialised[0] == false) ||
|
||||
(_currentSetting->device_id == 1 && spiInitialised[1] == false) ||
|
||||
(_currentSetting->device_id == 2 && spiInitialised[2] == false)) {
|
||||
MCUI::SSP::init(_currentSetting->device_id, _currentSetting->m_config);
|
||||
spiInitialised[_currentSetting->device_id] = true;
|
||||
}
|
||||
updateSettings();
|
||||
}
|
||||
|
||||
void SPIClass::beginTransaction(const SPISettings &cfg) {
|
||||
setBitOrder(cfg.bitOrder);
|
||||
setDataMode(cfg.dataMode);
|
||||
setDataSize(cfg.dataSize);
|
||||
//setClockDivider(determine_baud_rate(_currentSetting->spi_d, settings.clock));
|
||||
begin();
|
||||
}
|
||||
|
||||
uint8_t SPIClass::transfer(const uint16_t b) {
|
||||
uint16_t rx_word = 0;
|
||||
// clear rx fifo
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) == 1);
|
||||
MCUI::SSP::write(_currentSetting->device_id, b);
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) != 1);
|
||||
return rx_word;
|
||||
}
|
||||
|
||||
uint16_t SPIClass::transfer16(const uint16_t data) {
|
||||
return (transfer((data >> 8) & 0xFF) << 8) | (transfer(data & 0xFF) & 0xFF);
|
||||
}
|
||||
|
||||
void SPIClass::end() {
|
||||
// // Neither is needed for Marlin
|
||||
// //SSP_Cmd(_currentSetting->spi_d, DISABLE);
|
||||
// //SSP_DeInit(_currentSetting->spi_d);
|
||||
}
|
||||
|
||||
void SPIClass::send(uint8_t data) {
|
||||
MCUI::SSP::write(_currentSetting->device_id, data);
|
||||
}
|
||||
|
||||
void SPIClass::dmaSend(void *buf, uint16_t length, bool minc) {
|
||||
// //TODO: LPC dma can only write 0xFFF bytes at once.
|
||||
// GPDMA_Channel_CFG_Type GPDMACfg;
|
||||
|
||||
// /* Configure GPDMA channel 0 -------------------------------------------------------------*/
|
||||
// /* DMA Channel 0 */
|
||||
// GPDMACfg.ChannelNum = 0;
|
||||
// // Source memory
|
||||
// GPDMACfg.SrcMemAddr = (uint32_t)buf;
|
||||
// // Destination memory - Not used
|
||||
// GPDMACfg.DstMemAddr = 0;
|
||||
// // Transfer size
|
||||
// GPDMACfg.TransferSize = length;
|
||||
// // Transfer width
|
||||
// GPDMACfg.TransferWidth = (_currentSetting->dataSize == DATA_SIZE_16BIT) ? GPDMA_WIDTH_HALFWORD : GPDMA_WIDTH_BYTE;
|
||||
// // Transfer type
|
||||
// GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
|
||||
// // Source connection - unused
|
||||
// GPDMACfg.SrcConn = 0;
|
||||
// // Destination connection
|
||||
// GPDMACfg.DstConn = (_currentSetting->spi_d == LPC_SSP0) ? GPDMA_CONN_SSP0_Tx : GPDMA_CONN_SSP1_Tx;
|
||||
|
||||
// GPDMACfg.DMALLI = 0;
|
||||
|
||||
// // Enable dma on SPI
|
||||
// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, ENABLE);
|
||||
|
||||
// // Only increase memory if minc is true
|
||||
// GPDMACfg.MemoryIncrease = (minc ? GPDMA_DMACCxControl_SI : 0);
|
||||
|
||||
// // Setup channel with given parameter
|
||||
// GPDMA_Setup(&GPDMACfg);
|
||||
|
||||
// // Enable DMA
|
||||
// GPDMA_ChannelCmd(0, ENABLE);
|
||||
|
||||
// // Wait for data transfer
|
||||
// while (!GPDMA_IntGetStatus(GPDMA_STAT_RAWINTTC, 0) && !GPDMA_IntGetStatus(GPDMA_STAT_RAWINTERR, 0)) { }
|
||||
|
||||
// // Clear err and int
|
||||
// GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, 0);
|
||||
// GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, 0);
|
||||
|
||||
// // Disable DMA
|
||||
// GPDMA_ChannelCmd(0, DISABLE);
|
||||
|
||||
// waitSpiTxEnd(_currentSetting->spi_d);
|
||||
|
||||
// SSP_DMACmd(_currentSetting->spi_d, SSP_DMA_TX, DISABLE);
|
||||
}
|
||||
|
||||
uint16_t SPIClass::read() {
|
||||
uint16_t rx_word = 0;
|
||||
MCUI::SSP::read(_currentSetting->device_id, &rx_word);
|
||||
return rx_word;
|
||||
}
|
||||
|
||||
void SPIClass::read(uint8_t *buf, uint32_t len) {
|
||||
uint16_t rx_word = 0;
|
||||
// clear rx fifo
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) == 1);
|
||||
for (uint16_t i = 0; i < len; i++) {
|
||||
MCUI::SSP::write(_currentSetting->device_id, 0xFF);
|
||||
while(MCUI::SSP::read(_currentSetting->device_id, &rx_word) != 1);
|
||||
buf[i] = rx_word;
|
||||
}
|
||||
}
|
||||
|
||||
void SPIClass::setClock(uint32_t clock) { _currentSetting->clock = clock; }
|
||||
|
||||
void SPIClass::setModule(uint8_t device) { _currentSetting = &_settings[device - 1]; } // SPI channels are called 1, 2, and 3 but the array is zero-indexed
|
||||
|
||||
void SPIClass::setBitOrder(uint8_t bitOrder) { _currentSetting->bitOrder = bitOrder; }
|
||||
|
||||
void SPIClass::setDataMode(uint8_t dataMode) { _currentSetting->dataMode = dataMode; }
|
||||
|
||||
void SPIClass::setDataSize(uint32_t dataSize) { _currentSetting->dataSize = dataSize; }
|
||||
|
||||
// /**
|
||||
// * Set up/tear down
|
||||
// */
|
||||
void SPIClass::updateSettings() {
|
||||
MCUI::SSP::configure(_currentSetting->device_id, _currentSetting->m_config);
|
||||
}
|
||||
|
||||
SPIClass SPI(1);
|
||||
|
||||
#if SD_MISO_PIN == BOARD_SPI1_MISO_PIN
|
||||
SPIClass SPI(1);
|
||||
#elif SD_MISO_PIN == BOARD_SPI2_MISO_PIN
|
||||
SPIClass SPI(2);
|
||||
#endif
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,45 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <SPI.h>
|
||||
|
||||
/**
|
||||
* Marlin currently requires 3 SPI classes:
|
||||
*
|
||||
* SPIClass:
|
||||
* This class is normally provided by frameworks and has a semi-default interface.
|
||||
* This is needed because some libraries reference it globally.
|
||||
*
|
||||
* SPISettings:
|
||||
* Container for SPI configs for SPIClass. As above, libraries may reference it globally.
|
||||
*
|
||||
* These two classes are often provided by frameworks so we cannot extend them to add
|
||||
* useful methods for Marlin.
|
||||
*
|
||||
* MarlinSPI:
|
||||
* Provides the default SPIClass interface plus some Marlin goodies such as a simplified
|
||||
* interface for SPI DMA transfer.
|
||||
*
|
||||
*/
|
||||
|
||||
using MarlinSPI = SPIClass;
|
||||
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "MarlinSerial.h"
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
MarlinCDCSerial MCDCSerial0;
|
||||
|
||||
#define MarlinSerial(ID) \
|
||||
MarlinSerial _MSerial##ID(ID); \
|
||||
MSerialT MSerial##ID(true, _MSerial##ID)
|
||||
|
||||
#if USING_HW_SERIAL0
|
||||
MarlinSerial(0);
|
||||
#endif
|
||||
#if USING_HW_SERIAL1
|
||||
MarlinSerial(1);
|
||||
#endif
|
||||
#if USING_HW_SERIAL2
|
||||
MarlinSerial(2);
|
||||
#endif
|
||||
#if USING_HW_SERIAL3
|
||||
MarlinSerial(3);
|
||||
#endif
|
||||
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
|
||||
bool MarlinSerial::recv_callback(const char c) {
|
||||
// Need to figure out which serial port we are and react in consequence (Marlin does not have CONTAINER_OF macro)
|
||||
if (false) {}
|
||||
#if USING_HW_SERIAL0
|
||||
else if (this == &_MSerial0) emergency_parser.update(MSerial0.emergency_state, c);
|
||||
#endif
|
||||
#if USING_HW_SERIAL1
|
||||
else if (this == &_MSerial1) emergency_parser.update(MSerial1.emergency_state, c);
|
||||
#endif
|
||||
#if USING_HW_SERIAL2
|
||||
else if (this == &_MSerial2) emergency_parser.update(MSerial2.emergency_state, c);
|
||||
#endif
|
||||
#if USING_HW_SERIAL3
|
||||
else if (this == &_MSerial3) emergency_parser.update(MSerial3.emergency_state, c);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "../../feature/e_parser.h"
|
||||
|
||||
EmergencyParser::State emergency_state;
|
||||
|
||||
bool CDC_RecvCallback(const char c) {
|
||||
emergency_parser.update(emergency_state, c);
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,108 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <mcu_interface.h>
|
||||
#include <interface/uart.h>
|
||||
#include <driver/usb_cdc.h>
|
||||
|
||||
#include <UART.h>
|
||||
|
||||
#include "../../inc/MarlinConfigPre.h"
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
#include "../../feature/e_parser.h"
|
||||
#endif
|
||||
#include "../../core/serial_hook.h"
|
||||
|
||||
#ifndef SERIAL_PORT
|
||||
#define SERIAL_PORT 0
|
||||
#endif
|
||||
#ifndef RX_BUFFER_SIZE
|
||||
#define RX_BUFFER_SIZE 128
|
||||
#endif
|
||||
#ifndef TX_BUFFER_SIZE
|
||||
#define TX_BUFFER_SIZE 32
|
||||
#endif
|
||||
|
||||
class MarlinCDCSerial : public HardwareSerial {
|
||||
public:
|
||||
MarlinCDCSerial() {}
|
||||
void begin(unsigned long baudrate) override {}
|
||||
void begin(unsigned long baudrate, uint16_t config) override { }
|
||||
void end() override { }
|
||||
int available() override {
|
||||
return MCUI::CDCSerial0::available();
|
||||
}
|
||||
int peek() override { char c = 0; return MCUI::CDCSerial0::peek((uint8_t*)&c)? c : -1; }
|
||||
int read() override { char c = 0; return MCUI::CDCSerial0::read((uint8_t*)&c, 1)? c : -1; }
|
||||
void flush() override {};
|
||||
size_t write(uint8_t c) override { return write(&c, 1); }
|
||||
size_t write(const uint8_t *buffer, size_t size) override { return MCUI::CDCSerial0::connected() ? MCUI::CDCSerial0::write(buffer, size) : 0; }
|
||||
using Print::write;
|
||||
operator bool() override { return true; }
|
||||
};
|
||||
extern MarlinCDCSerial MCDCSerial0;
|
||||
|
||||
class MarlinSerial : public HardwareSerial {
|
||||
public:
|
||||
MarlinSerial(const uint32_t uart_id) : uart_device(uart_id) {}
|
||||
void begin(unsigned long baudrate) override {
|
||||
uart_device.configure_pins(P0_02, P0_03);
|
||||
uart_device.init({ .baud = baudrate });
|
||||
#if ENABLED(EMERGENCY_PARSER)
|
||||
uart_device.set_rx_callback([this](char rx_value){ return this->recv_callback(rx_value); } );
|
||||
#endif
|
||||
}
|
||||
void begin(unsigned long baudrate, uint16_t config) override {
|
||||
begin(baudrate);
|
||||
}
|
||||
void end() override { }
|
||||
int available() override {
|
||||
return uart_device.rx_available();
|
||||
}
|
||||
int peek() override { char c = 0; return uart_device.peek(&c)? c : -1; }
|
||||
int read() override { char c = 0; return uart_device.read(&c)? c : -1; }
|
||||
void flush() override {};
|
||||
size_t write(uint8_t c) override { return write(&c, 1); }
|
||||
size_t write(const uint8_t *buffer, size_t size) override { return uart_device.write((const char *)buffer, size); }
|
||||
using Print::write; // pull in write(str) and write(buf, size) from Print
|
||||
operator bool() override { return true; }
|
||||
|
||||
bool recv_callback(char value);
|
||||
private:
|
||||
MCUI::BufferedUARTC uart_device;
|
||||
};
|
||||
|
||||
// On LPC176x framework, HardwareSerial does not implement the same interface as Arduino's Serial, so overloads
|
||||
// of 'available' and 'read' method are not used in this multiple inheritance scenario.
|
||||
// Instead, use a ForwardSerial here that adapts the interface.
|
||||
typedef ForwardSerial1Class<MarlinSerial> MSerialT;
|
||||
extern MSerialT MSerial0;
|
||||
extern MSerialT MSerial1;
|
||||
extern MSerialT MSerial2;
|
||||
extern MSerialT MSerial3;
|
||||
|
||||
// Consequently, we can't use a RuntimeSerial either. The workaround would be to use
|
||||
// a RuntimeSerial<ForwardSerial<MarlinSerial>> type here. Ignore for now until it's actually required.
|
||||
#if ENABLED(SERIAL_RUNTIME_HOOK)
|
||||
#error "SERIAL_RUNTIME_HOOK is not yet supported for LPC176x."
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "HAL.h"
|
||||
|
||||
#if ENABLED(POSTMORTEM_DEBUGGING)
|
||||
|
||||
#include "../shared/MinSerial.h"
|
||||
#include <debug_frmwrk.h>
|
||||
|
||||
static void TX(char c) { _DBC(c); }
|
||||
void install_min_serial() { HAL_min_serial_out = &TX; }
|
||||
|
||||
#if DISABLED(DYNAMIC_VECTORTABLE)
|
||||
extern "C" {
|
||||
__attribute__((naked)) void JumpHandler_ASM() {
|
||||
__asm__ __volatile__ (
|
||||
"b CommonHandler_ASM\n"
|
||||
);
|
||||
}
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) HardFault_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) BusFault_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) UsageFault_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) MemManage_Handler();
|
||||
void __attribute__((naked, alias("JumpHandler_ASM"))) NMI_Handler();
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // POSTMORTEM_DEBUGGING
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,69 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* servo.h - Interrupt driven Servo library for Arduino using 16 bit timers- Version 2
|
||||
* Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Based on "servo.h - Interrupt driven Servo library for Arduino using 16 bit timers -
|
||||
* Version 2 Copyright (c) 2009 Michael Margolis. All right reserved.
|
||||
*
|
||||
* The only modification was to update/delete macros to match the LPC176x.
|
||||
*/
|
||||
|
||||
#include <Servo.h>
|
||||
|
||||
class libServo: public Servo {
|
||||
public:
|
||||
void move(const int value) {
|
||||
constexpr uint16_t servo_delay[] = SERVO_DELAY;
|
||||
static_assert(COUNT(servo_delay) == NUM_SERVOS, "SERVO_DELAY must be an array NUM_SERVOS long.");
|
||||
|
||||
if (attach(servo_info[servoIndex].Pin.nbr) >= 0) { // try to reattach
|
||||
write(value);
|
||||
safe_delay(servo_delay[servoIndex]); // delay to allow servo to reach position
|
||||
TERN_(DEACTIVATE_SERVOS_AFTER_MOVE, detach());
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class libServo;
|
||||
typedef libServo hal_servo_t;
|
||||
@@ -0,0 +1,47 @@
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include <Arduino.h>
|
||||
#include "SoftwareSPI.h"
|
||||
|
||||
#include <mcu_interface.h>
|
||||
|
||||
uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
|
||||
for (uint8_t i = 0; i < 8; i++) {
|
||||
if (spi_speed == 0) {
|
||||
MCUI::gpio_set(mosi_pin, !!(b & 0x80));
|
||||
MCUI::gpio_set(sck_pin, HIGH);
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1;
|
||||
MCUI::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
else {
|
||||
const uint8_t state = (b & 0x80) ? HIGH : LOW;
|
||||
for (uint8_t j = 0; j < spi_speed; j++)
|
||||
MCUI::gpio_set(mosi_pin, state);
|
||||
|
||||
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
|
||||
MCUI::gpio_set(sck_pin, HIGH);
|
||||
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && MCUI::gpio_get(miso_pin)) b |= 1;
|
||||
|
||||
for (uint8_t j = 0; j < spi_speed; j++)
|
||||
MCUI::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin) {
|
||||
pinMode(sck_pin, OUTPUT);
|
||||
if (MCUI::pin_is_valid(miso_pin)) pinMode(miso_pin, INPUT);
|
||||
pinMode(mosi_pin, OUTPUT);
|
||||
}
|
||||
|
||||
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin) {
|
||||
MCUI::gpio_set(mosi_pin, HIGH);
|
||||
MCUI::gpio_set(sck_pin, LOW);
|
||||
return (SystemCoreClock == 120000000 ? 44 : 38) / std::pow(2, 6 - std::min(spiRate, (uint8_t)6));
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,5 @@
|
||||
#include <mcu_interface.h>
|
||||
|
||||
uint8_t swSpiTransfer(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin);
|
||||
void swSpiBegin(const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin);
|
||||
uint8_t swSpiInit(const uint8_t spiRate, const pin_t sck_pin, const pin_t mosi_pin);
|
||||
@@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
/**
|
||||
* Emulate EEPROM storage using Flash Memory
|
||||
*
|
||||
* Use a single 32K flash sector to store EEPROM data. To reduce the
|
||||
* number of erase operations a simple "leveling" scheme is used that
|
||||
* maintains a number of EEPROM "slots" within the larger flash sector.
|
||||
* Each slot is used in turn and the entire sector is only erased when all
|
||||
* slots have been used.
|
||||
*
|
||||
* A simple RAM image is used to hold the EEPROM data during I/O operations
|
||||
* and this is flushed to the next available slot when an update is complete.
|
||||
* If RAM usage becomes an issue we could store this image in one of the two
|
||||
* 16Kb I/O buffers (intended to hold DMA USB and Ethernet data, but currently
|
||||
* unused).
|
||||
*/
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
#include "../shared/eeprom_api.h"
|
||||
|
||||
//#include <cstdio>
|
||||
|
||||
#ifndef MARLIN_EEPROM_SIZE
|
||||
#define MARLIN_EEPROM_SIZE 4032 // 4KB
|
||||
#endif
|
||||
|
||||
size_t PersistentStore::capacity() { return 4032; }
|
||||
|
||||
constexpr uint32_t page_size = MCUI::EEPROM::page_size;
|
||||
uint32_t buffered_page = 0;
|
||||
uint8_t page_buffer[page_size];
|
||||
bool buffered_page_dirty = false;
|
||||
|
||||
bool PersistentStore::access_start() {
|
||||
MCUI::EEPROM::init();
|
||||
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::access_finish() {
|
||||
if (buffered_page_dirty) {
|
||||
MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
|
||||
uint32_t address = pos;
|
||||
//printf("Marlin::eeprom::write(pos = %d, size = %d)\n", pos, size);
|
||||
uint32_t value_index = 0;
|
||||
for (uint32_t addr = address; addr < address + size; ++addr) {
|
||||
uint32_t page_address = addr & 0xFFFFFFC0;
|
||||
if (page_address != buffered_page) {
|
||||
//printf("Marlin::eeprom::write(@%ld):: page change new(%ld) != current(%d)\n",addr, page_address, buffered_page);
|
||||
if (buffered_page_dirty == true) MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
|
||||
buffered_page = page_address;
|
||||
buffered_page_dirty = false;
|
||||
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
|
||||
}
|
||||
page_buffer[addr & ~0xFFFFFFC0] = value[value_index++];
|
||||
buffered_page_dirty = true;
|
||||
}
|
||||
|
||||
pos += size;
|
||||
crc16(crc, value, size);
|
||||
|
||||
return false; // return true for any error
|
||||
}
|
||||
|
||||
bool PersistentStore::read_data(int &pos, uint8_t *value, size_t size, uint16_t *crc, const bool writing/*=true*/) {
|
||||
uint32_t address = pos;
|
||||
//printf("Marlin::eeprom::read(pos = %d, size = %d, writing = %d)\n", pos, size, writing);
|
||||
uint32_t value_index = 0;
|
||||
for (uint32_t addr = address; addr < address + size; ++addr) {
|
||||
uint32_t page_address = addr & 0xFFFFFFC0;
|
||||
if (page_address != buffered_page) {
|
||||
if (buffered_page_dirty) {
|
||||
MCUI::EEPROM::write_page(buffered_page, page_buffer, page_size);
|
||||
buffered_page_dirty = false;
|
||||
}
|
||||
buffered_page = page_address;
|
||||
MCUI::EEPROM::read_page(buffered_page, page_buffer, page_size);
|
||||
}
|
||||
if (writing) value[value_index++] = page_buffer[addr & ~0xFFFFFFC0];
|
||||
else crc16(crc, &page_buffer[addr & ~0xFFFFFFC0], 1);
|
||||
}
|
||||
|
||||
if (writing) crc16(crc, value, size);
|
||||
pos += size;
|
||||
|
||||
return false; // return true for any error
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,191 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Endstop Interrupts
|
||||
*
|
||||
* Without endstop interrupts the endstop pins must be polled continually in
|
||||
* the temperature-ISR via endstops.update(), most of the time finding no change.
|
||||
* With this feature endstops.update() is called only when we know that at
|
||||
* least one endstop has changed state, saving valuable CPU cycles.
|
||||
*
|
||||
* This feature only works when all used endstop pins can generate an 'external interrupt'.
|
||||
*
|
||||
* Test whether pins issue interrupts on your board by flashing 'pin_interrupt_test.ino'.
|
||||
* (Located in Marlin/buildroot/share/pin_interrupt_test/pin_interrupt_test.ino)
|
||||
*/
|
||||
|
||||
#include "../../module/endstops.h"
|
||||
|
||||
// One ISR for all EXT-Interrupts
|
||||
void endstop_ISR() { endstops.update(); }
|
||||
|
||||
void setup_endstop_interrupts() {
|
||||
#define _ATTACH(P) attachInterrupt(digitalPinToInterrupt(P), endstop_ISR, CHANGE)
|
||||
#define LPC1768_PIN_INTERRUPT_M(pin) ((pin >> 0x5 & 0x7) == 0 || (pin >> 0x5 & 0x7) == 2)
|
||||
|
||||
#if HAS_X_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(X_MAX_PIN)
|
||||
#error "X_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(X_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_X_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(X_MIN_PIN)
|
||||
#error "X_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(X_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Y_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Y_MAX_PIN)
|
||||
#error "Y_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Y_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Y_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Y_MIN_PIN)
|
||||
#error "Y_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Y_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z_MAX_PIN)
|
||||
#error "Z_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PIN)
|
||||
#error "Z_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z2_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z2_MAX_PIN)
|
||||
#error "Z2_MAX_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z2_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z2_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z2_MIN_PIN)
|
||||
#error "Z2_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z2_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z3_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z3_MAX_PIN)
|
||||
#error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z3_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z3_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z3_MIN_PIN)
|
||||
#error "Z3_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z3_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z4_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z4_MAX_PIN)
|
||||
#error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z4_MAX_PIN);
|
||||
#endif
|
||||
#if HAS_Z4_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z4_MIN_PIN)
|
||||
#error "Z4_MIN_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z4_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_Z_MIN_PROBE_PIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(Z_MIN_PROBE_PIN)
|
||||
#error "Z_MIN_PROBE_PIN is not INTERRUPT-capable. Disable ENDSTOP_INTERRUPTS_FEATURE to continue."
|
||||
#endif
|
||||
_ATTACH(Z_MIN_PROBE_PIN);
|
||||
#endif
|
||||
#if HAS_I_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(I_MAX_PIN)
|
||||
#error "I_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(I_MAX_PIN);
|
||||
#elif HAS_I_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(I_MIN_PIN)
|
||||
#error "I_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(I_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_J_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(J_MAX_PIN)
|
||||
#error "J_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(J_MAX_PIN);
|
||||
#elif HAS_J_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(J_MIN_PIN)
|
||||
#error "J_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(J_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_K_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(K_MAX_PIN)
|
||||
#error "K_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(K_MAX_PIN);
|
||||
#elif HAS_K_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(K_MIN_PIN)
|
||||
#error "K_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(K_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_U_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(U_MAX_PIN)
|
||||
#error "U_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(U_MAX_PIN);
|
||||
#elif HAS_U_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(U_MIN_PIN)
|
||||
#error "U_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(U_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_V_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(V_MAX_PIN)
|
||||
#error "V_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(V_MAX_PIN);
|
||||
#elif HAS_V_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(V_MIN_PIN)
|
||||
#error "V_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(V_MIN_PIN);
|
||||
#endif
|
||||
#if HAS_W_MAX
|
||||
#if !LPC1768_PIN_INTERRUPT_M(W_MAX_PIN)
|
||||
#error "W_MAX_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(W_MAX_PIN);
|
||||
#elif HAS_W_MIN
|
||||
#if !LPC1768_PIN_INTERRUPT_M(W_MIN_PIN)
|
||||
#error "W_MIN_PIN is not INTERRUPT-capable."
|
||||
#endif
|
||||
_ATTACH(W_MIN_PIN);
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include <mcu_interface.h>
|
||||
|
||||
void MarlinHAL::set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
|
||||
if (!MCUI::pin_is_valid(pin)) return;
|
||||
if (MCUI::pwm_attach_pin(pin))
|
||||
MCUI::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size); // map 1-254 onto PWM range
|
||||
}
|
||||
|
||||
void MarlinHAL::set_pwm_frequency(const pin_t pin, const uint16_t f_desired) {
|
||||
MCUI::pwm_set_frequency(pin, f_desired);
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,120 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Fast I/O Routines for LPC1768/9
|
||||
* Use direct port manipulation to save scads of processor time.
|
||||
* Contributed by Triffid_Hunter and modified by Kliment, thinkyhead, Bob-the-Kuhn, et.al.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Description: Fast IO functions LPC1768
|
||||
*
|
||||
* For TARGET LPC1768
|
||||
*/
|
||||
|
||||
#include "../shared/Marduino.h"
|
||||
#include <mcu_interface.h>
|
||||
|
||||
#define PWM_PIN(P) true // all pins are software PWM capable
|
||||
|
||||
#define LPC_PIN(pin) MCUI::gpio_pin(pin)
|
||||
#define LPC_GPIO(port) MCUI::gpio_port(port)
|
||||
|
||||
#define SET_DIR_INPUT(IO) MCUI::gpio_set_input(IO)
|
||||
#define SET_DIR_OUTPUT(IO) MCUI::gpio_set_output(IO)
|
||||
|
||||
#define SET_MODE(IO, mode) pinMode(IO, mode)
|
||||
|
||||
#define WRITE_PIN_SET(IO) MCUI::gpio_set(IO)
|
||||
#define WRITE_PIN_CLR(IO) MCUI::gpio_clear(IO)
|
||||
|
||||
#define READ_PIN(IO) MCUI::gpio_get(IO)
|
||||
#define WRITE_PIN(IO,V) MCUI::gpio_set(IO, V)
|
||||
|
||||
/**
|
||||
* Magic I/O routines
|
||||
*
|
||||
* Now you can simply SET_OUTPUT(STEP); WRITE(STEP, HIGH); WRITE(STEP, LOW);
|
||||
*
|
||||
* Why double up on these macros? see https://gcc.gnu.org/onlinedocs/gcc-4.8.5/cpp/Stringification.html
|
||||
*/
|
||||
|
||||
/// Read a pin
|
||||
#define _READ(IO) READ_PIN(IO)
|
||||
|
||||
/// Write to a pin
|
||||
#define _WRITE(IO,V) WRITE_PIN(IO,V)
|
||||
|
||||
/// toggle a pin
|
||||
#define _TOGGLE(IO) MCUI::gpio_toggle(IO)
|
||||
|
||||
/// set pin as input
|
||||
#define _SET_INPUT(IO) SET_DIR_INPUT(IO)
|
||||
|
||||
/// set pin as output
|
||||
#define _SET_OUTPUT(IO) SET_DIR_OUTPUT(IO)
|
||||
|
||||
/// set pin as input with pullup mode
|
||||
#define _PULLUP(IO,V) pinMode(IO, (V) ? INPUT_PULLUP : INPUT)
|
||||
|
||||
/// set pin as input with pulldown mode
|
||||
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
|
||||
|
||||
/// check if pin is an input
|
||||
#define _IS_INPUT(IO) (!MCUI::gpio_get_dir(IO))
|
||||
|
||||
/// check if pin is an output
|
||||
#define _IS_OUTPUT(IO) (MCUI::gpio_get_dir(IO))
|
||||
|
||||
/// Read a pin wrapper
|
||||
#define READ(IO) _READ(IO)
|
||||
|
||||
/// Write to a pin wrapper
|
||||
#define WRITE(IO,V) _WRITE(IO,V)
|
||||
|
||||
/// toggle a pin wrapper
|
||||
#define TOGGLE(IO) _TOGGLE(IO)
|
||||
|
||||
/// set pin as input wrapper
|
||||
#define SET_INPUT(IO) _SET_INPUT(IO)
|
||||
/// set pin as input with pullup wrapper
|
||||
#define SET_INPUT_PULLUP(IO) do{ _SET_INPUT(IO); _PULLUP(IO, HIGH); }while(0)
|
||||
/// set pin as input with pulldown wrapper
|
||||
#define SET_INPUT_PULLDOWN(IO) do{ _SET_INPUT(IO); _PULLDOWN(IO, HIGH); }while(0)
|
||||
/// set pin as output wrapper - reads the pin and sets the output to that value
|
||||
#define SET_OUTPUT(IO) do{ _WRITE(IO, _READ(IO)); _SET_OUTPUT(IO); }while(0)
|
||||
// set pin as PWM
|
||||
#define SET_PWM SET_OUTPUT
|
||||
|
||||
/// check if pin is an input wrapper
|
||||
#define IS_INPUT(IO) _IS_INPUT(IO)
|
||||
/// check if pin is an output wrapper
|
||||
#define IS_OUTPUT(IO) _IS_OUTPUT(IO)
|
||||
|
||||
// Shorthand
|
||||
#define OUT_WRITE(IO,V) do{ SET_OUTPUT(IO); WRITE(IO,V); }while(0)
|
||||
|
||||
// digitalRead/Write wrappers
|
||||
#define extDigitalRead(IO) digitalRead(IO)
|
||||
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if DISABLED(NO_SD_HOST_DRIVE)
|
||||
#define HAS_SD_HOST_DRIVE 1
|
||||
#endif
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if USE_FALLBACK_EEPROM
|
||||
#define FLASH_EEPROM_EMULATION
|
||||
#elif ANY(I2C_EEPROM, SPI_EEPROM)
|
||||
#define USE_SHARED_EEPROM 1
|
||||
#endif
|
||||
|
||||
// LPC1768 boards seem to lose steps when saving to EEPROM during print (issue #20785)
|
||||
// TODO: Which other boards are incompatible?
|
||||
#if defined(MCU_LPC1768) && ENABLED(FLASH_EEPROM_EMULATION) && PRINTCOUNTER_SAVE_INTERVAL > 0
|
||||
#define PRINTCOUNTER_SYNC 1
|
||||
#endif
|
||||
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -0,0 +1,276 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
// #if PIO_PLATFORM_VERSION < 1001
|
||||
// #error "nxplpc-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries. You may need to remove the platform and let it reinstall automatically."
|
||||
// #endif
|
||||
// #if PIO_FRAMEWORK_VERSION < 2006
|
||||
// #error "framework-arduino-lpc176x package is out of date, Please update the PlatformIO platforms, frameworks and libraries."
|
||||
// #endif
|
||||
|
||||
/**
|
||||
* Detect an old pins file by checking for old ADC pins values.
|
||||
*/
|
||||
#define _OLD_TEMP_PIN(P) PIN_EXISTS(P) && _CAT(P,_PIN) <= 7 && !WITHIN(_CAT(P,_PIN), TERN(LPC1768_IS_SKRV1_3, 0, 2), 3) // Include P0_00 and P0_01 for SKR V1.3 board
|
||||
#if _OLD_TEMP_PIN(TEMP_BED)
|
||||
#error "TEMP_BED_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_0)
|
||||
#error "TEMP_0_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_1)
|
||||
#error "TEMP_1_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_2)
|
||||
#error "TEMP_2_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_3)
|
||||
#error "TEMP_3_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_4)
|
||||
#error "TEMP_4_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_5)
|
||||
#error "TEMP_5_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_6)
|
||||
#error "TEMP_6_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#elif _OLD_TEMP_PIN(TEMP_7)
|
||||
#error "TEMP_7_PIN must be defined using the Pn_nn or Pn_nn_An format. (See the included pins files)."
|
||||
#endif
|
||||
#undef _OLD_TEMP_PIN
|
||||
|
||||
/**
|
||||
* Because PWM hardware channels all share the same frequency, along with the
|
||||
* fallback software channels, FAST_PWM_FAN is incompatible with Servos.
|
||||
*/
|
||||
static_assert(!(NUM_SERVOS && ENABLED(FAST_PWM_FAN)), "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards.");
|
||||
|
||||
#if SPINDLE_LASER_FREQUENCY
|
||||
static_assert(!NUM_SERVOS, "BLTOUCH and Servos are incompatible with SPINDLE_LASER_FREQUENCY on LPC176x boards.");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Test LPC176x-specific configuration values for errors at compile-time.
|
||||
*/
|
||||
|
||||
//#if ENABLED(SPINDLE_LASER_USE_PWM) && !(SPINDLE_LASER_PWM_PIN == 4 || SPINDLE_LASER_PWM_PIN == 6 || SPINDLE_LASER_PWM_PIN == 11)
|
||||
// #error "SPINDLE_LASER_PWM_PIN must use SERVO0, SERVO1 or SERVO3 connector"
|
||||
//#endif
|
||||
|
||||
#if MB(RAMPS_14_RE_ARM_EFB, RAMPS_14_RE_ARM_EEB, RAMPS_14_RE_ARM_EFF, RAMPS_14_RE_ARM_EEF, RAMPS_14_RE_ARM_SF)
|
||||
#if IS_RRD_FG_SC && HAS_DRIVER(TMC2130) && DISABLED(TMC_USE_SW_SPI)
|
||||
#error "Re-ARM with REPRAP_DISCOUNT_FULL_GRAPHIC_SMART_CONTROLLER and TMC2130 requires TMC_USE_SW_SPI."
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static_assert(DISABLED(BAUD_RATE_GCODE), "BAUD_RATE_GCODE is not yet supported on LPC176x.");
|
||||
|
||||
/**
|
||||
* Flag any serial port conflicts
|
||||
*
|
||||
* Port | TX | RX |
|
||||
* --- | --- | --- |
|
||||
* Serial | P0_02 | P0_03 |
|
||||
* Serial1 | P0_15 | P0_16 |
|
||||
* Serial2 | P0_10 | P0_11 |
|
||||
* Serial3 | P0_00 | P0_01 |
|
||||
*/
|
||||
#define ANY_TX(N,V...) DO(IS_TX##N,||,V)
|
||||
#define ANY_RX(N,V...) DO(IS_RX##N,||,V)
|
||||
|
||||
#if USING_HW_SERIAL0
|
||||
#define IS_TX0(P) (P == P0_02)
|
||||
#define IS_RX0(P) (P == P0_03)
|
||||
#if IS_TX0(TMC_SW_MISO) || IS_RX0(TMC_SW_MOSI)
|
||||
#error "Serial port pins (0) conflict with Trinamic SPI pins!"
|
||||
#elif HAS_PRUSA_MMU1 && (IS_TX0(E_MUX1_PIN) || IS_RX0(E_MUX0_PIN))
|
||||
#error "Serial port pins (0) conflict with Multi-Material-Unit multiplexer pins!"
|
||||
#elif (AXIS_HAS_SPI(X) && IS_TX0(X_CS_PIN)) || (AXIS_HAS_SPI(Y) && IS_RX0(Y_CS_PIN))
|
||||
#error "Serial port pins (0) conflict with X/Y axis SPI pins!"
|
||||
#endif
|
||||
#undef IS_TX0
|
||||
#undef IS_RX0
|
||||
#endif
|
||||
|
||||
#if USING_HW_SERIAL1
|
||||
#define IS_TX1(P) (P == P0_15)
|
||||
#define IS_RX1(P) (P == P0_16)
|
||||
#define _IS_TX1_1 IS_TX1
|
||||
#define _IS_RX1_1 IS_RX1
|
||||
#if IS_TX1(TMC_SW_SCK)
|
||||
#error "Serial port pins (1) conflict with other pins!"
|
||||
#elif HAS_ROTARY_ENCODER
|
||||
#if IS_TX1(BTN_EN2) || IS_RX1(BTN_EN1)
|
||||
#error "Serial port pins (1) conflict with Encoder Buttons!"
|
||||
#elif ANY_TX(1, SD_SCK_PIN, LCD_PINS_D4, DOGLCD_SCK, LCD_RESET_PIN, LCD_PINS_RS, SHIFT_CLK_PIN) \
|
||||
|| ANY_RX(1, LCD_SDSS, LCD_PINS_RS, SD_MISO_PIN, DOGLCD_A0, SD_SS_PIN, LCD_SDSS, DOGLCD_CS, LCD_RESET_PIN, LCD_BACKLIGHT_PIN)
|
||||
#error "Serial port pins (1) conflict with LCD pins!"
|
||||
#endif
|
||||
#endif
|
||||
#undef IS_TX1
|
||||
#undef IS_RX1
|
||||
#undef _IS_TX1_1
|
||||
#undef _IS_RX1_1
|
||||
#endif
|
||||
|
||||
#if USING_HW_SERIAL2
|
||||
#define IS_TX2(P) (P == P0_10)
|
||||
#define IS_RX2(P) (P == P0_11)
|
||||
#define _IS_TX2_1 IS_TX2
|
||||
#define _IS_RX2_1 IS_RX2
|
||||
#if IS_TX2(X2_ENABLE_PIN) || ANY_RX(2, X2_DIR_PIN, X2_STEP_PIN) || (AXIS_HAS_SPI(X2) && IS_TX2(X2_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with X2 pins!"
|
||||
#elif IS_TX2(Y2_ENABLE_PIN) || ANY_RX(2, Y2_DIR_PIN, Y2_STEP_PIN) || (AXIS_HAS_SPI(Y2) && IS_TX2(Y2_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Y2 pins!"
|
||||
#elif IS_TX2(Z2_ENABLE_PIN) || ANY_RX(2, Z2_DIR_PIN, Z2_STEP_PIN) || (AXIS_HAS_SPI(Z2) && IS_TX2(Z2_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Z2 pins!"
|
||||
#elif IS_TX2(Z3_ENABLE_PIN) || ANY_RX(2, Z3_DIR_PIN, Z3_STEP_PIN) || (AXIS_HAS_SPI(Z3) && IS_TX2(Z3_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Z3 pins!"
|
||||
#elif IS_TX2(Z4_ENABLE_PIN) || ANY_RX(2, Z4_DIR_PIN, Z4_STEP_PIN) || (AXIS_HAS_SPI(Z4) && IS_TX2(Z4_CS_PIN))
|
||||
#error "Serial port pins (2) conflict with Z4 pins!"
|
||||
#elif ANY_RX(2, X_DIR_PIN, Y_DIR_PIN)
|
||||
#error "Serial port pins (2) conflict with other pins!"
|
||||
#elif Y_HOME_TO_MIN && IS_TX2(Y_STOP_PIN)
|
||||
#error "Serial port pins (2) conflict with Y endstop pin!"
|
||||
#elif USES_Z_MIN_PROBE_PIN && IS_TX2(Z_MIN_PROBE_PIN)
|
||||
#error "Serial port pins (2) conflict with probe pin!"
|
||||
#elif ANY_TX(2, X_ENABLE_PIN, Y_ENABLE_PIN) || ANY_RX(2, X_DIR_PIN, Y_DIR_PIN)
|
||||
#error "Serial port pins (2) conflict with X/Y stepper pins!"
|
||||
#elif HAS_MULTI_EXTRUDER && (IS_TX2(E1_ENABLE_PIN) || (AXIS_HAS_SPI(E1) && IS_TX2(E1_CS_PIN)))
|
||||
#error "Serial port pins (2) conflict with E1 stepper pins!"
|
||||
#elif EXTRUDERS && ANY_RX(2, E0_DIR_PIN, E0_STEP_PIN)
|
||||
#error "Serial port pins (2) conflict with E stepper pins!"
|
||||
#endif
|
||||
#undef IS_TX2
|
||||
#undef IS_RX2
|
||||
#undef _IS_TX2_1
|
||||
#undef _IS_RX2_1
|
||||
#endif
|
||||
|
||||
#if USING_HW_SERIAL3
|
||||
#define PIN_IS_TX3(P) (PIN_EXISTS(P) && P##_PIN == P0_00)
|
||||
#define PIN_IS_RX3(P) (P##_PIN == P0_01)
|
||||
#if PIN_IS_TX3(X_MIN) || PIN_IS_RX3(X_MAX)
|
||||
#error "Serial port pins (3) conflict with X endstop pins!"
|
||||
#elif PIN_IS_TX3(Y_SERIAL_TX) || PIN_IS_TX3(Y_SERIAL_RX) || PIN_IS_RX3(X_SERIAL_TX) || PIN_IS_RX3(X_SERIAL_RX)
|
||||
#error "Serial port pins (3) conflict with X/Y axis UART pins!"
|
||||
#elif PIN_IS_TX3(X2_DIR) || PIN_IS_RX3(X2_STEP)
|
||||
#error "Serial port pins (3) conflict with X2 pins!"
|
||||
#elif PIN_IS_TX3(Y2_DIR) || PIN_IS_RX3(Y2_STEP)
|
||||
#error "Serial port pins (3) conflict with Y2 pins!"
|
||||
#elif PIN_IS_TX3(Z2_DIR) || PIN_IS_RX3(Z2_STEP)
|
||||
#error "Serial port pins (3) conflict with Z2 pins!"
|
||||
#elif PIN_IS_TX3(Z3_DIR) || PIN_IS_RX3(Z3_STEP)
|
||||
#error "Serial port pins (3) conflict with Z3 pins!"
|
||||
#elif PIN_IS_TX3(Z4_DIR) || PIN_IS_RX3(Z4_STEP)
|
||||
#error "Serial port pins (3) conflict with Z4 pins!"
|
||||
#elif HAS_MULTI_EXTRUDER && (PIN_IS_TX3(E1_DIR) || PIN_IS_RX3(E1_STEP))
|
||||
#error "Serial port pins (3) conflict with E1 pins!"
|
||||
#endif
|
||||
#undef PIN_IS_TX3
|
||||
#undef PIN_IS_RX3
|
||||
#endif
|
||||
|
||||
#undef ANY_TX
|
||||
#undef ANY_RX
|
||||
|
||||
//
|
||||
// Flag any i2c pin conflicts
|
||||
//
|
||||
#if ANY(HAS_MOTOR_CURRENT_I2C, HAS_MOTOR_CURRENT_DAC, EXPERIMENTAL_I2CBUS, I2C_POSITION_ENCODERS, PCA9632, I2C_EEPROM)
|
||||
#define USEDI2CDEV_M 1 // <Arduino>/Wire.cpp
|
||||
|
||||
#if USEDI2CDEV_M == 0 // P0_27 [D57] (AUX-1) .......... P0_28 [D58] (AUX-1)
|
||||
#define PIN_IS_SDA0(P) (P##_PIN == P0_27)
|
||||
#define IS_SCL0(P) (P == P0_28)
|
||||
#if ENABLED(SDSUPPORT) && PIN_IS_SDA0(SD_DETECT)
|
||||
#error "SDA0 overlaps with SD_DETECT_PIN!"
|
||||
#elif PIN_IS_SDA0(E0_AUTO_FAN)
|
||||
#error "SDA0 overlaps with E0_AUTO_FAN_PIN!"
|
||||
#elif PIN_IS_SDA0(BEEPER)
|
||||
#error "SDA0 overlaps with BEEPER_PIN!"
|
||||
#elif IS_SCL0(BTN_ENC)
|
||||
#error "SCL0 overlaps with Encoder Button!"
|
||||
#elif IS_SCL0(SD_SS_PIN)
|
||||
#error "SCL0 overlaps with SD_SS_PIN!"
|
||||
#elif IS_SCL0(LCD_SDSS)
|
||||
#error "SCL0 overlaps with LCD_SDSS!"
|
||||
#endif
|
||||
#undef PIN_IS_SDA0
|
||||
#undef IS_SCL0
|
||||
#elif USEDI2CDEV_M == 1 // P0_00 [D20] (SCA) ............ P0_01 [D21] (SCL)
|
||||
#define PIN_IS_SDA1(P) (PIN_EXISTS(P) && P##_PIN == P0_00)
|
||||
#define PIN_IS_SCL1(P) (P##_PIN == P0_01)
|
||||
#if PIN_IS_SDA1(X_MIN) || PIN_IS_SCL1(X_MAX)
|
||||
#error "One or more i2c (1) pins overlaps with X endstop pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(X2_DIR) || PIN_IS_SCL1(X2_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with X2 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Y2_DIR) || PIN_IS_SCL1(Y2_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Y2 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Z2_DIR) || PIN_IS_SCL1(Z2_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Z2 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Z3_DIR) || PIN_IS_SCL1(Z3_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Z3 pins! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA1(Z4_DIR) || PIN_IS_SCL1(Z4_STEP)
|
||||
#error "One or more i2c (1) pins overlaps with Z4 pins! Disable i2c peripherals."
|
||||
#elif HAS_MULTI_EXTRUDER && (PIN_IS_SDA1(E1_DIR) || PIN_IS_SCL1(E1_STEP))
|
||||
#error "One or more i2c (1) pins overlaps with E1 pins! Disable i2c peripherals."
|
||||
#endif
|
||||
#undef PIN_IS_SDA1
|
||||
#undef PIN_IS_SCL1
|
||||
#elif USEDI2CDEV_M == 2 // P0_10 [D38] (X_ENABLE_PIN) ... P0_11 [D55] (X_DIR_PIN)
|
||||
#define PIN_IS_SDA2(P) (P##_PIN == P0_10)
|
||||
#define PIN_IS_SCL2(P) (P##_PIN == P0_11)
|
||||
#if PIN_IS_SDA2(Y_STOP)
|
||||
#error "i2c SDA2 overlaps with Y endstop pin!"
|
||||
#elif USES_Z_MIN_PROBE_PIN && PIN_IS_SDA2(Z_MIN_PROBE)
|
||||
#error "i2c SDA2 overlaps with Z probe pin!"
|
||||
#elif PIN_IS_SDA2(X_ENABLE) || PIN_IS_SDA2(Y_ENABLE)
|
||||
#error "i2c SDA2 overlaps with X/Y ENABLE pin!"
|
||||
#elif AXIS_HAS_SPI(X) && PIN_IS_SDA2(X_CS)
|
||||
#error "i2c SDA2 overlaps with X CS pin!"
|
||||
#elif PIN_IS_SDA2(X2_ENABLE)
|
||||
#error "i2c SDA2 overlaps with X2 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Y2_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Y2 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Z2_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Z2 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Z3_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Z3 enable pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(Z4_ENABLE)
|
||||
#error "i2c SDA2 overlaps with Z4 enable pin! Disable i2c peripherals."
|
||||
#elif HAS_MULTI_EXTRUDER && PIN_IS_SDA2(E1_ENABLE)
|
||||
#error "i2c SDA2 overlaps with E1 enable pin! Disable i2c peripherals."
|
||||
#elif HAS_MULTI_EXTRUDER && AXIS_HAS_SPI(E1) && PIN_IS_SDA2(E1_CS)
|
||||
#error "i2c SDA2 overlaps with E1 CS pin! Disable i2c peripherals."
|
||||
#elif EXTRUDERS && (PIN_IS_SDA2(E0_STEP) || PIN_IS_SDA2(E0_DIR))
|
||||
#error "i2c SCL2 overlaps with E0 STEP/DIR pin! Disable i2c peripherals."
|
||||
#elif PIN_IS_SDA2(X_DIR) || PIN_IS_SDA2(Y_DIR)
|
||||
#error "One or more i2c pins overlaps with X/Y DIR pin! Disable i2c peripherals."
|
||||
#endif
|
||||
#undef PIN_IS_SDA2
|
||||
#undef PIN_IS_SCL2
|
||||
#endif
|
||||
|
||||
#undef USEDI2CDEV_M
|
||||
#endif
|
||||
|
||||
#if ENABLED(SERIAL_STATS_MAX_RX_QUEUED)
|
||||
#error "SERIAL_STATS_MAX_RX_QUEUED is not supported on LPC176x."
|
||||
#elif ENABLED(SERIAL_STATS_DROPPED_RX)
|
||||
#error "SERIAL_STATS_DROPPED_RX is not supported on LPX176x."
|
||||
#endif
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mcu_interface.h>
|
||||
|
||||
//#define MSBFIRST 1
|
||||
|
||||
#define SPI_MODE0 0
|
||||
#define SPI_MODE1 1
|
||||
#define SPI_MODE2 2
|
||||
#define SPI_MODE3 3
|
||||
|
||||
#define SSP_CR0_DSS(n) ((uint32_t)((n-1)&0xF))
|
||||
#define SSP_DATABIT_4 SSP_CR0_DSS(4) /*!< Databit number = 4 */
|
||||
#define SSP_DATABIT_5 SSP_CR0_DSS(5) /*!< Databit number = 5 */
|
||||
#define SSP_DATABIT_6 SSP_CR0_DSS(6) /*!< Databit number = 6 */
|
||||
#define SSP_DATABIT_7 SSP_CR0_DSS(7) /*!< Databit number = 7 */
|
||||
#define SSP_DATABIT_8 SSP_CR0_DSS(8) /*!< Databit number = 8 */
|
||||
#define SSP_DATABIT_9 SSP_CR0_DSS(9) /*!< Databit number = 9 */
|
||||
#define SSP_DATABIT_10 SSP_CR0_DSS(10) /*!< Databit number = 10 */
|
||||
#define SSP_DATABIT_11 SSP_CR0_DSS(11) /*!< Databit number = 11 */
|
||||
#define SSP_DATABIT_12 SSP_CR0_DSS(12) /*!< Databit number = 12 */
|
||||
#define SSP_DATABIT_13 SSP_CR0_DSS(13) /*!< Databit number = 13 */
|
||||
#define SSP_DATABIT_14 SSP_CR0_DSS(14) /*!< Databit number = 14 */
|
||||
#define SSP_DATABIT_15 SSP_CR0_DSS(15) /*!< Databit number = 15 */
|
||||
#define SSP_DATABIT_16 SSP_CR0_DSS(16) /*!< Databit number = 16 */
|
||||
|
||||
#define DATA_SIZE_8BIT SSP_DATABIT_8
|
||||
#define DATA_SIZE_16BIT SSP_DATABIT_16
|
||||
|
||||
#define SPI_CLOCK_MAX_TFT 30000000UL
|
||||
#define SPI_CLOCK_DIV2 8333333 //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
|
||||
#define SPI_CLOCK_DIV4 4166667 //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
|
||||
#define SPI_CLOCK_DIV8 2083333 //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
|
||||
#define SPI_CLOCK_DIV16 1000000 //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
|
||||
#define SPI_CLOCK_DIV32 500000 //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
|
||||
#define SPI_CLOCK_DIV64 250000 //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
|
||||
#define SPI_CLOCK_DIV128 125000 //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
|
||||
|
||||
#define SPI_CLOCK_MAX SPI_CLOCK_DIV2
|
||||
|
||||
#define BOARD_NR_SPI 3
|
||||
|
||||
// SSP0 TMC port
|
||||
#define BOARD_SPI1_NSS_PIN P_NC
|
||||
#define BOARD_SPI1_SCK_PIN P1_20
|
||||
#define BOARD_SPI1_MISO_PIN P1_23
|
||||
#define BOARD_SPI1_MOSI_PIN P1_24
|
||||
|
||||
// SSP2 LCD SD port
|
||||
#define BOARD_SPI2_NSS_PIN P_NC
|
||||
#define BOARD_SPI2_SCK_PIN P1_00
|
||||
#define BOARD_SPI2_MISO_PIN P1_04
|
||||
#define BOARD_SPI2_MOSI_PIN P1_01
|
||||
|
||||
// SSP1 Onboard SD port
|
||||
#define BOARD_SPI3_NSS_PIN P_NC
|
||||
#define BOARD_SPI3_SCK_PIN P0_07
|
||||
#define BOARD_SPI3_MISO_PIN P0_08
|
||||
#define BOARD_SPI3_MOSI_PIN P0_09
|
||||
|
||||
class SPISettings {
|
||||
public:
|
||||
SPISettings(uint32_t spiRate, int inBitOrder, int inDataMode) {
|
||||
init_AlwaysInline(spiRate2Clock(spiRate), inBitOrder, inDataMode, DATA_SIZE_8BIT);
|
||||
}
|
||||
SPISettings(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
|
||||
if (__builtin_constant_p(inClock))
|
||||
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
|
||||
else
|
||||
init_MightInline(inClock, inBitOrder, inDataMode, inDataSize);
|
||||
}
|
||||
SPISettings() {
|
||||
init_AlwaysInline(4000000, MSBFIRST, SPI_MODE0, DATA_SIZE_8BIT);
|
||||
}
|
||||
|
||||
//uint32_t spiRate() const { return spi_speed; }
|
||||
|
||||
static uint32_t spiRate2Clock(uint32_t spiRate) {
|
||||
uint32_t Marlin_speed[7]; // CPSR is always 2
|
||||
Marlin_speed[0] = 8333333; //(SCR: 2) desired: 8,000,000 actual: 8,333,333 +4.2% SPI_FULL_SPEED
|
||||
Marlin_speed[1] = 4166667; //(SCR: 5) desired: 4,000,000 actual: 4,166,667 +4.2% SPI_HALF_SPEED
|
||||
Marlin_speed[2] = 2083333; //(SCR: 11) desired: 2,000,000 actual: 2,083,333 +4.2% SPI_QUARTER_SPEED
|
||||
Marlin_speed[3] = 1000000; //(SCR: 24) desired: 1,000,000 actual: 1,000,000 SPI_EIGHTH_SPEED
|
||||
Marlin_speed[4] = 500000; //(SCR: 49) desired: 500,000 actual: 500,000 SPI_SPEED_5
|
||||
Marlin_speed[5] = 250000; //(SCR: 99) desired: 250,000 actual: 250,000 SPI_SPEED_6
|
||||
Marlin_speed[6] = 125000; //(SCR:199) desired: 125,000 actual: 125,000 Default from HAL.h
|
||||
return Marlin_speed[spiRate > 6 ? 6 : spiRate];
|
||||
}
|
||||
|
||||
private:
|
||||
void init_MightInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) {
|
||||
init_AlwaysInline(inClock, inBitOrder, inDataMode, inDataSize);
|
||||
}
|
||||
void init_AlwaysInline(uint32_t inClock, uint8_t inBitOrder, uint8_t inDataMode, uint32_t inDataSize) __attribute__((__always_inline__)) {
|
||||
clock = inClock;
|
||||
bitOrder = inBitOrder;
|
||||
dataMode = inDataMode;
|
||||
dataSize = inDataSize;
|
||||
m_config = {};
|
||||
m_config.frequency = 400000;
|
||||
}
|
||||
|
||||
MCUI::SSP::Config m_config;
|
||||
|
||||
//uint32_t spi_speed;
|
||||
uint32_t clock;
|
||||
uint32_t dataSize;
|
||||
//uint32_t clockDivider;
|
||||
uint8_t bitOrder;
|
||||
uint8_t dataMode;
|
||||
|
||||
uint8_t device_id;
|
||||
|
||||
friend class SPIClass;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Wirish SPI interface.
|
||||
*
|
||||
* This is the same interface is available across HAL
|
||||
*
|
||||
* This implementation uses software slave management, so the caller
|
||||
* is responsible for controlling the slave select line.
|
||||
*/
|
||||
class SPIClass {
|
||||
public:
|
||||
/**
|
||||
* @param spiPortNumber Number of the SPI port to manage.
|
||||
*/
|
||||
SPIClass(uint8_t spiPortNumber);
|
||||
|
||||
/**
|
||||
* Init using pins
|
||||
*/
|
||||
SPIClass(pin_t mosi, pin_t miso, pin_t sclk, pin_t ssel = (pin_t)-1);
|
||||
|
||||
/**
|
||||
* Select and configure the current selected SPI device to use
|
||||
*/
|
||||
void begin();
|
||||
|
||||
/**
|
||||
* Disable the current SPI device
|
||||
*/
|
||||
void end();
|
||||
|
||||
void beginTransaction(const SPISettings&);
|
||||
void endTransaction() {}
|
||||
|
||||
// Transfer using 1 "Data Size"
|
||||
uint8_t transfer(uint16_t data);
|
||||
// Transfer 2 bytes in 8 bit mode
|
||||
uint16_t transfer16(uint16_t data);
|
||||
|
||||
void send(uint8_t data);
|
||||
|
||||
uint16_t read();
|
||||
void read(uint8_t *buf, uint32_t len);
|
||||
|
||||
void dmaSend(void *buf, uint16_t length, bool minc);
|
||||
|
||||
/**
|
||||
* @brief Sets the number of the SPI peripheral to be used by
|
||||
* this HardwareSPI instance.
|
||||
*
|
||||
* @param spi_num Number of the SPI port. 1-2 in low density devices
|
||||
* or 1-3 in high density devices.
|
||||
*/
|
||||
void setModule(uint8_t device);
|
||||
|
||||
void setClock(uint32_t clock);
|
||||
void setBitOrder(uint8_t bitOrder);
|
||||
void setDataMode(uint8_t dataMode);
|
||||
void setDataSize(uint32_t ds);
|
||||
|
||||
inline uint32_t getDataSize() { return _currentSetting->dataSize; }
|
||||
|
||||
private:
|
||||
SPISettings _settings[BOARD_NR_SPI];
|
||||
SPISettings *_currentSetting;
|
||||
|
||||
void updateSettings();
|
||||
};
|
||||
|
||||
extern SPIClass SPI;
|
||||
@@ -0,0 +1,111 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
#include "../../core/millis_t.h"
|
||||
#include "../../sd/cardreader.h"
|
||||
|
||||
#include <mcu_interface.h>
|
||||
#include <driver/usb_device.h>
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, extern void install_min_serial());
|
||||
|
||||
void MarlinHAL::init() {
|
||||
|
||||
MCUI::pwm_init();
|
||||
|
||||
// Init LEDs
|
||||
#if PIN_EXISTS(LED)
|
||||
SET_DIR_OUTPUT(LED_PIN);
|
||||
WRITE_PIN_CLR(LED_PIN);
|
||||
#if PIN_EXISTS(LED2)
|
||||
SET_DIR_OUTPUT(LED2_PIN);
|
||||
WRITE_PIN_CLR(LED2_PIN);
|
||||
#if PIN_EXISTS(LED3)
|
||||
SET_DIR_OUTPUT(LED3_PIN);
|
||||
WRITE_PIN_CLR(LED3_PIN);
|
||||
#if PIN_EXISTS(LED4)
|
||||
SET_DIR_OUTPUT(LED4_PIN);
|
||||
WRITE_PIN_CLR(LED4_PIN);
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Flash status LED 3 times to indicate Marlin has started booting
|
||||
for(int i = 0; i < 6; ++i) {
|
||||
TOGGLE(LED_PIN);
|
||||
delay(100);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Init Servo Pins
|
||||
#define INIT_SERVO(N) OUT_WRITE(SERVO##N##_PIN, LOW)
|
||||
#if HAS_SERVO_0
|
||||
INIT_SERVO(0);
|
||||
#endif
|
||||
#if HAS_SERVO_1
|
||||
INIT_SERVO(1);
|
||||
#endif
|
||||
#if HAS_SERVO_2
|
||||
INIT_SERVO(2);
|
||||
#endif
|
||||
#if HAS_SERVO_3
|
||||
INIT_SERVO(3);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(SD_SS)
|
||||
OUT_WRITE(SD_SS_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
#if PIN_EXISTS(ONBOARD_SD_CS) && ONBOARD_SD_CS_PIN != SD_SS_PIN
|
||||
OUT_WRITE(ONBOARD_SD_CS_PIN, HIGH);
|
||||
#endif
|
||||
|
||||
TERN_(HAS_SD_HOST_DRIVE, MCUI::USBDevice::msc_storage_init()); // Enable USB SD card access
|
||||
MCUI::USBDevice::connect(2000, LED_PIN);
|
||||
|
||||
HAL_timer_init();
|
||||
|
||||
TERN_(POSTMORTEM_DEBUGGING, install_min_serial()); // Install the min serial handler
|
||||
}
|
||||
|
||||
// HAL idle task
|
||||
void MarlinHAL::idletask() {
|
||||
#if HAS_SHARED_MEDIA
|
||||
// If Marlin is using the SD card we need to lock it to prevent access from
|
||||
// a PC via USB.
|
||||
// Other HALs use IS_SD_PRINTING() and IS_SD_FILE_OPEN() to check for access but
|
||||
// this will not reliably detect delete operations. To be safe we will lock
|
||||
// the disk if Marlin has it mounted. Unfortunately there is currently no way
|
||||
// to unmount the disk from the LCD menu.
|
||||
// if (IS_SD_PRINTING() || IS_SD_FILE_OPEN())
|
||||
if (card.isMounted())
|
||||
MCUI::USBDevice::msc_storage_lock();
|
||||
else
|
||||
MCUI::USBDevice::msc_storage_release();
|
||||
#endif
|
||||
// Perform USB stack housekeeping
|
||||
MCUI::USBDevice::msc_run_deferred_commands();
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Support routines for LPC1768
|
||||
*/
|
||||
|
||||
/**
|
||||
* Translation of routines & variables used by pinsDebug.h
|
||||
*/
|
||||
|
||||
#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS
|
||||
#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0)
|
||||
#define digitalRead_mod(p) extDigitalRead(p)
|
||||
#define PRINT_PORT(p)
|
||||
#define GET_ARRAY_PIN(p) pin_array[p].pin
|
||||
#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0)
|
||||
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), MCUI::pin_port(p), MCUI::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
|
||||
#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), MCUI::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0)
|
||||
#define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin
|
||||
|
||||
// pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities
|
||||
#ifndef M43_NEVER_TOUCH
|
||||
#define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins
|
||||
#endif
|
||||
|
||||
bool GET_PINMODE(const pin_t pin) {
|
||||
if (!MCUI::pin_is_valid(pin) || MCUI::pin_adc_enabled(pin)) // found an invalid pin or active analog pin
|
||||
return false;
|
||||
|
||||
return MCUI::gpio_direction(pin);
|
||||
}
|
||||
|
||||
#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital)
|
||||
|
||||
void print_port(const pin_t) {}
|
||||
void pwm_details(const pin_t) {}
|
||||
bool pwm_status(const pin_t) { return false; }
|
||||
@@ -0,0 +1,54 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "../../core/macros.h"
|
||||
|
||||
#if ALL(SDSUPPORT, HAS_MARLINUI_U8GLIB) && (LCD_PINS_D4 == SD_SCK_PIN || LCD_PINS_ENABLE == SD_MOSI_PIN || DOGLCD_SCK == SD_SCK_PIN || DOGLCD_MOSI == SD_MOSI_PIN)
|
||||
#define LPC_SOFTWARE_SPI // If the SD card and LCD adapter share the same SPI pins, then software SPI is currently
|
||||
// needed due to the speed and mode required for communicating with each device being different.
|
||||
// This requirement can be removed if the SPI access to these devices is updated to use
|
||||
// spiBeginTransaction.
|
||||
#endif
|
||||
|
||||
/** onboard SD card */
|
||||
//#define SD_SCK_PIN P0_07
|
||||
//#define SD_MISO_PIN P0_08
|
||||
//#define SD_MOSI_PIN P0_09
|
||||
//#define SD_SS_PIN P0_06
|
||||
/** external */
|
||||
#ifndef SD_SCK_PIN
|
||||
#define SD_SCK_PIN P0_15
|
||||
#endif
|
||||
#ifndef SD_MISO_PIN
|
||||
#define SD_MISO_PIN P0_17
|
||||
#endif
|
||||
#ifndef SD_MOSI_PIN
|
||||
#define SD_MOSI_PIN P0_18
|
||||
#endif
|
||||
#ifndef SD_SS_PIN
|
||||
#define SD_SS_PIN P1_23
|
||||
#endif
|
||||
#if !defined(SDSS) || SDSS == P_NC // gets defaulted in pins.h
|
||||
#undef SDSS
|
||||
#define SDSS SD_SS_PIN
|
||||
#endif
|
||||
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
* Copyright (c) 2015-2016 Nico Tonnhofer wurstnase.reprap@gmail.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Description:
|
||||
*
|
||||
* Timers for LPC1768
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../inc/MarlinConfig.h"
|
||||
|
||||
void HAL_timer_init() {
|
||||
SBI(MCUI::system_control.PCONP, SBIT_TIMER0); // Power ON Timer 0
|
||||
STEP_TIMER_REF.PR = (HAL_TIMER_RATE) / (STEPPER_TIMER_RATE) - 1; // Use prescaler to set frequency if needed
|
||||
|
||||
SBI(MCUI::system_control.PCONP, SBIT_TIMER1); // Power ON Timer 1
|
||||
TEMP_TIMER_REF.PR = (HAL_TIMER_RATE) / 1000000 - 1;
|
||||
}
|
||||
|
||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP:
|
||||
STEP_TIMER_REF.MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
|
||||
STEP_TIMER_REF.MR0 = uint32_t(STEPPER_TIMER_RATE) / frequency; // Match value (period) to set frequency
|
||||
STEP_TIMER_REF.TCR = _BV(SBIT_CNTEN); // Counter Enable
|
||||
|
||||
MCUCore::nvic_set_priority(MCUI::IRQNumber::TIMER0, MCUCore::nvic_encode_priority(0, 1, 0));
|
||||
MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER0);
|
||||
break;
|
||||
|
||||
case MF_TIMER_TEMP:
|
||||
TEMP_TIMER_REF.MCR = _BV(SBIT_MR0I) | _BV(SBIT_MR0R); // Match on MR0, reset on MR0, interrupts when NVIC enables them
|
||||
TEMP_TIMER_REF.MR0 = uint32_t(TEMP_TIMER_RATE) / frequency;
|
||||
TEMP_TIMER_REF.TCR = _BV(SBIT_CNTEN); // Counter Enable
|
||||
|
||||
MCUCore::nvic_set_priority(MCUI::IRQNumber::TIMER1, MCUCore::nvic_encode_priority(0, 2, 0));
|
||||
MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER1);
|
||||
break;
|
||||
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,165 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
*
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
* Copyright (c) 2016 Bob Cousins bobcousins42@googlemail.com
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* HAL For LPC1768
|
||||
*/
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <mcu_interface.h>
|
||||
|
||||
#include "../../core/macros.h"
|
||||
|
||||
#define SBIT_TIMER0 1
|
||||
#define SBIT_TIMER1 2
|
||||
|
||||
#define SBIT_CNTEN 0
|
||||
|
||||
#define SBIT_MR0I 0 // Timer 0 Interrupt when TC matches MR0
|
||||
#define SBIT_MR0R 1 // Timer 0 Reset TC on Match
|
||||
#define SBIT_MR0S 2 // Timer 0 Stop TC and PC on Match
|
||||
#define SBIT_MR1I 3
|
||||
#define SBIT_MR1R 4
|
||||
#define SBIT_MR1S 5
|
||||
#define SBIT_MR2I 6
|
||||
#define SBIT_MR2R 7
|
||||
#define SBIT_MR2S 8
|
||||
#define SBIT_MR3I 9
|
||||
#define SBIT_MR3R 10
|
||||
#define SBIT_MR3S 11
|
||||
|
||||
// ------------------------
|
||||
// Defines
|
||||
// ------------------------
|
||||
|
||||
#define _HAL_TIMER(T) _CAT(MCUI::timer, T)
|
||||
#define _HAL_TIMER_IRQ(T) TIMER##T##_IRQn
|
||||
#define __HAL_TIMER_ISR(T) extern "C" void TIMER##T##_IRQHandler()
|
||||
#define _HAL_TIMER_ISR(T) __HAL_TIMER_ISR(T)
|
||||
|
||||
typedef uint32_t hal_timer_t;
|
||||
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
|
||||
|
||||
#define HAL_TIMER_RATE ((F_CPU) / 2) // frequency of timers peripherals
|
||||
|
||||
#ifndef MF_TIMER_STEP
|
||||
#define MF_TIMER_STEP 0 // Timer Index for Stepper
|
||||
#endif
|
||||
#ifndef MF_TIMER_PULSE
|
||||
#define MF_TIMER_PULSE MF_TIMER_STEP
|
||||
#endif
|
||||
#ifndef MF_TIMER_TEMP
|
||||
#define MF_TIMER_TEMP 1 // Timer Index for Temperature
|
||||
#endif
|
||||
#ifndef MF_TIMER_PWM
|
||||
#define MF_TIMER_PWM 3 // Timer Index for PWM
|
||||
#endif
|
||||
|
||||
#define TEMP_TIMER_RATE 1000000
|
||||
#define TEMP_TIMER_FREQUENCY 1000 // temperature interrupt frequency
|
||||
|
||||
#define STEPPER_TIMER_RATE HAL_TIMER_RATE // frequency of stepper timer (HAL_TIMER_RATE / STEPPER_TIMER_PRESCALE)
|
||||
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
|
||||
#define STEPPER_TIMER_PRESCALE (CYCLES_PER_MICROSECOND / STEPPER_TIMER_TICKS_PER_US)
|
||||
|
||||
#define PULSE_TIMER_RATE STEPPER_TIMER_RATE // frequency of pulse timer
|
||||
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
|
||||
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
|
||||
|
||||
#define ENABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_STEP)
|
||||
#define DISABLE_STEPPER_DRIVER_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_STEP)
|
||||
#define STEPPER_ISR_ENABLED() HAL_timer_interrupt_enabled(MF_TIMER_STEP)
|
||||
|
||||
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(MF_TIMER_TEMP)
|
||||
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(MF_TIMER_TEMP)
|
||||
|
||||
#ifndef HAL_STEP_TIMER_ISR
|
||||
#define HAL_STEP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_STEP)
|
||||
#endif
|
||||
#ifndef HAL_TEMP_TIMER_ISR
|
||||
#define HAL_TEMP_TIMER_ISR() _HAL_TIMER_ISR(MF_TIMER_TEMP)
|
||||
#endif
|
||||
|
||||
// Timer references by index
|
||||
#define STEP_TIMER_REF _HAL_TIMER(MF_TIMER_STEP)
|
||||
#define TEMP_TIMER_REF _HAL_TIMER(MF_TIMER_TEMP)
|
||||
|
||||
// ------------------------
|
||||
// Public functions
|
||||
// ------------------------
|
||||
void HAL_timer_init();
|
||||
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency);
|
||||
|
||||
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t compare) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: STEP_TIMER_REF.MR0 = compare; break; // Stepper Timer Match Register 0
|
||||
case MF_TIMER_TEMP: TEMP_TIMER_REF.MR0 = compare; break; // Temp Timer Match Register 0
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: return STEP_TIMER_REF.MR0; // Stepper Timer Match Register 0
|
||||
case MF_TIMER_TEMP: return TEMP_TIMER_REF.MR0; // Temp Timer Match Register 0
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: return STEP_TIMER_REF.TC; // Stepper Timer Count
|
||||
case MF_TIMER_TEMP: return TEMP_TIMER_REF.TC; // Temp Timer Count
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
FORCE_INLINE static void HAL_timer_enable_interrupt(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER0); break; // Enable interrupt handler
|
||||
case MF_TIMER_TEMP: MCUCore::nvic_enable_irq(MCUI::IRQNumber::TIMER1); break; // Enable interrupt handler
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static void HAL_timer_disable_interrupt(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: MCUCore::nvic_disable_irq(MCUI::IRQNumber::TIMER0); break; // Disable interrupt handler
|
||||
case MF_TIMER_TEMP: MCUCore::nvic_disable_irq(MCUI::IRQNumber::TIMER1); break; // Disable interrupt handler
|
||||
}
|
||||
}
|
||||
|
||||
FORCE_INLINE static bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: return MCUCore::nvic_irq_is_enabled(MCUI::IRQNumber::TIMER0); // Check if interrupt is enabled or not
|
||||
case MF_TIMER_TEMP: return MCUCore::nvic_irq_is_enabled(MCUI::IRQNumber::TIMER1); // Check if interrupt is enabled or not
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
FORCE_INLINE static void HAL_timer_isr_prologue(const uint8_t timer_num) {
|
||||
switch (timer_num) {
|
||||
case MF_TIMER_STEP: SBI(STEP_TIMER_REF.IR, SBIT_CNTEN); break;
|
||||
case MF_TIMER_TEMP: SBI(TEMP_TIMER_REF.IR, SBIT_CNTEN); break;
|
||||
}
|
||||
}
|
||||
|
||||
#define HAL_timer_isr_epilogue(T) NOOP
|
||||
@@ -0,0 +1,89 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
// adapted from I2C/master/master.c example
|
||||
// https://www-users.cs.york.ac.uk/~pcc/MCP/HAPR-Course-web/CMSIS/examples/html/master_8c_source.html
|
||||
|
||||
#ifdef TARGET_LPC1768
|
||||
|
||||
#include "../include/i2c_util.h"
|
||||
#include "../../../core/millis_t.h"
|
||||
|
||||
extern int millis();
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define I2CDEV_S_ADDR 0x78 // From SSD1306 (actual address is 0x3C - shift left 1 with LSB set to 0 to indicate write)
|
||||
|
||||
// Send slave address and write bit
|
||||
uint8_t u8g_i2c_start(const uint8_t sla) {
|
||||
// Sometimes TX data ACK or NAK status is returned. That mean the start state didn't
|
||||
// happen which means only the value of the slave address was send. Keep looping until
|
||||
// the slave address and write bit are actually sent.
|
||||
do{
|
||||
_I2C_Stop(I2CDEV_M); // output stop state on I2C bus
|
||||
_I2C_Start(I2CDEV_M); // output start state on I2C bus
|
||||
while ((I2C_status != I2C_I2STAT_M_TX_START)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_RESTART)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_ACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for start to be asserted
|
||||
|
||||
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_STAC; // clear start state before tansmitting slave address
|
||||
LPC_I2C1->I2DAT = I2CDEV_S_ADDR & I2C_I2DAT_BITMASK; // transmit slave address & write bit
|
||||
LPC_I2C1->I2CONSET = I2C_I2CONSET_AA;
|
||||
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
while ((I2C_status != I2C_I2STAT_M_TX_SLAW_ACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_SLAW_NACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_ACK)
|
||||
&& (I2C_status != I2C_I2STAT_M_TX_DAT_NACK)); //wait for slaw to finish
|
||||
}while ( (I2C_status == I2C_I2STAT_M_TX_DAT_ACK) || (I2C_status == I2C_I2STAT_M_TX_DAT_NACK));
|
||||
return 1;
|
||||
}
|
||||
|
||||
void u8g_i2c_init(const uint8_t clock_option) {
|
||||
configure_i2c(clock_option);
|
||||
u8g_i2c_start(0); // Send slave address and write bit
|
||||
}
|
||||
|
||||
uint8_t u8g_i2c_send_byte(uint8_t data) {
|
||||
#define I2C_TIMEOUT 3
|
||||
LPC_I2C1->I2DAT = data & I2C_I2DAT_BITMASK; // transmit data
|
||||
LPC_I2C1->I2CONSET = I2C_I2CONSET_AA;
|
||||
LPC_I2C1->I2CONCLR = I2C_I2CONCLR_SIC;
|
||||
const millis_t timeout = millis() + I2C_TIMEOUT;
|
||||
while ((I2C_status != I2C_I2STAT_M_TX_DAT_ACK) && (I2C_status != I2C_I2STAT_M_TX_DAT_NACK) && PENDING(millis(), timeout)); // wait for xmit to finish
|
||||
// had hangs with SH1106 so added time out - have seen temporary screen corruption when this happens
|
||||
return 1;
|
||||
}
|
||||
|
||||
void u8g_i2c_stop() {
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
@@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
void u8g_i2c_init(const uint8_t clock_options);
|
||||
//uint8_t u8g_i2c_wait(uint8_t mask, uint8_t pos);
|
||||
uint8_t u8g_i2c_start(uint8_t sla);
|
||||
uint8_t u8g_i2c_send_byte(uint8_t data);
|
||||
void u8g_i2c_stop();
|
||||
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* LPC1768 LCD-specific defines
|
||||
*/
|
||||
|
||||
#ifndef U8G_HAL_LINKS
|
||||
|
||||
#define U8G_COM_SSD_I2C_HAL u8g_com_arduino_ssd_i2c_fn // See U8glib-HAL
|
||||
|
||||
#else
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr);
|
||||
|
||||
#define U8G_COM_HAL_SW_SPI_FN u8g_com_HAL_LPC1768_sw_spi_fn
|
||||
#define U8G_COM_HAL_HW_SPI_FN u8g_com_HAL_LPC1768_hw_spi_fn
|
||||
#define U8G_COM_ST7920_HAL_SW_SPI u8g_com_HAL_LPC1768_ST7920_sw_spi_fn
|
||||
#define U8G_COM_ST7920_HAL_HW_SPI u8g_com_HAL_LPC1768_ST7920_hw_spi_fn
|
||||
#define U8G_COM_SSD_I2C_HAL u8g_com_HAL_LPC1768_ssd_hw_i2c_fn
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* LCD delay routines - used by all the drivers.
|
||||
*
|
||||
* These are based on the LPC1768 routines.
|
||||
*
|
||||
* Couldn't just call exact copies because the overhead
|
||||
* results in a one microsecond delay taking about 4µS.
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void U8g_delay(int msec);
|
||||
void u8g_MicroDelay();
|
||||
void u8g_10MicroDelay();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Low level pin manipulation routines - used by all the drivers.
|
||||
*
|
||||
* These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines.
|
||||
*
|
||||
* Couldn't just call exact copies because the overhead killed the LCD update speed
|
||||
* With an intermediate level the softspi was running in the 10-20kHz range which
|
||||
* resulted in using about about 25% of the CPU's time.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include <mcu_interface.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
#include "LCD_pin_routines.h"
|
||||
|
||||
void u8g_SetPinOutput(uint8_t pin) {
|
||||
MCUI::gpio_set_output(pin);
|
||||
}
|
||||
|
||||
void u8g_SetPinInput(uint8_t pin) {
|
||||
MCUI::gpio_set_input(pin);
|
||||
}
|
||||
|
||||
void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status) {
|
||||
MCUI::gpio_set(pin, pin_status);
|
||||
}
|
||||
|
||||
uint8_t u8g_GetPinLevel(uint8_t pin) {
|
||||
return MCUI::gpio_get(pin);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Low level pin manipulation routines - used by all the drivers.
|
||||
*
|
||||
* These are based on the LPC1768 pinMode, digitalRead & digitalWrite routines.
|
||||
*
|
||||
* Couldn't just call exact copies because the overhead killed the LCD update speed
|
||||
* With an intermediate level the softspi was running in the 10-20kHz range which
|
||||
* resulted in using about about 25% of the CPU's time.
|
||||
*/
|
||||
|
||||
void u8g_SetPinOutput(uint8_t internal_pin_number);
|
||||
void u8g_SetPinInput(uint8_t internal_pin_number);
|
||||
void u8g_SetPinLevel(uint8_t pin, uint8_t pin_status);
|
||||
uint8_t u8g_GetPinLevel(uint8_t pin);
|
||||
@@ -0,0 +1,129 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_msp430_hw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#ifndef LCD_SPI_SPEED
|
||||
#ifdef SD_SPI_SPEED
|
||||
#define LCD_SPI_SPEED SD_SPI_SPEED // Assume SPI speed shared with SD
|
||||
#else
|
||||
#define LCD_SPI_SPEED SPI_FULL_SPEED // Use full speed if SD speed is not supplied
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, 1);
|
||||
u8g_SetPILevel(u8g, U8G_PI_A0, 1);
|
||||
u8g_SetPILevel(u8g, U8G_PI_RESET, 1);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_A0);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_RESET);
|
||||
u8g_Delay(5);
|
||||
spiBegin();
|
||||
spiInit(LCD_SPI_SPEED);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g_SetPILevel(u8g, U8G_PI_A0, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, (arg_val ? 0 : 1));
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
spiSend((uint8_t)arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
spiSend(*ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
spiSend(*ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,198 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_arduino_ssd_i2c.c
|
||||
*
|
||||
* COM interface for Arduino (AND ATmega) and the SSDxxxx chip (SOLOMON) variant
|
||||
* I2C protocol
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Special pin usage:
|
||||
* U8G_PI_I2C_OPTION additional options
|
||||
* U8G_PI_A0_STATE used to store the last value of the command/data register selection
|
||||
* U8G_PI_SET_A0 1: Signal request to update I2C device with new A0_STATE, 0: Do nothing, A0_STATE matches I2C device
|
||||
* U8G_PI_SCL clock line (NOT USED)
|
||||
* U8G_PI_SDA data line (NOT USED)
|
||||
*
|
||||
* U8G_PI_RESET reset line (currently disabled, see below)
|
||||
*
|
||||
* Protocol:
|
||||
* SLA, Cmd/Data Selection, Arguments
|
||||
* The command/data register is selected by a special instruction byte, which is sent after SLA
|
||||
*
|
||||
* The continue bit is always 0 so that a (re)start is equired for the change from cmd to/data mode
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC1768
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
|
||||
#define I2C_SLA (0x3C*2)
|
||||
//#define I2C_CMD_MODE 0x080
|
||||
#define I2C_CMD_MODE 0x000
|
||||
#define I2C_DATA_MODE 0x040
|
||||
|
||||
uint8_t u8g_com_ssd_I2C_start_sequence(u8g_t *u8g) {
|
||||
/* are we requested to set the a0 state? */
|
||||
if (u8g->pin_list[U8G_PI_SET_A0] == 0) return 1;
|
||||
|
||||
/* setup bus, might be a repeated start */
|
||||
if (u8g_i2c_start(I2C_SLA) == 0) return 0;
|
||||
if (u8g->pin_list[U8G_PI_A0_STATE] == 0) {
|
||||
if (u8g_i2c_send_byte(I2C_CMD_MODE) == 0) return 0;
|
||||
}
|
||||
else if (u8g_i2c_send_byte(I2C_DATA_MODE) == 0)
|
||||
return 0;
|
||||
|
||||
u8g->pin_list[U8G_PI_SET_A0] = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_ssd_hw_i2c_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
//u8g_com_arduino_digital_write(u8g, U8G_PI_SCL, HIGH);
|
||||
//u8g_com_arduino_digital_write(u8g, U8G_PI_SDA, HIGH);
|
||||
//u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: unknown mode */
|
||||
|
||||
u8g_i2c_init(u8g->pin_list[U8G_PI_I2C_OPTION]);
|
||||
u8g_com_ssd_I2C_start_sequence(u8g);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
/* Currently disabled, but it could be enable. Previous restrictions have been removed */
|
||||
/* u8g_com_arduino_digital_write(u8g, U8G_PI_RESET, arg_val); */
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = 0;
|
||||
u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again, also forces start condition */
|
||||
if (arg_val == 0 ) {
|
||||
/* disable chip, send stop condition */
|
||||
u8g_i2c_stop();
|
||||
}
|
||||
else {
|
||||
/* enable, do nothing: any byte writing will trigger the i2c start */
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
//u8g->pin_list[U8G_PI_SET_A0] = 1;
|
||||
if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (u8g_i2c_send_byte(arg_val) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
// u8g_i2c_stop();
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
//u8g->pin_list[U8G_PI_SET_A0] = 1;
|
||||
if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
if (u8g_i2c_send_byte(*ptr++) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
// u8g_i2c_stop();
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
//u8g->pin_list[U8G_PI_SET_A0] = 1;
|
||||
if (u8g_com_ssd_I2C_start_sequence(u8g) == 0) {
|
||||
u8g_i2c_stop();
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
if (u8g_i2c_send_byte(u8g_pgm_read(ptr)) == 0)
|
||||
return 0;
|
||||
ptr++;
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
// u8g_i2c_stop();
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
|
||||
u8g->pin_list[U8G_PI_SET_A0] = 1; /* force a0 to set again */
|
||||
break;
|
||||
|
||||
} // switch
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
|
||||
#endif // TARGET_LPC1768
|
||||
@@ -0,0 +1,138 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_LPC1768_st7920_hw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
#include "../../shared/Delay.h"
|
||||
|
||||
void spiBegin();
|
||||
void spiInit(uint8_t spiRate);
|
||||
void spiSend(uint8_t b);
|
||||
void spiSend(const uint8_t *buf, size_t n);
|
||||
|
||||
static uint8_t rs_last_state = 255;
|
||||
|
||||
static void u8g_com_LPC1768_st7920_write_byte_hw_spi(uint8_t rs, uint8_t val) {
|
||||
|
||||
if (rs != rs_last_state) { // Time to send a command/data byte
|
||||
rs_last_state = rs;
|
||||
spiSend(rs ? 0x0FA : 0x0F8); // Send data or command
|
||||
DELAY_US(40); // Give the controller some time: 20 is bad, 30 is OK, 40 is safe
|
||||
}
|
||||
|
||||
spiSend(val & 0xF0);
|
||||
spiSend(val << 4);
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_hw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_Delay(5);
|
||||
spiBegin();
|
||||
spiInit(SPI_EIGHTH_SPEED); // ST7920 max speed is about 1.1 MHz
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = 0; // initial RS state: command mode
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: // Define cmd (arg_val = 0) or data mode (arg_val = 1)
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); // Note: the ST7920 has an active high chip-select
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_hw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB
|
||||
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,147 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_st7920_hw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2011, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if IS_U8GLIB_ST7920
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
#include "../SoftwareSPI.h"
|
||||
#include "../../shared/Delay.h"
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#ifndef LCD_SPI_SPEED
|
||||
#define LCD_SPI_SPEED SPI_EIGHTH_SPEED // About 1 MHz
|
||||
#endif
|
||||
|
||||
static pin_t SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL;
|
||||
static uint8_t SPI_speed = 0;
|
||||
|
||||
static void u8g_com_LPC1768_st7920_write_byte_sw_spi(uint8_t rs, uint8_t val) {
|
||||
static uint8_t rs_last_state = 255;
|
||||
if (rs != rs_last_state) {
|
||||
// Transfer Data (FA) or Command (F8)
|
||||
swSpiTransfer(rs ? 0x0FA : 0x0F8, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
|
||||
rs_last_state = rs;
|
||||
DELAY_US(40); // Give the controller time to process the data: 20 is bad, 30 is OK, 40 is safe
|
||||
}
|
||||
swSpiTransfer(val & 0x0F0, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
|
||||
swSpiTransfer(val << 4, SPI_speed, SCK_pin_ST7920_HAL, -1, MOSI_pin_ST7920_HAL_HAL);
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_ST7920_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
SCK_pin_ST7920_HAL = u8g->pin_list[U8G_PI_SCK];
|
||||
MOSI_pin_ST7920_HAL_HAL = u8g->pin_list[U8G_PI_MOSI];
|
||||
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_SCK);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
|
||||
u8g_Delay(5);
|
||||
|
||||
SPI_speed = swSpiInit(LCD_SPI_SPEED, SCK_pin_ST7920_HAL, MOSI_pin_ST7920_HAL_HAL);
|
||||
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, 0);
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
|
||||
u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
|
||||
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = 0; /* initial RS state: command mode */
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g->pin_list[U8G_PI_A0_STATE] = arg_val;
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_CS]) u8g_SetPILevel(u8g, U8G_PI_CS, arg_val); //note: the st7920 has an active high chip select
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t*) arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_com_LPC1768_st7920_write_byte_sw_spi(u8g->pin_list[U8G_PI_A0_STATE], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // IS_U8GLIB_ST7920
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -0,0 +1,209 @@
|
||||
/**
|
||||
* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Based on u8g_com_std_sw_spi.c
|
||||
*
|
||||
* Universal 8bit Graphics Library
|
||||
*
|
||||
* Copyright (c) 2015, olikraus@gmail.com
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright notice, this list
|
||||
* of conditions and the following disclaimer.
|
||||
*
|
||||
* * Redistributions in binary form must reproduce the above copyright notice, this
|
||||
* list of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef TARGET_LPC4078
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
|
||||
|
||||
#include <SoftwareSPI.h>
|
||||
#include "../../shared/HAL_SPI.h"
|
||||
|
||||
#ifndef LCD_SPI_SPEED
|
||||
#define LCD_SPI_SPEED SPI_QUARTER_SPEED // About 2 MHz
|
||||
#endif
|
||||
|
||||
#include <Arduino.h>
|
||||
#include <algorithm>
|
||||
#include <LPC17xx.h>
|
||||
#include <gpio.h>
|
||||
|
||||
#include <U8glib-HAL.h>
|
||||
|
||||
uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) {
|
||||
|
||||
LOOP_L_N(i, 8) {
|
||||
if (spi_speed == 0) {
|
||||
LPC176x::gpio_set(mosi_pin, !!(b & 0x80));
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
else {
|
||||
const uint8_t state = (b & 0x80) ? HIGH : LOW;
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(mosi_pin, state);
|
||||
|
||||
LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
|
||||
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck_pin, const pin_t miso_pin, const pin_t mosi_pin ) {
|
||||
|
||||
LOOP_L_N(i, 8) {
|
||||
const uint8_t state = (b & 0x80) ? HIGH : LOW;
|
||||
if (spi_speed == 0) {
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
LPC176x::gpio_set(mosi_pin, state);
|
||||
LPC176x::gpio_set(mosi_pin, state); // need some setup time
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
}
|
||||
else {
|
||||
LOOP_L_N(j, spi_speed + (miso_pin >= 0 ? 0 : 1))
|
||||
LPC176x::gpio_set(sck_pin, LOW);
|
||||
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(mosi_pin, state);
|
||||
|
||||
LOOP_L_N(j, spi_speed)
|
||||
LPC176x::gpio_set(sck_pin, HIGH);
|
||||
}
|
||||
b <<= 1;
|
||||
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
static uint8_t SPI_speed = 0;
|
||||
|
||||
static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
|
||||
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864)
|
||||
swSpiTransfer_mode_3(val, SPI_speed, clockPin, -1, dataPin);
|
||||
#else
|
||||
swSpiTransfer_mode_0(val, SPI_speed, clockPin, -1, dataPin);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val, void *arg_ptr) {
|
||||
switch (msg) {
|
||||
case U8G_COM_MSG_INIT:
|
||||
u8g_SetPIOutput(u8g, U8G_PI_SCK);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_MOSI);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_CS);
|
||||
u8g_SetPIOutput(u8g, U8G_PI_A0);
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPIOutput(u8g, U8G_PI_RESET);
|
||||
SPI_speed = swSpiInit(LCD_SPI_SPEED, u8g->pin_list[U8G_PI_SCK], u8g->pin_list[U8G_PI_MOSI]);
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 0);
|
||||
u8g_SetPILevel(u8g, U8G_PI_MOSI, 0);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_STOP:
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_RESET:
|
||||
if (U8G_PIN_NONE != u8g->pin_list[U8G_PI_RESET]) u8g_SetPILevel(u8g, U8G_PI_RESET, arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_CHIP_SELECT:
|
||||
#if ANY(FYSETC_MINI_12864, MKS_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
|
||||
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
|
||||
// the next chip select goes active
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, LOW);
|
||||
}
|
||||
else {
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, HIGH);
|
||||
u8g_SetPILevel(u8g, U8G_PI_SCK, 0); // Set SCK to mode 0 idle state after CS goes inactive
|
||||
}
|
||||
#else
|
||||
u8g_SetPILevel(u8g, U8G_PI_CS, !arg_val);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_BYTE:
|
||||
u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], arg_val);
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ: {
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], *ptr++);
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_WRITE_SEQ_P: {
|
||||
uint8_t *ptr = (uint8_t *)arg_ptr;
|
||||
while (arg_val > 0) {
|
||||
u8g_sw_spi_HAL_LPC1768_shift_out(u8g->pin_list[U8G_PI_MOSI], u8g->pin_list[U8G_PI_SCK], u8g_pgm_read(ptr));
|
||||
ptr++;
|
||||
arg_val--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case U8G_COM_MSG_ADDRESS: /* define cmd (arg_val = 0) or data mode (arg_val = 1) */
|
||||
u8g_SetPILevel(u8g, U8G_PI_A0, arg_val);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif // HAS_MARLINUI_U8GLIB && !IS_U8GLIB_ST7920
|
||||
#endif // TARGET_LPC4078
|
||||
@@ -112,7 +112,7 @@
|
||||
#else
|
||||
#error "LCD_SERIAL_PORT must be from 1 to 9, or -1 for Native USB."
|
||||
#endif
|
||||
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
|
||||
#if HAS_DGUS_LCD
|
||||
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
#define LCD_SERIAL MSERIAL(1) // dummy port
|
||||
static_assert(false, "LCD_SERIAL_PORT must be from 1 to " STRINGIFY(NUM_UARTS) ". You can also use -1 if the board supports Native USB.")
|
||||
#endif
|
||||
#if ANY(HAS_DGUS_LCD, EXTENSIBLE_UI)
|
||||
#if HAS_DGUS_LCD
|
||||
#define LCD_SERIAL_TX_BUFFER_FREE() LCD_SERIAL.availableForWrite()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ typedef uint32_t hal_timer_t;
|
||||
#define FTM0_TIMER_PRESCALE_BITS 0b011
|
||||
#define FTM1_TIMER_PRESCALE_BITS 0b010
|
||||
|
||||
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz
|
||||
#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7.5MHz
|
||||
#define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz
|
||||
|
||||
#define HAL_TIMER_RATE (FTM0_TIMER_RATE)
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/LPC1768/NAME)
|
||||
#elif defined(ARDUINO_ARCH_HC32)
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/HC32/NAME)
|
||||
#elif defined(TARGET_LPC4078)
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/LPC4078/NAME)
|
||||
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
|
||||
#define HAL_PATH(PATH, NAME) XSTR(PATH/HAL/STM32F1/NAME)
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
|
||||
@@ -76,6 +76,8 @@
|
||||
#include "../LPC1768/Servo.h"
|
||||
#elif defined(ARDUINO_ARCH_HC32)
|
||||
#include "../HC32/Servo.h"
|
||||
#elif defined(TARGET_LPC4078)
|
||||
#include "../LPC4078/Servo.h"
|
||||
#elif defined(__STM32F1__) || defined(TARGET_STM32F1)
|
||||
#include "../STM32F1/Servo.h"
|
||||
#elif defined(ARDUINO_ARCH_STM32)
|
||||
|
||||
@@ -410,6 +410,7 @@
|
||||
|
||||
#define BOARD_TEENSY31_32 5100 // Teensy3.1 and Teensy3.2
|
||||
#define BOARD_TEENSY35_36 5101 // Teensy3.5 and Teensy3.6
|
||||
#define BOARD_EBAB 5102
|
||||
|
||||
//
|
||||
// STM32 ARM Cortex-M4F
|
||||
|
||||
@@ -89,7 +89,7 @@
|
||||
#define HYPOT2(x,y) (sq(x)+sq(y))
|
||||
#define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z))
|
||||
|
||||
#define FLOAT_SQ(I) sq(float(I))
|
||||
#define FLOAT_SQ(I) float(sq(I))
|
||||
#define CIRCLE_AREA(R) (float(M_PI) * FLOAT_SQ(R))
|
||||
#define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R))
|
||||
|
||||
@@ -197,8 +197,8 @@
|
||||
#define ENABLED(V...) DO(ENA,&&,V)
|
||||
#define DISABLED(V...) DO(DIS,&&,V)
|
||||
#define ANY(V...) !DISABLED(V)
|
||||
#define ALL(V...) ENABLED(V)
|
||||
#define NONE(V...) DISABLED(V)
|
||||
#define ALL ENABLED
|
||||
#define NONE DISABLED
|
||||
#define COUNT_ENABLED(V...) DO(ENA,+,V)
|
||||
#define MANY(V...) (COUNT_ENABLED(V) > 1)
|
||||
|
||||
@@ -630,7 +630,7 @@
|
||||
#define DEFER4(M) M EMPTY EMPTY EMPTY EMPTY()()()()
|
||||
|
||||
// Force define expansion
|
||||
#define EVAL(V...) EVAL16(V)
|
||||
#define EVAL EVAL16
|
||||
#define EVAL4096(V...) EVAL2048(EVAL2048(V))
|
||||
#define EVAL2048(V...) EVAL1024(EVAL1024(V))
|
||||
#define EVAL1024(V...) EVAL512(EVAL512(V))
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#include "../../feature/probe_temp_comp.h"
|
||||
#endif
|
||||
|
||||
#if ANY(DWIN_CREALITY_LCD_JYERSUI, EXTENSIBLE_UI)
|
||||
#if ANY(DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
|
||||
#define VERBOSE_SINGLE_PROBE
|
||||
#endif
|
||||
|
||||
|
||||
@@ -833,6 +833,16 @@ static_assert(COUNT(arm) == LOGICAL_AXES, "AXIS_RELATIVE_MODES must contain " _L
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* S_CURVE_ACCELERATION
|
||||
*/
|
||||
#if ENABLED(S_CURVE_ACCELERATION) && defined(S_CURVE_FACTOR)
|
||||
#if defined(__AVR__)
|
||||
#error "S_CURVE_FACTOR is not implemented for AVR yet"
|
||||
#endif
|
||||
static_assert(WITHIN(S_CURVE_FACTOR, 0, 1), "S_CURVE_FACTOR must be from 0 to 1");
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Nonlinear Extrusion requirements
|
||||
*/
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
* version was tagged.
|
||||
*/
|
||||
#ifndef STRING_DISTRIBUTION_DATE
|
||||
#define STRING_DISTRIBUTION_DATE "2024-05-29"
|
||||
#define STRING_DISTRIBUTION_DATE "2024-05-27"
|
||||
#endif
|
||||
|
||||
/**
|
||||
|
||||
@@ -1343,7 +1343,7 @@ void MarlinUI::draw_status_screen() {
|
||||
void MenuItem_sdbase::draw(const bool sel, const uint8_t row, FSTR_P const, CardReader &theCard, const bool isDir) {
|
||||
lcd_put_lchar(0, row, sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
|
||||
uint8_t n = LCD_WIDTH - 2;
|
||||
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, row, sel), n);
|
||||
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, sel), n);
|
||||
for (; n; --n) lcd_put_u8str(F(" "));
|
||||
lcd_put_lchar(isDir ? LCD_STR_FOLDER[0] : ' ');
|
||||
}
|
||||
|
||||
@@ -1086,7 +1086,7 @@ void MarlinUI::draw_status_screen() {
|
||||
lcd_moveto(0, row);
|
||||
lcd.write(sel ? LCD_STR_ARROW_RIGHT[0] : ' ');
|
||||
uint8_t n = LCD_WIDTH - 2;
|
||||
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, row, sel), n);
|
||||
n -= lcd_put_u8str_max(ui.scrolled_filename(theCard, n, sel), n);
|
||||
for (; n; --n) lcd.write(' ');
|
||||
lcd.write(isDir ? LCD_STR_FOLDER[0] : ' ');
|
||||
lcd.print_line();
|
||||
|
||||
@@ -606,7 +606,7 @@ void MarlinUI::clear_lcd() { } // Automatically cleared by Picture Loop
|
||||
const uint8_t maxlen = LCD_WIDTH - isDir;
|
||||
if (isDir) lcd_put_lchar(LCD_STR_FOLDER[0]);
|
||||
const pixel_len_t pixw = maxlen * (MENU_FONT_WIDTH);
|
||||
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, row, sel), pixw);
|
||||
pixel_len_t n = pixw - lcd_put_u8str_max(ui.scrolled_filename(theCard, maxlen, sel), pixw);
|
||||
for (; n > MENU_FONT_WIDTH; n -= MENU_FONT_WIDTH) lcd_put_u8str(F(" "));
|
||||
}
|
||||
|
||||
|
||||
@@ -487,7 +487,7 @@ void MarlinUI::draw_status_message(const bool blink) {
|
||||
maxlen -= 2;
|
||||
}
|
||||
|
||||
dwin_string.add(ui.scrolled_filename(theCard, maxlen, row, sel), maxlen);
|
||||
dwin_string.add(ui.scrolled_filename(theCard, maxlen, sel), maxlen);
|
||||
uint8_t n = maxlen - dwin_string.length;
|
||||
while (n > 0) { dwin_string.add(' '); --n; }
|
||||
lcd_moveto(1, row);
|
||||
|
||||
@@ -765,24 +765,6 @@ namespace ExtUI {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_SHAPING
|
||||
float getShapingZeta(const axis_t axis) {
|
||||
return stepper.get_shaping_damping_ratio(AxisEnum(axis));
|
||||
}
|
||||
void setShapingZeta(const float zeta, const axis_t axis) {
|
||||
if (!WITHIN(zeta, 0, 1)) return;
|
||||
stepper.set_shaping_damping_ratio(AxisEnum(axis), zeta);
|
||||
}
|
||||
float getShapingFrequency(const axis_t axis) {
|
||||
return stepper.get_shaping_frequency(AxisEnum(axis));
|
||||
}
|
||||
void setShapingFrequency(const float freq, const axis_t axis) {
|
||||
constexpr float min_freq = float(uint32_t(STEPPER_TIMER_RATE) / 2) / shaping_time_t(-2);
|
||||
if (freq == 0.0f || freq > min_freq)
|
||||
stepper.set_shaping_frequency(AxisEnum(axis), freq);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if HAS_JUNCTION_DEVIATION
|
||||
|
||||
float getJunctionDeviation_mm() { return planner.junction_deviation_mm; }
|
||||
@@ -951,7 +933,6 @@ namespace ExtUI {
|
||||
#if HAS_BED_PROBE
|
||||
float getProbeOffset_mm(const axis_t axis) { return probe.offset.pos[axis]; }
|
||||
void setProbeOffset_mm(const_float_t val, const axis_t axis) { probe.offset.pos[axis] = val; }
|
||||
probe_limits_t getBedProbeLimits() { return probe_limits_t({ probe.min_x(), probe.min_y(), probe.max_x(), probe.max_y() }); }
|
||||
#endif
|
||||
|
||||
#if ENABLED(BACKLASH_GCODE)
|
||||
|
||||
@@ -74,7 +74,6 @@ namespace ExtUI {
|
||||
#if ENABLED(MPC_AUTOTUNE)
|
||||
enum mpcresult_t : uint8_t { MPC_STARTED, MPC_TEMP_ERROR, MPC_INTERRUPTED, MPC_DONE };
|
||||
#endif
|
||||
struct probe_limits_t { float xmin, ymin, xmax, ymax; };
|
||||
|
||||
constexpr uint8_t extruderCount = EXTRUDERS;
|
||||
constexpr uint8_t hotendCount = HOTENDS;
|
||||
@@ -328,13 +327,6 @@ namespace ExtUI {
|
||||
void setLinearAdvance_mm_mm_s(const_float_t, const extruder_t);
|
||||
#endif
|
||||
|
||||
#if HAS_SHAPING
|
||||
float getShapingZeta(const axis_t);
|
||||
void setShapingZeta(const float, const axis_t);
|
||||
float getShapingFrequency(const axis_t);
|
||||
void setShapingFrequency(const float, const axis_t);
|
||||
#endif
|
||||
|
||||
// JD or Jerk Control
|
||||
#if HAS_JUNCTION_DEVIATION
|
||||
float getJunctionDeviation_mm();
|
||||
@@ -375,7 +367,6 @@ namespace ExtUI {
|
||||
#if HAS_BED_PROBE
|
||||
float getProbeOffset_mm(const axis_t);
|
||||
void setProbeOffset_mm(const_float_t, const axis_t);
|
||||
probe_limits_t getBedProbeLimits();
|
||||
#endif
|
||||
|
||||
// Backlash Control
|
||||
|
||||
+23
-26
@@ -357,25 +357,21 @@ void MarlinUI::init() {
|
||||
#if HAS_MEDIA
|
||||
|
||||
#if MARLINUI_SCROLL_NAME
|
||||
uint8_t MarlinUI::filename_scroll_pos, MarlinUI::filename_scroll_max;
|
||||
static uint8_t filename_scroll_pos, filename_scroll_max;
|
||||
#endif
|
||||
|
||||
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll) {
|
||||
const char * MarlinUI::scrolled_filename(CardReader &theCard, const uint8_t maxlen, const bool doScroll) {
|
||||
const char *outstr = theCard.longest_filename();
|
||||
if (theCard.longFilename[0]) {
|
||||
#if MARLINUI_SCROLL_NAME
|
||||
if (doScroll) {
|
||||
for (uint8_t l = FILENAME_LENGTH; l--;)
|
||||
hash = ((hash << 1) | (hash >> 7)) ^ theCard.filename[l]; // rotate, xor
|
||||
static uint8_t filename_scroll_hash;
|
||||
if (filename_scroll_hash != hash) { // If the hash changed...
|
||||
filename_scroll_hash = hash; // Save the new hash
|
||||
filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen); // Update the scroll limit
|
||||
filename_scroll_pos = 0; // Reset scroll to the start
|
||||
lcd_status_update_delay = 8; // Don't scroll right away
|
||||
filename_scroll_max = _MAX(0, utf8_strlen(theCard.longFilename) - maxlen);
|
||||
if (filename_scroll_max) {
|
||||
// Ensure filename_scroll_pos isn't out of bounds even though it should never happen.
|
||||
if (filename_scroll_pos > filename_scroll_max) filename_scroll_pos = 0;
|
||||
// Advance byte position corresponding to filename_scroll_pos char position
|
||||
outstr += TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(outstr, filename_scroll_pos), filename_scroll_pos);
|
||||
}
|
||||
// Advance byte position corresponding to filename_scroll_pos char position
|
||||
outstr += TERN(UTF_FILENAME_SUPPORT, utf8_byte_pos_by_char_num(outstr, filename_scroll_pos), filename_scroll_pos);
|
||||
}
|
||||
#else
|
||||
theCard.longFilename[
|
||||
@@ -1003,22 +999,19 @@ void MarlinUI::init() {
|
||||
|
||||
#endif // HAS_MARLINUI_MENU
|
||||
|
||||
if (ELAPSED(ms, next_lcd_update_ms) || TERN0(HAS_MARLINUI_U8GLIB, drawing_screen)) {
|
||||
|
||||
const bool lcd_update_ms_elapsed = ELAPSED(ms, next_lcd_update_ms);
|
||||
if (lcd_update_ms_elapsed) {
|
||||
next_lcd_update_ms = ms + LCD_UPDATE_INTERVAL;
|
||||
|
||||
#if HAS_TOUCH_BUTTONS
|
||||
|
||||
if (on_status_screen()) next_lcd_update_ms += (LCD_UPDATE_INTERVAL) * 2;
|
||||
|
||||
TERN_(HAS_ENCODER_ACTION, touch_buttons = touchBt.read_buttons());
|
||||
|
||||
#endif
|
||||
|
||||
TERN_(LCD_HAS_STATUS_INDICATORS, update_indicators());
|
||||
|
||||
#if HAS_ENCODER_ACTION
|
||||
|
||||
TERN_(HAS_SLOW_BUTTONS, slow_buttons = read_slow_buttons()); // Buttons that take too long to read in interrupt context
|
||||
|
||||
if (TERN0(IS_RRW_KEYPAD, handle_keypad()))
|
||||
@@ -1083,12 +1076,17 @@ void MarlinUI::init() {
|
||||
#endif
|
||||
|
||||
refresh(LCDVIEW_REDRAW_NOW);
|
||||
TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false);
|
||||
#if MARLINUI_SCROLL_NAME
|
||||
filename_scroll_max = 0;
|
||||
filename_scroll_pos = 0;
|
||||
lcd_status_update_delay = 9;
|
||||
#endif
|
||||
|
||||
#if LED_POWEROFF_TIMEOUT > 0
|
||||
if (!powerManager.psu_on) leds.reset_timeout(ms);
|
||||
#endif
|
||||
} // encoder activity
|
||||
|
||||
#endif // HAS_ENCODER_ACTION
|
||||
|
||||
// This runs every ~100ms when idling often enough.
|
||||
@@ -1097,19 +1095,23 @@ void MarlinUI::init() {
|
||||
lcd_status_update_delay = TERN(HAS_MARLINUI_U8GLIB, 12, 9);
|
||||
if (max_display_update_time) max_display_update_time--; // Be sure never go to a very big number
|
||||
refresh(LCDVIEW_REDRAW_NOW);
|
||||
TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false);
|
||||
}
|
||||
|
||||
#if ALL(HAS_MARLINUI_MENU, SCROLL_LONG_FILENAMES)
|
||||
#if MARLINUI_SCROLL_NAME
|
||||
// If scrolling of long file names is enabled and we are in the sd card menu,
|
||||
// cause a refresh to occur until all the text has scrolled into view.
|
||||
if (currentScreen == menu_media && !lcd_status_update_delay--) {
|
||||
if (currentScreen == menu_media && filename_scroll_max && !lcd_status_update_delay--) {
|
||||
lcd_status_update_delay = ++filename_scroll_pos >= filename_scroll_max ? 12 : 4; // Long delay at end and start
|
||||
if (filename_scroll_pos > filename_scroll_max) filename_scroll_pos = 0;
|
||||
refresh(LCDVIEW_REDRAW_NOW);
|
||||
TERN_(HAS_MARLINUI_U8GLIB, drawing_screen = false);
|
||||
reset_status_timeout(ms);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (lcd_update_ms_elapsed || drawing_screen) {
|
||||
// Then we want to use only 50% of the time
|
||||
const uint16_t bbr2 = planner.block_buffer_runtime() >> 1;
|
||||
|
||||
@@ -1131,7 +1133,6 @@ void MarlinUI::init() {
|
||||
TERN_(HAS_ADC_BUTTONS, keypad_buttons = 0);
|
||||
|
||||
#if HAS_MARLINUI_U8GLIB
|
||||
|
||||
#if ENABLED(LIGHTWEIGHT_UI)
|
||||
const bool in_status = on_status_screen(),
|
||||
do_u8g_loop = !in_status;
|
||||
@@ -1160,14 +1161,11 @@ void MarlinUI::init() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
run_current_screen();
|
||||
|
||||
// Apply all DWIN drawing after processing
|
||||
TERN_(IS_DWIN_MARLINUI, dwinUpdateLCD());
|
||||
|
||||
#endif
|
||||
|
||||
TERN_(HAS_MARLINUI_MENU, lcd_clicked = false);
|
||||
@@ -1212,8 +1210,7 @@ void MarlinUI::init() {
|
||||
case LCDVIEW_CALL_NO_REDRAW:
|
||||
default: break;
|
||||
} // switch
|
||||
|
||||
} // ELAPSED(ms, next_lcd_update_ms)
|
||||
}
|
||||
|
||||
TERN_(HAS_GRAPHICAL_TFT, tft_idle());
|
||||
}
|
||||
|
||||
@@ -644,10 +644,7 @@ public:
|
||||
#if ALL(SCROLL_LONG_FILENAMES, HAS_MARLINUI_MENU)
|
||||
#define MARLINUI_SCROLL_NAME 1
|
||||
#endif
|
||||
#if MARLINUI_SCROLL_NAME
|
||||
static uint8_t filename_scroll_pos, filename_scroll_max;
|
||||
#endif
|
||||
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, uint8_t hash, const bool doScroll);
|
||||
static const char * scrolled_filename(CardReader &theCard, const uint8_t maxlen, const bool doScroll);
|
||||
#endif
|
||||
|
||||
#if HAS_PREHEAT
|
||||
|
||||
@@ -523,12 +523,12 @@ void menu_backlash();
|
||||
// M204 T Travel Acceleration
|
||||
EDIT_ITEM_FAST(float5_25, MSG_A_TRAVEL, &planner.settings.travel_acceleration, 25, max_accel);
|
||||
|
||||
#define EDIT_AMAX(Q,L) EDIT_ITEM_FAST_N(long5_25, _AXIS(Q), MSG_AMAX_N, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.refresh_acceleration_rates(); })
|
||||
NUM_AXIS_CODE(
|
||||
EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10),
|
||||
EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10),
|
||||
EDIT_AMAX(U, 10), EDIT_AMAX(V, 10), EDIT_AMAX(W, 10)
|
||||
);
|
||||
//#define EDIT_AMAX(Q,L) EDIT_ITEM_FAST_N(long5_25, _AXIS(Q), MSG_AMAX_N, &planner.settings.max_acceleration_mm_per_s2[_AXIS(Q)], L, max_accel_edit_scaled[_AXIS(Q)], []{ planner.refresh_acceleration_rates(); })
|
||||
//NUM_AXIS_CODE(
|
||||
// EDIT_AMAX(A, 100), EDIT_AMAX(B, 100), EDIT_AMAX(C, 10),
|
||||
// EDIT_AMAX(I, 10), EDIT_AMAX(J, 10), EDIT_AMAX(K, 10),
|
||||
// EDIT_AMAX(U, 10), EDIT_AMAX(V, 10), EDIT_AMAX(W, 10)
|
||||
//);
|
||||
|
||||
#if ENABLED(DISTINCT_E_FACTORS)
|
||||
EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS_N(active_extruder)], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); });
|
||||
@@ -538,7 +538,7 @@ void menu_backlash();
|
||||
planner.refresh_acceleration_rates();
|
||||
});
|
||||
#elif E_STEPPERS
|
||||
EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); });
|
||||
//EDIT_ITEM_FAST(long5_25, MSG_AMAX_E, &planner.settings.max_acceleration_mm_per_s2[E_AXIS], 100, max_accel_edit_scaled.e, []{ planner.refresh_acceleration_rates(); });
|
||||
#endif
|
||||
|
||||
#ifdef XY_FREQUENCY_LIMIT
|
||||
|
||||
@@ -386,7 +386,7 @@ void MenuItem_static::draw(const uint8_t row, FSTR_P const ftpl, const uint8_t s
|
||||
menu_item(row, sel);
|
||||
if (isDir) tft.add_image(MENU_ITEM_ICON_X, MENU_ITEM_ICON_Y, imgDirectory, COLOR_MENU_TEXT, sel ? COLOR_SELECTION_BG : COLOR_BACKGROUND);
|
||||
uint8_t maxlen = (MENU_ITEM_HEIGHT) - (MENU_TEXT_Y) + 1;
|
||||
tft.add_text(MENU_ITEM_ICON_SPACE, MENU_TEXT_Y, COLOR_MENU_TEXT, ui.scrolled_filename(theCard, maxlen, row, sel));
|
||||
tft.add_text(MENU_ITEM_ICON_SPACE, MENU_TEXT_Y, COLOR_MENU_TEXT, ui.scrolled_filename(theCard, maxlen, sel));
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
+144
-227
@@ -128,7 +128,6 @@ Planner planner;
|
||||
block_t Planner::block_buffer[BLOCK_BUFFER_SIZE];
|
||||
volatile uint8_t Planner::block_buffer_head, // Index of the next block to be pushed
|
||||
Planner::block_buffer_nonbusy, // Index of the first non-busy block
|
||||
Planner::block_buffer_planned, // Index of the optimally planned block
|
||||
Planner::block_buffer_tail; // Index of the busy block, if any
|
||||
uint16_t Planner::cleaning_buffer_counter; // A counter to disable queuing of blocks
|
||||
uint8_t Planner::delay_before_delivering; // Delay block delivery so initial blocks in an empty queue may merge
|
||||
@@ -150,7 +149,7 @@ planner_settings_t Planner::settings; // Initialized by settings.load(
|
||||
const uint8_t laser_power_floor = cutter.pct_to_ocr(SPEED_POWER_MIN);
|
||||
#endif
|
||||
|
||||
uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
|
||||
uint64_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
|
||||
|
||||
#if HAS_JUNCTION_DEVIATION
|
||||
float Planner::junction_deviation_mm; // (mm) M205 J
|
||||
@@ -170,7 +169,7 @@ uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D
|
||||
#endif
|
||||
|
||||
#if ENABLED(DIRECT_STEPPING)
|
||||
uint32_t Planner::last_page_step_rate = 0;
|
||||
uint64_t Planner::last_page_step_rate = 0;
|
||||
AxisBits Planner::last_page_dir; // = 0
|
||||
#endif
|
||||
|
||||
@@ -220,7 +219,7 @@ uint32_t Planner::max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) D
|
||||
|
||||
xyze_long_t Planner::position{0};
|
||||
|
||||
uint32_t Planner::acceleration_long_cutoff;
|
||||
uint64_t Planner::acceleration_long_cutoff;
|
||||
|
||||
xyze_float_t Planner::previous_speed;
|
||||
float Planner::previous_nominal_speed;
|
||||
@@ -248,7 +247,7 @@ float Planner::previous_nominal_speed;
|
||||
#endif
|
||||
|
||||
#if HAS_WIRED_LCD
|
||||
volatile uint32_t Planner::block_buffer_runtime_us = 0;
|
||||
volatile uint64_t Planner::block_buffer_runtime_us = 0;
|
||||
#endif
|
||||
|
||||
/**
|
||||
@@ -338,7 +337,7 @@ void Planner::init() {
|
||||
* // Compute initial estimation of 0x1000000/x -
|
||||
* // Get most significant bit set on divider
|
||||
* uint8_t idx = 0;
|
||||
* uint32_t nr = d;
|
||||
* uint64_t nr = d;
|
||||
* if (!(nr & 0xFF0000)) {
|
||||
* nr <<= 8; idx += 8;
|
||||
* if (!(nr & 0xFF0000)) { nr <<= 8; idx += 8; }
|
||||
@@ -348,16 +347,16 @@ void Planner::init() {
|
||||
* if (!(nr & 0x800000)) { nr <<= 1; idx += 1; }
|
||||
*
|
||||
* // Isolate top 9 bits of the denominator, to be used as index into the initial estimation table
|
||||
* uint32_t tidx = nr >> 15, // top 9 bits. bit8 is always set
|
||||
* uint64_t tidx = nr >> 15, // top 9 bits. bit8 is always set
|
||||
* ie = inv_tab[tidx & 0xFF] + 256, // Get the table value. bit9 is always set
|
||||
* x = idx <= 8 ? (ie >> (8 - idx)) : (ie << (idx - 8)); // Position the estimation at the proper place
|
||||
*
|
||||
* x = uint32_t((x * uint64_t(_BV(25) - x * d)) >> 24); // Refine estimation by newton-raphson. 1 iteration is enough
|
||||
* const uint32_t r = _BV(24) - x * d; // Estimate remainder
|
||||
* x = uint64_t((x * uint64_t(_BV(25) - x * d)) >> 24); // Refine estimation by newton-raphson. 1 iteration is enough
|
||||
* const uint64_t r = _BV(24) - x * d; // Estimate remainder
|
||||
* if (r >= d) x++; // Check whether to adjust result
|
||||
* return uint32_t(x); // x holds the proper estimation
|
||||
* return uint64_t(x); // x holds the proper estimation
|
||||
*/
|
||||
static uint32_t get_period_inverse(uint32_t d) {
|
||||
static uint64_t get_period_inverse(uint64_t d) {
|
||||
|
||||
static const uint8_t inv_tab[256] PROGMEM = {
|
||||
255,253,252,250,248,246,244,242,240,238,236,234,233,231,229,227,
|
||||
@@ -381,7 +380,7 @@ void Planner::init() {
|
||||
// For small denominators, it is cheaper to directly store the result.
|
||||
// For bigger ones, just ONE Newton-Raphson iteration is enough to get
|
||||
// maximum precision we need
|
||||
static const uint32_t small_inv_tab[111] PROGMEM = {
|
||||
static const uint64_t small_inv_tab[111] PROGMEM = {
|
||||
16777216,16777216,8388608,5592405,4194304,3355443,2796202,2396745,2097152,1864135,1677721,1525201,1398101,1290555,1198372,1118481,
|
||||
1048576,986895,932067,883011,838860,798915,762600,729444,699050,671088,645277,621378,599186,578524,559240,541200,
|
||||
524288,508400,493447,479349,466033,453438,441505,430185,419430,409200,399457,390167,381300,372827,364722,356962,
|
||||
@@ -718,20 +717,18 @@ void Planner::init() {
|
||||
);
|
||||
|
||||
// Return the result
|
||||
return r11 | (uint16_t(r12) << 8) | (uint32_t(r13) << 16);
|
||||
return r11 | (uint16_t(r12) << 8) | (uint64_t(r13) << 16);
|
||||
}
|
||||
#else
|
||||
// All other 32-bit MPUs can easily do inverse using hardware division,
|
||||
// so we don't need to reduce precision or to use assembly language at all.
|
||||
// This routine, for all other archs, returns 0x100000000 / d ~= 0xFFFFFFFF / d
|
||||
FORCE_INLINE static uint32_t get_period_inverse(const uint32_t d) {
|
||||
FORCE_INLINE static uint64_t get_period_inverse(const uint64_t d) {
|
||||
return d ? 0xFFFFFFFF / d : 0xFFFFFFFF;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define MINIMAL_STEP_RATE 120
|
||||
|
||||
/**
|
||||
* Get the current block for processing
|
||||
* and mark the block as busy.
|
||||
@@ -768,10 +765,6 @@ block_t* Planner::get_current_block() {
|
||||
// As this block is busy, advance the nonbusy block pointer
|
||||
block_buffer_nonbusy = next_block_index(block_buffer_tail);
|
||||
|
||||
// Push block_buffer_planned pointer, if encountered.
|
||||
if (block_buffer_tail == block_buffer_planned)
|
||||
block_buffer_planned = block_buffer_nonbusy;
|
||||
|
||||
// Return the block
|
||||
return block;
|
||||
}
|
||||
@@ -784,33 +777,37 @@ block_t* Planner::get_current_block() {
|
||||
|
||||
/**
|
||||
* Calculate trapezoid parameters, multiplying the entry- and exit-speeds
|
||||
* by the provided factors. Requires that initial_rate and final_rate are
|
||||
* no less than sqrt(block->acceleration_steps_per_s2 / 2), which is ensured
|
||||
* through minimum_planner_speed_sqr in _populate_block().
|
||||
* by the provided factors. If entry_factor is 0 don't change the initial_rate.
|
||||
* Assumes that the implied initial_rate and final_rate are no less than
|
||||
* sqrt(block->acceleration_steps_per_s2 / 2). This is ensured through
|
||||
* minimum_planner_speed_sqr / min_entry_speed_sqr though note there's one
|
||||
* exception in recalculate_trapezoids().
|
||||
**
|
||||
* ############ VERY IMPORTANT ############
|
||||
* NOTE that the PRECONDITION to call this function is that the block is
|
||||
* NOT BUSY and it is marked as RECALCULATE. That WARRANTIES the Stepper ISR
|
||||
* is not and will not use the block while we modify it, so it is safe to
|
||||
* alter its values.
|
||||
* is not and will not use the block while we modify it.
|
||||
*/
|
||||
void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor) {
|
||||
void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed) {
|
||||
|
||||
uint32_t initial_rate = LROUND(block->nominal_rate * entry_factor),
|
||||
final_rate = LROUND(block->nominal_rate * exit_factor); // (steps per second)
|
||||
const float spmm = block->steps_per_mm;
|
||||
uint64_t initial_rate = entry_speed ? _MAX(long(MINIMAL_STEP_RATE), LROUND(entry_speed * spmm)) : block->initial_rate,
|
||||
final_rate = _MAX(long(MINIMAL_STEP_RATE), LROUND(exit_speed * spmm));
|
||||
|
||||
// Legacy check against supposed timer overflow. However Stepper::calc_timer_interval() already
|
||||
// should protect against it. But removing this code produces judder in direction-switching
|
||||
// moves. This is because the current discrete stepping math diverges from physical motion under
|
||||
// constant acceleration when acceleration_steps_per_s2 is large compared to initial/final_rate.
|
||||
NOLESS(initial_rate, uint32_t(MINIMAL_STEP_RATE)); // Enforce the minimum speed
|
||||
NOLESS(final_rate, uint32_t(MINIMAL_STEP_RATE));
|
||||
NOLESS(initial_rate, uint64_t(MINIMAL_STEP_RATE)); // Enforce the minimum speed
|
||||
NOLESS(final_rate, uint64_t(MINIMAL_STEP_RATE));
|
||||
|
||||
NOLESS(block->nominal_rate, MINIMAL_STEP_RATE);
|
||||
NOMORE(initial_rate, block->nominal_rate); // NOTE: The nominal rate may be less than MINIMAL_STEP_RATE!
|
||||
NOMORE(final_rate, block->nominal_rate);
|
||||
|
||||
#if ANY(S_CURVE_ACCELERATION, LIN_ADVANCE)
|
||||
// If we have some plateau time, the cruise rate will be the nominal rate
|
||||
uint32_t cruise_rate = block->nominal_rate;
|
||||
uint64_t cruise_rate = block->nominal_rate;
|
||||
#endif
|
||||
|
||||
// Steps for acceleration, plateau and deceleration
|
||||
@@ -827,7 +824,6 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
|
||||
// Steps required for acceleration, deceleration to/from nominal rate
|
||||
decelerate_steps_float = half_inverse_accel * (nominal_rate_sq - FLOAT_SQ(final_rate)),
|
||||
accelerate_steps_float = half_inverse_accel * (nominal_rate_sq - FLOAT_SQ(initial_rate));
|
||||
// Aims to fully reach nominal and final rates
|
||||
accelerate_steps = CEIL(accelerate_steps_float);
|
||||
decelerate_steps = CEIL(decelerate_steps_float);
|
||||
|
||||
@@ -853,7 +849,7 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
const float rate_factor = inverse_accel * (STEPPER_TIMER_RATE);
|
||||
// Jerk controlled speed requires to express speed versus time, NOT steps
|
||||
uint32_t acceleration_time = rate_factor * float(cruise_rate - initial_rate),
|
||||
uint64_t acceleration_time = rate_factor * float(cruise_rate - initial_rate),
|
||||
deceleration_time = rate_factor * float(cruise_rate - final_rate),
|
||||
// And to offload calculations from the ISR, we also calculate the inverse of those times here
|
||||
acceleration_time_inverse = get_period_inverse(acceleration_time),
|
||||
@@ -942,16 +938,16 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
|
||||
*
|
||||
* Recalculates the motion plan according to the following basic guidelines:
|
||||
*
|
||||
* 1. Go over every feasible block sequentially in reverse order and calculate the junction speeds
|
||||
* (i.e. current->entry_speed) such that:
|
||||
* a. No junction speed exceeds the pre-computed maximum junction speed limit or nominal speeds of
|
||||
* neighboring blocks.
|
||||
* b. A block entry speed cannot exceed one reverse-computed from its exit speed (next->entry_speed)
|
||||
* with a maximum allowable deceleration over the block travel distance.
|
||||
* c. The last (or newest appended) block is planned from safe_exit_speed_sqr.
|
||||
* 2. Go over every block in chronological (forward) order and dial down junction speed values if
|
||||
* a. The exit speed exceeds the one forward-computed from its entry speed with the maximum allowable
|
||||
* acceleration over the block travel distance.
|
||||
* 1. Go over blocks sequentially in reverse order and maximize the entry junction speed:
|
||||
* a. Entry speed should stay below/at the pre-computed maximum junction speed limit
|
||||
* b. Aim for the maximum entry speed which is the one reverse-computed from its exit speed
|
||||
* (next->entry_speed) if assuming maximum deceleration over the full block travel distance
|
||||
* c. The last (newest appended) block uses safe_exit_speed exit speed (there's no 'next')
|
||||
* 2. Go over blocks in chronological (forward) order and fix the exit junction speed:
|
||||
* a. Exit speed (next->entry_speed) must be below/at the maximum exit speed forward-computed
|
||||
* from its entry speed if assuming maximum acceleration over the full block travel distance
|
||||
* b. Exit speed should stay above/at the pre-computed minimum junction speed limit
|
||||
* 3. Convert entry / exit speeds (mm/s) into final/initial steps/s
|
||||
*
|
||||
* When these stages are complete, the planner will have maximized the velocity profiles throughout the all
|
||||
* of the planner blocks, where every block is operating at its maximum allowable acceleration limits. In
|
||||
@@ -959,28 +955,22 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
|
||||
* are possible. If a new block is added to the buffer, the plan is recomputed according to the said
|
||||
* guidelines for a new optimal plan.
|
||||
*
|
||||
* To increase computational efficiency of these guidelines, a set of planner block pointers have been
|
||||
* created to indicate stop-compute points for when the planner guidelines cannot logically make any further
|
||||
* changes or improvements to the plan when in normal operation and new blocks are streamed and added to the
|
||||
* planner buffer. For example, if a subset of sequential blocks in the planner have been planned and are
|
||||
* bracketed by junction velocities at their maximums (or by the first planner block as well), no new block
|
||||
* added to the planner buffer will alter the velocity profiles within them. So we no longer have to compute
|
||||
* them. Or, if a set of sequential blocks from the first block in the planner (or a optimal stop-compute
|
||||
* point) are all accelerating, they are all optimal and can not be altered by a new block added to the
|
||||
* planner buffer, as this will only further increase the plan speed to chronological blocks until a maximum
|
||||
* junction velocity is reached. However, if the operational conditions of the plan changes from infrequently
|
||||
* used feed holds or feedrate overrides, the stop-compute pointers will be reset and the entire plan is
|
||||
* recomputed as stated in the general guidelines.
|
||||
* To increase computational efficiency of these guidelines:
|
||||
* 1. We keep track of which blocks need calculation (block->flag.recalculate)
|
||||
* 2. We stop the reverse pass on the first block whose entry_speed == max_entry_speed. As soon
|
||||
* as that happens, there can be no further increases (ensured by the previous recalculate)
|
||||
* 3. On the forward pass we skip through to the first block with a modified exit speed
|
||||
* (next->entry_speed)
|
||||
* 4. On the forward pass if we encounter a full acceleration block that limits its exit speed
|
||||
* (next->entry_speed) we also update the maximum for that junction (next->max_entry_speed)
|
||||
* so it's never updated again
|
||||
* 5. We use speed squared (ex: entry_speed_sqr in mm^2/s^2) in acceleration limit computations
|
||||
* 6. We don't recompute sqrt(entry_speed_sqr) if the block's entry speed didn't change
|
||||
*
|
||||
* Planner buffer index mapping:
|
||||
* - block_buffer_tail: Points to the beginning of the planner buffer. First to be executed or being executed.
|
||||
* - block_buffer_head: Points to the buffer block after the last block in the buffer. Used to indicate whether
|
||||
* the buffer is full or empty. As described for standard ring buffers, this block is always empty.
|
||||
* - block_buffer_planned: Points to the first buffer block after the last optimally planned block for normal
|
||||
* streaming operating conditions. Use for planning optimizations by avoiding recomputing parts of the
|
||||
* planner buffer that don't change with the addition of a new block, as describe above. In addition,
|
||||
* this block can never be less than block_buffer_tail and will always be pushed forward and maintain
|
||||
* this requirement when encountered by the Planner::release_current_block() routine during a cycle.
|
||||
*
|
||||
* NOTE: Since the planner only computes on what's in the planner buffer, some motions with many short
|
||||
* segments (e.g., complex curves) may seem to move slowly. This is because there simply isn't
|
||||
@@ -1003,7 +993,8 @@ void Planner::calculate_trapezoid_for_block(block_t * const block, const_float_t
|
||||
*/
|
||||
|
||||
// The kernel called by recalculate() when scanning the plan from last to first entry.
|
||||
void Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) {
|
||||
// Returns true if it could increase the current block's entry speed.
|
||||
bool Planner::reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr) {
|
||||
// We need to recalculate only for the last block added or if next->entry_speed_sqr changed.
|
||||
if (!next || next->flag.recalculate) {
|
||||
// And only if we're not already at max entry speed.
|
||||
@@ -1021,196 +1012,136 @@ void Planner::reverse_pass_kernel(block_t * const current, const block_t * const
|
||||
// become BUSY just before being marked RECALCULATE, so check for that!
|
||||
if (stepper.is_block_busy(current)) {
|
||||
// Block became busy. Clear the RECALCULATE flag (no point in
|
||||
// recalculating BUSY blocks). And don't set its speed, as it can't
|
||||
// be updated at this time.
|
||||
// recalculating BUSY blocks).
|
||||
current->flag.recalculate = false;
|
||||
}
|
||||
else {
|
||||
// Block is not BUSY so this is ahead of the Stepper ISR:
|
||||
// Just Set the new entry speed.
|
||||
|
||||
current->entry_speed_sqr = new_entry_speed_sqr;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* recalculate() needs to go over the current plan twice.
|
||||
* Once in reverse and once forward. This implements the reverse pass.
|
||||
* Once in reverse and once forward. This implements the reverse pass that
|
||||
* coarsely maximizes the entry speeds starting from last block.
|
||||
* Requires there's at least one block with flag.recalculate in the buffer.
|
||||
*/
|
||||
void Planner::reverse_pass(const_float_t safe_exit_speed_sqr) {
|
||||
// Initialize block index to the last block in the planner buffer.
|
||||
// This last block will have flag.recalculate set.
|
||||
uint8_t block_index = prev_block_index(block_buffer_head);
|
||||
|
||||
// Read the index of the last buffer planned block.
|
||||
// The ISR may change it so get a stable local copy.
|
||||
uint8_t planned_block_index = block_buffer_planned;
|
||||
// The ISR may change block_buffer_nonbusy so get a stable local copy.
|
||||
uint8_t nonbusy_block_index = block_buffer_nonbusy;
|
||||
|
||||
// If there was a race condition and block_buffer_planned was incremented
|
||||
// or was pointing at the head (queue empty) break loop now and avoid
|
||||
// planning already consumed blocks
|
||||
if (planned_block_index == block_buffer_head) return;
|
||||
|
||||
// Reverse Pass: Coarsely maximize all possible deceleration curves back-planning from the last
|
||||
// block in buffer. Cease planning when the last optimal planned or tail pointer is reached.
|
||||
// NOTE: Forward pass will later refine and correct the reverse pass to create an optimal plan.
|
||||
const block_t *next = nullptr;
|
||||
while (block_index != planned_block_index) {
|
||||
|
||||
// Perform the reverse pass
|
||||
// Don't try to change the entry speed of the first non-busy block.
|
||||
while (block_index != nonbusy_block_index) {
|
||||
block_t *current = &block_buffer[block_index];
|
||||
|
||||
// Only process movement blocks
|
||||
if (current->is_move()) {
|
||||
reverse_pass_kernel(current, next, safe_exit_speed_sqr);
|
||||
// If no entry speed increase was possible we end the reverse pass.
|
||||
if (!reverse_pass_kernel(current, next, safe_exit_speed_sqr)) return;
|
||||
next = current;
|
||||
}
|
||||
|
||||
// Advance to the next
|
||||
block_index = prev_block_index(block_index);
|
||||
|
||||
// The ISR could advance the block_buffer_planned while we were doing the reverse pass.
|
||||
// The ISR could advance block_buffer_nonbusy while we were doing the reverse pass.
|
||||
// We must try to avoid using an already consumed block as the last one - So follow
|
||||
// changes to the pointer and make sure to limit the loop to the currently busy block
|
||||
while (planned_block_index != block_buffer_planned) {
|
||||
while (nonbusy_block_index != block_buffer_nonbusy) {
|
||||
|
||||
// If we reached the busy block or an already processed block, break the loop now
|
||||
if (block_index == planned_block_index) return;
|
||||
if (block_index == nonbusy_block_index) return;
|
||||
|
||||
// Advance the pointer, following the busy block
|
||||
planned_block_index = next_block_index(planned_block_index);
|
||||
nonbusy_block_index = next_block_index(nonbusy_block_index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The kernel called by recalculate() when scanning the plan from first to last entry.
|
||||
void Planner::forward_pass_kernel(const block_t * const previous, block_t * const current, const uint8_t block_index) {
|
||||
// Check against previous speed only on current->entry_speed_sqr changes (or if first time).
|
||||
if (current->flag.recalculate) {
|
||||
// If the previous block is accelerating check if it's too short to complete the full speed
|
||||
// change then adjust the entry speed accordingly. Entry speeds have already been maximized.
|
||||
if (previous->entry_speed_sqr < current->entry_speed_sqr) {
|
||||
float new_entry_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
|
||||
// The kernel called during the forward pass. Assumes current->flag.recalculate.
|
||||
void Planner::forward_pass_kernel(const block_t * const previous, block_t * const current) {
|
||||
// Check if the previous block is accelerating.
|
||||
if (previous->entry_speed_sqr < current->entry_speed_sqr) {
|
||||
// Compute the maximum achievable speed if the previous block was fully accelerating.
|
||||
float new_exit_speed_sqr = max_allowable_speed_sqr(-previous->acceleration, previous->entry_speed_sqr, previous->millimeters);
|
||||
|
||||
// If true, previous block is full-acceleration and we can move the planned pointer forward.
|
||||
if (new_entry_speed_sqr < current->entry_speed_sqr) {
|
||||
// Current entry speed limited by full acceleration from previous entry speed.
|
||||
// Make sure entry speed not lower than minimum_planner_speed_sqr.
|
||||
NOLESS(new_entry_speed_sqr, current->min_entry_speed_sqr);
|
||||
current->entry_speed_sqr = new_entry_speed_sqr;
|
||||
if (new_exit_speed_sqr < current->entry_speed_sqr) {
|
||||
// Current entry speed limited by full acceleration from previous entry speed.
|
||||
|
||||
// Set optimal plan pointer.
|
||||
block_buffer_planned = block_index;
|
||||
}
|
||||
else {
|
||||
// Previous entry speed has been maximized.
|
||||
block_buffer_planned = prev_block_index(block_index);
|
||||
}
|
||||
// Make sure entry speed not lower than minimum_planner_speed_sqr.
|
||||
NOLESS(new_exit_speed_sqr, current->min_entry_speed_sqr);
|
||||
current->entry_speed_sqr = new_exit_speed_sqr;
|
||||
// Ensure we don't try updating entry_speed_sqr again.
|
||||
current->max_entry_speed_sqr = new_exit_speed_sqr;
|
||||
}
|
||||
|
||||
// Any block set at its maximum entry speed also creates an optimal plan up to this
|
||||
// point in the buffer. When the plan is bracketed by either the beginning of the
|
||||
// buffer and a maximum entry speed or two maximum entry speeds, every block in between
|
||||
// cannot logically be further improved. Hence, we don't have to recompute them anymore.
|
||||
if (current->entry_speed_sqr == current->max_entry_speed_sqr)
|
||||
block_buffer_planned = block_index;
|
||||
}
|
||||
|
||||
// The fully optimized entry speed is our new minimum speed.
|
||||
current->min_entry_speed_sqr = current->entry_speed_sqr;
|
||||
}
|
||||
|
||||
/**
|
||||
* recalculate() needs to go over the current plan twice.
|
||||
* Once in reverse and once forward. This implements the forward pass.
|
||||
*/
|
||||
void Planner::forward_pass() {
|
||||
|
||||
// Forward Pass: Forward plan the acceleration curve from the planned pointer onward.
|
||||
// Also scans for optimal plan breakpoints and appropriately updates the planned pointer.
|
||||
|
||||
// Begin at buffer planned pointer. Note that block_buffer_planned can be modified
|
||||
// by the stepper ISR, so read it ONCE. It it guaranteed that block_buffer_planned
|
||||
// will never lead head, so the loop is safe to execute. Also note that the forward
|
||||
// pass will never modify the values at the tail.
|
||||
uint8_t block_index = block_buffer_planned;
|
||||
|
||||
block_t *block;
|
||||
const block_t * previous = nullptr;
|
||||
while (block_index != block_buffer_head) {
|
||||
|
||||
// Perform the forward pass
|
||||
block = &block_buffer[block_index];
|
||||
|
||||
// Only process movement blocks
|
||||
if (block->is_move()) {
|
||||
// If there's no previous block or the previous block is not
|
||||
// BUSY (thus, modifiable) run the forward_pass_kernel. Otherwise,
|
||||
// the previous block became BUSY, so assume the current block's
|
||||
// entry speed can't be altered (since that would also require
|
||||
// updating the exit speed of the previous block).
|
||||
if (previous && !stepper.is_block_busy(previous))
|
||||
forward_pass_kernel(previous, block, block_index);
|
||||
previous = block;
|
||||
}
|
||||
// Advance to the previous
|
||||
block_index = next_block_index(block_index);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate the trapezoid speed profiles for all blocks in the plan
|
||||
* according to the entry_factor for each junction. Must be called by
|
||||
* recalculate() after updating the blocks.
|
||||
* Do the forward pass and recalculate the trapezoid speed profiles for all blocks in the plan
|
||||
* according to entry/exit speeds.
|
||||
*/
|
||||
void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
|
||||
// The tail may be changed by the ISR so get a local copy.
|
||||
// Start with the block that's about to execute or is executing.
|
||||
uint8_t block_index = block_buffer_tail,
|
||||
head_block_index = block_buffer_head;
|
||||
// Since there could be a sync block in the head of the queue, and the
|
||||
// next loop must not recalculate the head block (as it needs to be
|
||||
// specially handled), scan backwards to the first non-SYNC block.
|
||||
while (head_block_index != block_index) {
|
||||
|
||||
// Go back (head always point to the first free block)
|
||||
const uint8_t prev_index = prev_block_index(head_block_index);
|
||||
|
||||
// Get the pointer to the block
|
||||
block_t *prev = &block_buffer[prev_index];
|
||||
|
||||
// It the block is a move, we're done with this loop
|
||||
if (prev->is_move()) break;
|
||||
|
||||
// Examine the previous block. This and all following are SYNC blocks
|
||||
head_block_index = prev_index;
|
||||
}
|
||||
|
||||
// Go from the tail (currently executed block) to the first block, without including it)
|
||||
block_t *block = nullptr, *next = nullptr;
|
||||
float current_entry_speed = 0.0f, next_entry_speed = 0.0f;
|
||||
float next_entry_speed = 0.0f;
|
||||
while (block_index != head_block_index) {
|
||||
|
||||
next = &block_buffer[block_index];
|
||||
|
||||
// Only process movement blocks
|
||||
if (next->is_move()) {
|
||||
next_entry_speed = SQRT(next->entry_speed_sqr);
|
||||
// Check if the next block's entry speed changed
|
||||
if (next->flag.recalculate) {
|
||||
if (!block) {
|
||||
// 'next' is the first move due to either being the first added move or due to the planner
|
||||
// having completely fallen behind. Revert any reverse pass change.
|
||||
next->entry_speed_sqr = next->min_entry_speed_sqr;
|
||||
next_entry_speed = SQRT(next->min_entry_speed_sqr);
|
||||
}
|
||||
else {
|
||||
// Try to fix exit speed which requires trapezoid recalculation
|
||||
block->flag.recalculate = true;
|
||||
|
||||
if (block) {
|
||||
// But there is an inherent race condition here, as the block may have
|
||||
// become BUSY just before being marked RECALCULATE, so check for that!
|
||||
if (stepper.is_block_busy(block)) {
|
||||
// Block is BUSY so we can't change the exit speed. Revert any reverse pass change.
|
||||
next->entry_speed_sqr = next->min_entry_speed_sqr;
|
||||
if (!next->initial_rate) {
|
||||
// 'next' was never calculated. Planner is falling behind so for maximum efficiency
|
||||
// set next's stepping speed directly and forgo checking against min_entry_speed_sqr.
|
||||
// calculate_trapezoid_for_block() can handle it, albeit sub-optimally.
|
||||
next->initial_rate = block->final_rate;
|
||||
}
|
||||
// Note that at this point next_entry_speed is (still) 0.
|
||||
}
|
||||
else {
|
||||
// Block is not BUSY: we won the race against the ISR or recalculate was already set
|
||||
|
||||
// If the next block is marked to RECALCULATE, also mark the previously-fetched one
|
||||
if (next->flag.recalculate) block->flag.recalculate = true;
|
||||
if (next->entry_speed_sqr != next->min_entry_speed_sqr)
|
||||
forward_pass_kernel(block, next);
|
||||
|
||||
// Recalculate if current block entry or exit junction speed has changed.
|
||||
if (block->flag.recalculate) {
|
||||
const float current_entry_speed = next_entry_speed;
|
||||
next_entry_speed = SQRT(next->entry_speed_sqr);
|
||||
|
||||
// But there is an inherent race condition here, as the block maybe
|
||||
// became BUSY, just before it was marked as RECALCULATE, so check
|
||||
// if that is the case!
|
||||
if (!stepper.is_block_busy(block)) {
|
||||
// Block is not BUSY, we won the race against the Stepper ISR:
|
||||
|
||||
// NOTE: Entry and exit factors always > 0 by all previous logic operations.
|
||||
const float nomr = 1.0f / block->nominal_speed;
|
||||
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
|
||||
calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed);
|
||||
}
|
||||
|
||||
// Reset current only to ensure next trapezoid is computed - The
|
||||
@@ -1220,30 +1151,17 @@ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
|
||||
}
|
||||
|
||||
block = next;
|
||||
current_entry_speed = next_entry_speed;
|
||||
}
|
||||
|
||||
block_index = next_block_index(block_index);
|
||||
}
|
||||
|
||||
// Last/newest block in buffer. Always recalculated.
|
||||
if (block) {
|
||||
// Last/newest block in buffer. The above guarantees it's a move block.
|
||||
if (block && block->flag.recalculate) {
|
||||
const float current_entry_speed = next_entry_speed;
|
||||
next_entry_speed = SQRT(safe_exit_speed_sqr);
|
||||
|
||||
// Mark the next(last) block as RECALCULATE, to prevent the Stepper ISR running it.
|
||||
// As the last block is always recalculated here, there is a chance the block isn't
|
||||
// marked as RECALCULATE yet. That's the reason for the following line.
|
||||
block->flag.recalculate = true;
|
||||
|
||||
// But there is an inherent race condition here, as the block maybe
|
||||
// became BUSY, just before it was marked as RECALCULATE, so check
|
||||
// if that is the case!
|
||||
if (!stepper.is_block_busy(block)) {
|
||||
// Block is not BUSY, we won the race against the Stepper ISR:
|
||||
|
||||
const float nomr = 1.0f / block->nominal_speed;
|
||||
calculate_trapezoid_for_block(block, current_entry_speed * nomr, next_entry_speed * nomr);
|
||||
}
|
||||
calculate_trapezoid_for_block(block, current_entry_speed, next_entry_speed);
|
||||
|
||||
// Reset block to ensure its trapezoid is computed - The stepper is free to use
|
||||
// the block from now on.
|
||||
@@ -1251,14 +1169,10 @@ void Planner::recalculate_trapezoids(const_float_t safe_exit_speed_sqr) {
|
||||
}
|
||||
}
|
||||
|
||||
// Requires there's at least one block with flag.recalculate in the buffer
|
||||
void Planner::recalculate(const_float_t safe_exit_speed_sqr) {
|
||||
// Initialize block index to the last block in the planner buffer.
|
||||
const uint8_t block_index = prev_block_index(block_buffer_head);
|
||||
// If there is just one block, no planning can be done. Avoid it!
|
||||
if (block_index != block_buffer_planned) {
|
||||
reverse_pass(safe_exit_speed_sqr);
|
||||
forward_pass();
|
||||
}
|
||||
reverse_pass(safe_exit_speed_sqr);
|
||||
// The forward pass is done as part of recalculate_trapezoids()
|
||||
recalculate_trapezoids(safe_exit_speed_sqr);
|
||||
}
|
||||
|
||||
@@ -1667,7 +1581,7 @@ void Planner::quick_stop() {
|
||||
const bool was_enabled = stepper.suspend();
|
||||
|
||||
// Drop all queue entries
|
||||
block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail;
|
||||
block_buffer_nonbusy = block_buffer_head = block_buffer_tail;
|
||||
|
||||
// Restart the block delay for the first movement - As the queue was
|
||||
// forced to empty, there's no risk the ISR will touch this.
|
||||
@@ -1995,9 +1909,9 @@ bool Planner::_populate_block(
|
||||
#if HAS_EXTRUDERS
|
||||
dm.e = (dist.e > 0);
|
||||
const float esteps_float = dist.e * e_factor[extruder];
|
||||
const uint32_t esteps = ABS(esteps_float);
|
||||
const uint64_t esteps = ABS(esteps_float);
|
||||
#else
|
||||
constexpr uint32_t esteps = 0;
|
||||
constexpr uint64_t esteps = 0;
|
||||
#endif
|
||||
|
||||
// Clear all flags, including the "busy" bit
|
||||
@@ -2436,7 +2350,8 @@ bool Planner::_populate_block(
|
||||
|
||||
// Compute and limit the acceleration rate for the trapezoid generator.
|
||||
const float steps_per_mm = block->step_event_count * inverse_millimeters;
|
||||
uint32_t accel;
|
||||
block->steps_per_mm = steps_per_mm;
|
||||
uint64_t accel;
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
bool use_advance_lead = false;
|
||||
#endif
|
||||
@@ -2446,7 +2361,7 @@ bool Planner::_populate_block(
|
||||
else {
|
||||
#define LIMIT_ACCEL_LONG(AXIS,INDX) do{ \
|
||||
if (block->steps[AXIS] && max_acceleration_steps_per_s2[AXIS+INDX] < accel) { \
|
||||
const uint32_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \
|
||||
const uint64_t max_possible = max_acceleration_steps_per_s2[AXIS+INDX] * block->step_event_count / block->steps[AXIS]; \
|
||||
NOMORE(accel, max_possible); \
|
||||
} \
|
||||
}while(0)
|
||||
@@ -2490,7 +2405,7 @@ bool Planner::_populate_block(
|
||||
use_advance_lead = false;
|
||||
else {
|
||||
// Scale E acceleration so that it will be possible to jump to the advance speed.
|
||||
const uint32_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
|
||||
const uint64_t max_accel_steps_per_s2 = MAX_E_JERK(extruder) / (extruder_advance_K[E_INDEX_N(extruder)] * e_D_ratio) * steps_per_mm;
|
||||
if (accel > max_accel_steps_per_s2) {
|
||||
accel = max_accel_steps_per_s2;
|
||||
if (ENABLED(LA_DEBUG)) SERIAL_ECHOLNPGM("Acceleration limited.");
|
||||
@@ -2520,7 +2435,7 @@ bool Planner::_populate_block(
|
||||
block->acceleration_steps_per_s2 = accel;
|
||||
block->acceleration = accel / steps_per_mm;
|
||||
#if DISABLED(S_CURVE_ACCELERATION)
|
||||
block->acceleration_rate = (uint32_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
|
||||
block->acceleration_rate = (uint64_t)(accel * (float(1UL << 24) / (STEPPER_TIMER_RATE)));
|
||||
#endif
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
@@ -2533,7 +2448,7 @@ bool Planner::_populate_block(
|
||||
|
||||
// reduce LA ISR frequency by calling it only often enough to ensure that there will
|
||||
// never be more than four extruder steps per call
|
||||
for (uint32_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
|
||||
for (uint64_t dividend = block->steps.e << 1; dividend <= (block->step_event_count >> 2); dividend <<= 1)
|
||||
block->la_scaling++;
|
||||
|
||||
#if ENABLED(LA_DEBUG)
|
||||
@@ -2546,7 +2461,7 @@ bool Planner::_populate_block(
|
||||
// Formula for the average speed over a 1 step worth of distance if starting from zero and
|
||||
// accelerating at the current limit. Since we can only change the speed every step this is a
|
||||
// good lower limit for the entry and exit speeds. Note that for calculate_trapezoid_for_block()
|
||||
// to work correctly, this must be accurately set and propagated.
|
||||
// to work correctly this must be accurately set and propagated.
|
||||
minimum_planner_speed_sqr = 0.5f * block->acceleration / steps_per_mm;
|
||||
// Go straight to/from nominal speed if block->acceleration is too high for it.
|
||||
NOMORE(minimum_planner_speed_sqr, sq(block->nominal_speed));
|
||||
@@ -2772,7 +2687,7 @@ bool Planner::_populate_block(
|
||||
// Advance affects E_AXIS speed and therefore jerk. Add a speed correction whenever
|
||||
// LA is turned OFF. No correction is applied when LA is turned ON (because it didn't
|
||||
// perform well; it takes more time/effort to push/melt filament than the reverse).
|
||||
static uint32_t previous_advance_rate;
|
||||
static uint64_t previous_advance_rate;
|
||||
static float previous_e_mm_per_step;
|
||||
if (dist.e < 0 && previous_advance_rate) {
|
||||
// Retract move after a segment with LA that ended with an E speed decrease.
|
||||
@@ -2820,7 +2735,7 @@ bool Planner::_populate_block(
|
||||
#endif // CLASSIC_JERK
|
||||
|
||||
// High acceleration limits override low jerk/junction deviation limits (as fixing trapezoids
|
||||
// or reducing acceleration introduces too much complexity and/or too much compute)
|
||||
// or reducing acceleration introduces too much complexity and/or too much compute).
|
||||
NOLESS(vmax_junction_sqr, minimum_planner_speed_sqr);
|
||||
|
||||
// Max entry speed of this block equals the max exit speed of the previous block.
|
||||
@@ -2829,6 +2744,8 @@ bool Planner::_populate_block(
|
||||
block->entry_speed_sqr = minimum_planner_speed_sqr;
|
||||
// Set min entry speed. Rarely it could be higher than the previous nominal speed but that's ok.
|
||||
block->min_entry_speed_sqr = minimum_planner_speed_sqr;
|
||||
// Zero the initial_rate to indicate that calculate_trapezoid_for_block() hasn't been called yet.
|
||||
block->initial_rate = 0;
|
||||
|
||||
block->flag.recalculate = true;
|
||||
|
||||
@@ -3275,7 +3192,7 @@ void Planner::set_position_mm(const xyze_pos_t &xyze) {
|
||||
|
||||
// Recalculate the steps/s^2 acceleration rates, based on the mm/s^2
|
||||
void Planner::refresh_acceleration_rates() {
|
||||
uint32_t highest_rate = 1;
|
||||
uint64_t highest_rate = 1;
|
||||
LOOP_DISTINCT_AXES(i) {
|
||||
max_acceleration_steps_per_s2[i] = settings.max_acceleration_mm_per_s2[i] * settings.axis_steps_per_mm[i];
|
||||
if (TERN1(DISTINCT_E_FACTORS, i < E_AXIS || i == E_AXIS_N(active_extruder)))
|
||||
@@ -3388,7 +3305,7 @@ void Planner::set_max_feedrate(const AxisEnum axis, float inMaxFeedrateMMS) {
|
||||
const bool was_enabled = stepper.suspend();
|
||||
#endif
|
||||
|
||||
uint32_t bbru = block_buffer_runtime_us;
|
||||
uint64_t bbru = block_buffer_runtime_us;
|
||||
|
||||
#ifdef __AVR__
|
||||
// Reenable Stepper ISR
|
||||
|
||||
+26
-19
@@ -78,6 +78,14 @@
|
||||
#include "../feature/closedloop.h"
|
||||
#endif
|
||||
|
||||
constexpr uint64_t MINIMAL_STEP_RATE = (
|
||||
#ifdef CPU_32_BIT
|
||||
_MAX((STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX, 1U) // 32-bit shouldn't go below 1
|
||||
#else
|
||||
(F_CPU) / 500000U // AVR shouldn't go below 32 (16MHz) or 40 (20MHz)
|
||||
#endif
|
||||
);
|
||||
|
||||
// Feedrate for manual moves
|
||||
#ifdef MANUAL_FEEDRATE
|
||||
constexpr xyze_feedrate_t manual_feedrate_mm_m = MANUAL_FEEDRATE,
|
||||
@@ -219,13 +227,14 @@ typedef struct PlannerBlock {
|
||||
min_entry_speed_sqr, // Minimum allowable junction entry speed in (mm/sec)^2
|
||||
max_entry_speed_sqr, // Maximum allowable junction entry speed in (mm/sec)^2
|
||||
millimeters, // The total travel of this block in mm
|
||||
steps_per_mm, // steps/mm
|
||||
acceleration; // acceleration mm/sec^2
|
||||
|
||||
union {
|
||||
abce_ulong_t steps; // Step count along each axis
|
||||
abce_long_t position; // New position to force when this sync block is executed
|
||||
};
|
||||
uint32_t step_event_count; // The number of step events required to complete this block
|
||||
uint64_t step_event_count; // The number of step events required to complete this block
|
||||
|
||||
#if HAS_MULTI_EXTRUDER
|
||||
uint8_t extruder; // The extruder to move (if E move)
|
||||
@@ -238,30 +247,30 @@ typedef struct PlannerBlock {
|
||||
#endif
|
||||
|
||||
// Settings for the trapezoid generator
|
||||
uint32_t accelerate_before, // The index of the step event where cruising starts
|
||||
uint64_t accelerate_before, // The index of the step event on which to start cruising
|
||||
decelerate_start; // The index of the step event on which to start decelerating
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
uint32_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase
|
||||
uint64_t cruise_rate, // The actual cruise rate to use, between end of the acceleration phase and start of deceleration phase
|
||||
acceleration_time, // Acceleration time and deceleration time in STEP timer counts
|
||||
deceleration_time,
|
||||
acceleration_time_inverse, // Inverse of acceleration and deceleration periods, expressed as integer. Scale depends on CPU being used
|
||||
deceleration_time_inverse;
|
||||
#else
|
||||
uint32_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s
|
||||
uint64_t acceleration_rate; // Acceleration rate in (2^24 steps)/timer_ticks*s
|
||||
#endif
|
||||
|
||||
AxisBits direction_bits; // Direction bits set for this block, where 1 is negative motion
|
||||
|
||||
// Advance extrusion
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
uint32_t la_advance_rate; // The rate at which steps are added whilst accelerating
|
||||
uint64_t la_advance_rate; // The rate at which steps are added whilst accelerating
|
||||
uint8_t la_scaling; // Scale ISR frequency down and step frequency up by 2 ^ la_scaling
|
||||
uint16_t max_adv_steps, // Max advance steps to get cruising speed pressure
|
||||
final_adv_steps; // Advance steps for exit speed pressure
|
||||
#endif
|
||||
|
||||
uint32_t nominal_rate, // The nominal step rate for this block in step_events/sec
|
||||
uint64_t nominal_rate, // The nominal step rate for this block in step_events/sec
|
||||
initial_rate, // The jerk-adjusted step rate at start of block
|
||||
final_rate, // The minimal rate at exit
|
||||
acceleration_steps_per_s2; // acceleration steps/sec^2
|
||||
@@ -283,11 +292,11 @@ typedef struct PlannerBlock {
|
||||
#endif
|
||||
|
||||
#if HAS_WIRED_LCD
|
||||
uint32_t segment_time_us;
|
||||
uint64_t segment_time_us;
|
||||
#endif
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
uint32_t sdpos;
|
||||
uint64_t sdpos;
|
||||
xyze_pos_t start_position;
|
||||
#endif
|
||||
|
||||
@@ -338,7 +347,7 @@ constexpr uint8_t block_inc_mod(const uint8_t v1, const uint8_t v2) {
|
||||
#endif
|
||||
|
||||
typedef struct PlannerSettings {
|
||||
uint32_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE
|
||||
uint64_t max_acceleration_mm_per_s2[DISTINCT_AXES], // (mm/s^2) M201 XYZE
|
||||
min_segment_time_us; // (µs) M205 B
|
||||
|
||||
// (steps) M92 XYZE - Steps per millimeter
|
||||
@@ -442,7 +451,6 @@ class Planner {
|
||||
static block_t block_buffer[BLOCK_BUFFER_SIZE];
|
||||
static volatile uint8_t block_buffer_head, // Index of the next block to be pushed
|
||||
block_buffer_nonbusy, // Index of the first non busy block
|
||||
block_buffer_planned, // Index of the optimally planned block
|
||||
block_buffer_tail; // Index of the busy block, if any
|
||||
static uint16_t cleaning_buffer_counter; // A counter to disable queuing of blocks
|
||||
static uint8_t delay_before_delivering; // This counter delays delivery of blocks when queue becomes empty to allow the opportunity of merging blocks
|
||||
@@ -452,7 +460,7 @@ class Planner {
|
||||
#endif
|
||||
|
||||
#if ENABLED(DIRECT_STEPPING)
|
||||
static uint32_t last_page_step_rate; // Last page step rate given
|
||||
static uint64_t last_page_step_rate; // Last page step rate given
|
||||
static AxisBits last_page_dir; // Last page direction given, where 1 represents forward or positive motion
|
||||
#endif
|
||||
|
||||
@@ -479,7 +487,7 @@ class Planner {
|
||||
static laser_state_t laser_inline;
|
||||
#endif
|
||||
|
||||
static uint32_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
|
||||
static uint64_t max_acceleration_steps_per_s2[DISTINCT_AXES]; // (steps/s^2) Derived from mm_per_s2
|
||||
|
||||
#if ENABLED(EDITABLE_STEPS_PER_UNIT)
|
||||
static float mm_per_step[DISTINCT_AXES]; // Millimeters per step
|
||||
@@ -569,7 +577,7 @@ class Planner {
|
||||
/**
|
||||
* Limit where 64bit math is necessary for acceleration calculation
|
||||
*/
|
||||
static uint32_t acceleration_long_cutoff;
|
||||
static uint64_t acceleration_long_cutoff;
|
||||
|
||||
#ifdef MAX7219_DEBUG_SLOWDOWN
|
||||
friend class Max7219;
|
||||
@@ -586,7 +594,7 @@ class Planner {
|
||||
#endif
|
||||
|
||||
#if HAS_WIRED_LCD
|
||||
volatile static uint32_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs
|
||||
volatile static uint64_t block_buffer_runtime_us; // Theoretical block buffer runtime in µs
|
||||
#endif
|
||||
|
||||
public:
|
||||
@@ -804,7 +812,7 @@ class Planner {
|
||||
FORCE_INLINE static uint8_t nonbusy_movesplanned() { return block_dec_mod(block_buffer_head, block_buffer_nonbusy); }
|
||||
|
||||
// Remove all blocks from the buffer
|
||||
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_planned = block_buffer_head = block_buffer_tail = 0; }
|
||||
FORCE_INLINE static void clear_block_buffer() { block_buffer_nonbusy = block_buffer_head = block_buffer_tail = 0; }
|
||||
|
||||
// Check if movement queue is full
|
||||
FORCE_INLINE static bool is_full() { return block_buffer_tail == next_block_index(block_buffer_head); }
|
||||
@@ -1081,13 +1089,12 @@ class Planner {
|
||||
}
|
||||
#endif
|
||||
|
||||
static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_factor, const_float_t exit_factor);
|
||||
static void calculate_trapezoid_for_block(block_t * const block, const_float_t entry_speed, const_float_t exit_speed);
|
||||
|
||||
static void reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr);
|
||||
static void forward_pass_kernel(const block_t * const previous, block_t * const current, uint8_t block_index);
|
||||
static bool reverse_pass_kernel(block_t * const current, const block_t * const next, const_float_t safe_exit_speed_sqr);
|
||||
static void forward_pass_kernel(const block_t * const previous, block_t * const current);
|
||||
|
||||
static void reverse_pass(const_float_t safe_exit_speed_sqr);
|
||||
static void forward_pass();
|
||||
|
||||
static void recalculate_trapezoids(const_float_t safe_exit_speed_sqr);
|
||||
|
||||
|
||||
+227
-99
@@ -58,16 +58,10 @@
|
||||
*
|
||||
* time ----->
|
||||
*
|
||||
* The speed over time graph forms a TRAPEZOID. The slope of acceleration is calculated by
|
||||
* v = u + t
|
||||
* where 't' is the accumulated timer values of the steps so far.
|
||||
*
|
||||
* The Stepper ISR dynamically executes acceleration, deceleration, and cruising according to the block parameters.
|
||||
* - Start at block->initial_rate.
|
||||
* - Accelerate while step_events_completed < block->accelerate_before.
|
||||
* - Cruise while step_events_completed < block->decelerate_start.
|
||||
* - Decelerate after that, until all steps are completed.
|
||||
* - Reset the trapezoid generator.
|
||||
* The trapezoid is the shape the speed curve over time. It starts at block->initial_rate, accelerates
|
||||
* while step_events_completed < block->accelerate_before, then starts cruising at constant speed while
|
||||
* step_events_completed < block->decelerate_start, then it decelerates until the trapezoid generator is reset.
|
||||
* The slope of acceleration is calculated using v = u + at where t is the accumulated timer values of the steps so far.
|
||||
*/
|
||||
|
||||
/**
|
||||
@@ -160,9 +154,9 @@ Stepper stepper; // Singleton
|
||||
|
||||
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
|
||||
bool Stepper::initialized; // = false
|
||||
uint32_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
|
||||
uint64_t Stepper::motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
|
||||
#if HAS_MOTOR_CURRENT_SPI
|
||||
constexpr uint32_t Stepper::digipot_count[];
|
||||
constexpr uint64_t Stepper::digipot_count[];
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -200,7 +194,7 @@ bool Stepper::abort_current_block;
|
||||
#endif
|
||||
|
||||
// In timer_ticks
|
||||
uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
|
||||
uint64_t Stepper::acceleration_time, Stepper::deceleration_time;
|
||||
|
||||
#if MULTISTEPPING_LIMIT > 1
|
||||
uint8_t Stepper::steps_per_isr = 1; // Count of steps to perform per Stepper ISR call
|
||||
@@ -229,7 +223,7 @@ uint32_t Stepper::acceleration_time, Stepper::deceleration_time;
|
||||
xyze_long_t Stepper::delta_error{0};
|
||||
|
||||
xyze_long_t Stepper::advance_dividend{0};
|
||||
uint32_t Stepper::advance_divisor = 0,
|
||||
uint64_t Stepper::advance_divisor = 0,
|
||||
Stepper::step_events_completed = 0, // The number of step events executed in the current block
|
||||
Stepper::accelerate_before, // The count at which to start cruising
|
||||
Stepper::decelerate_start, // The count at which to start decelerating
|
||||
@@ -245,8 +239,8 @@ uint32_t Stepper::advance_divisor = 0,
|
||||
int32_t __attribute__((used)) Stepper::bezier_A __asm__("bezier_A"); // A coefficient in Bézier speed curve with alias for assembler
|
||||
int32_t __attribute__((used)) Stepper::bezier_B __asm__("bezier_B"); // B coefficient in Bézier speed curve with alias for assembler
|
||||
int32_t __attribute__((used)) Stepper::bezier_C __asm__("bezier_C"); // C coefficient in Bézier speed curve with alias for assembler
|
||||
uint32_t __attribute__((used)) Stepper::bezier_F __asm__("bezier_F"); // F coefficient in Bézier speed curve with alias for assembler
|
||||
uint32_t __attribute__((used)) Stepper::bezier_AV __asm__("bezier_AV"); // AV coefficient in Bézier speed curve with alias for assembler
|
||||
uint64_t __attribute__((used)) Stepper::bezier_F __asm__("bezier_F"); // F coefficient in Bézier speed curve with alias for assembler
|
||||
uint64_t __attribute__((used)) Stepper::bezier_AV __asm__("bezier_AV"); // AV coefficient in Bézier speed curve with alias for assembler
|
||||
#ifdef __AVR__
|
||||
bool __attribute__((used)) Stepper::A_negative __asm__("A_negative"); // If A coefficient was negative
|
||||
#endif
|
||||
@@ -266,7 +260,7 @@ uint32_t Stepper::advance_divisor = 0,
|
||||
ne_coeff_t Stepper::ne;
|
||||
ne_fix_t Stepper::ne_fix;
|
||||
int32_t Stepper::ne_edividend;
|
||||
uint32_t Stepper::ne_scale;
|
||||
uint64_t Stepper::ne_scale;
|
||||
#endif
|
||||
|
||||
#if HAS_ZV_SHAPING
|
||||
@@ -303,7 +297,7 @@ uint32_t Stepper::advance_divisor = 0,
|
||||
|
||||
hal_timer_t Stepper::ticks_nominal = 0;
|
||||
#if DISABLED(S_CURVE_ACCELERATION)
|
||||
uint32_t Stepper::acc_step_rate; // needed for deceleration start point
|
||||
uint64_t Stepper::acc_step_rate; // needed for deceleration start point
|
||||
#endif
|
||||
|
||||
xyz_long_t Stepper::endstops_trigsteps;
|
||||
@@ -691,7 +685,7 @@ void Stepper::apply_directions() {
|
||||
* a "linear pop" velocity curve; with pop being the sixth derivative of position:
|
||||
* velocity - 1st, acceleration - 2nd, jerk - 3rd, snap - 4th, crackle - 5th, pop - 6th
|
||||
*
|
||||
* The Bézier curve takes the form:
|
||||
* The 6th order Bézier curve takes the form:
|
||||
*
|
||||
* V(t) = P_0 * B_0(t) + P_1 * B_1(t) + P_2 * B_2(t) + P_3 * B_3(t) + P_4 * B_4(t) + P_5 * B_5(t)
|
||||
*
|
||||
@@ -711,7 +705,10 @@ void Stepper::apply_directions() {
|
||||
* Unfortunately, we cannot use forward-differencing to calculate each position through
|
||||
* the curve, as Marlin uses variable timer periods. So, we require a formula of the form:
|
||||
*
|
||||
* 6th order:
|
||||
* V_f(t) = A*t^5 + B*t^4 + C*t^3 + D*t^2 + E*t + F
|
||||
* 4th order:
|
||||
* V_f(t) = A*t^3 + B*t^2 + C*t + F
|
||||
*
|
||||
* Looking at the above B_0(t) through B_5(t) expanded forms, if we take the coefficients of t^5
|
||||
* through t of the Bézier form of V(t), we can determine that:
|
||||
@@ -734,15 +731,27 @@ void Stepper::apply_directions() {
|
||||
* E = 0
|
||||
* F = P_i
|
||||
*
|
||||
* For 4th order we want the initial and final acceleration to be a fixed S_CURVE_FACTOR fraction
|
||||
* and solving gives us:
|
||||
*
|
||||
* A = 2*(1 - S_CURVE_FACTOR)*(P_i - P_t)
|
||||
* B = 3*(1 - S_CURVE_FACTOR)*(P_t - P_i)
|
||||
* C = S_CURVE_FACTOR*(P_t - P_i)
|
||||
* F = P_i
|
||||
*
|
||||
* As the t is evaluated in non uniform steps here, there is no other way rather than evaluating
|
||||
* the Bézier curve at each point:
|
||||
*
|
||||
* 6th order:
|
||||
* V_f(t) = A*t^5 + B*t^4 + C*t^3 + F [0 <= t <= 1]
|
||||
* 4th order:
|
||||
* V_f(t) = A*t^3 + B*t^2 + C*t + F [0 <= t <= 1]
|
||||
*
|
||||
* Floating point arithmetic execution time cost is prohibitive, so we will transform the math to
|
||||
* use fixed point values to be able to evaluate it in realtime. Assuming a maximum of 250000 steps
|
||||
* per second (driver pulses should at least be 2µS hi/2µS lo), and allocating 2 bits to avoid
|
||||
* overflows on the evaluation of the Bézier curve, means we can use
|
||||
* use fixed point values to be able to evaluate it in realtime.
|
||||
*
|
||||
* 6th order: Assumes a maximum of 250000 steps/s (driver pulses down to 2µS hi/2µS lo),
|
||||
* and allocates 2 bits to avoid overflows on the evaluation of the Bézier curve:
|
||||
*
|
||||
* t: unsigned Q0.32 (0 <= t < 1) |range 0 to 0xFFFFFFFF unsigned
|
||||
* A: signed Q24.7 , |range = +/- 250000 * 6 * 128 = +/- 192000000 = 0x0B71B000 | 28 bits + sign
|
||||
@@ -750,6 +759,8 @@ void Stepper::apply_directions() {
|
||||
* C: signed Q24.7 , |range = +/- 250000 *10 * 128 = +/- 320000000 = 0x1312D000 | 29 bits + sign
|
||||
* F: signed Q24.7 , |range = +/- 250000 * 128 = 32000000 = 0x01E84800 | 25 bits + sign
|
||||
*
|
||||
* 4th order: With B coefficient at least 5x smaller the maximum will be ~1250000 steps/s.
|
||||
*
|
||||
* The trapezoid generator state contains the following information, that we will use to create and evaluate
|
||||
* the Bézier curve:
|
||||
*
|
||||
@@ -764,42 +775,48 @@ void Stepper::apply_directions() {
|
||||
*
|
||||
* At the start of each trapezoid, calculate the coefficients A,B,C,F and Advance [AV], as follows:
|
||||
*
|
||||
* 6th order:
|
||||
* A = 6*128*(VF - VI) = 768*(VF - VI)
|
||||
* B = 15*128*(VI - VF) = 1920*(VI - VF)
|
||||
* C = 10*128*(VF - VI) = 1280*(VF - VI)
|
||||
* 4th order:
|
||||
* A = 2*(1-S_CURVE_FACTOR)*128*(VI - VF)
|
||||
* B = 3*(1-S_CURVE_FACTOR)*128*(VF - VI)
|
||||
* C = S_CURVE_FACTOR*128*(VF - VI)
|
||||
* both:
|
||||
* F = 128*VI = 128*VI
|
||||
* AV = (1<<32)/TS ~= 0xFFFFFFFF / TS (To use ARM UDIV, that is 32 bits) (this is computed at the planner, to offload expensive calculations from the ISR)
|
||||
*
|
||||
* And for each point, evaluate the curve with the following sequence:
|
||||
*
|
||||
* void lsrs(uint32_t& d, uint32_t s, int cnt) {
|
||||
* void lsrs(uint64_t& d, uint64_t s, int cnt) {
|
||||
* d = s >> cnt;
|
||||
* }
|
||||
* void lsls(uint32_t& d, uint32_t s, int cnt) {
|
||||
* void lsls(uint64_t& d, uint64_t s, int cnt) {
|
||||
* d = s << cnt;
|
||||
* }
|
||||
* void lsrs(int32_t& d, uint32_t s, int cnt) {
|
||||
* d = uint32_t(s) >> cnt;
|
||||
* void lsrs(int32_t& d, uint64_t s, int cnt) {
|
||||
* d = uint64_t(s) >> cnt;
|
||||
* }
|
||||
* void lsls(int32_t& d, uint32_t s, int cnt) {
|
||||
* d = uint32_t(s) << cnt;
|
||||
* void lsls(int32_t& d, uint64_t s, int cnt) {
|
||||
* d = uint64_t(s) << cnt;
|
||||
* }
|
||||
* void umull(uint32_t& rlo, uint32_t& rhi, uint32_t op1, uint32_t op2) {
|
||||
* void umull(uint64_t& rlo, uint64_t& rhi, uint64_t op1, uint64_t op2) {
|
||||
* uint64_t res = uint64_t(op1) * op2;
|
||||
* rlo = uint32_t(res & 0xFFFFFFFF);
|
||||
* rhi = uint32_t((res >> 32) & 0xFFFFFFFF);
|
||||
* rlo = uint64_t(res & 0xFFFFFFFF);
|
||||
* rhi = uint64_t((res >> 32) & 0xFFFFFFFF);
|
||||
* }
|
||||
* void smlal(int32_t& rlo, int32_t& rhi, int32_t op1, int32_t op2) {
|
||||
* int64_t mul = int64_t(op1) * op2;
|
||||
* int64_t s = int64_t(uint32_t(rlo) | ((uint64_t(uint32_t(rhi)) << 32U)));
|
||||
* int64_t s = int64_t(uint64_t(rlo) | ((uint64_t(uint64_t(rhi)) << 32U)));
|
||||
* mul += s;
|
||||
* rlo = int32_t(mul & 0xFFFFFFFF);
|
||||
* rhi = int32_t((mul >> 32) & 0xFFFFFFFF);
|
||||
* }
|
||||
* int32_t _eval_bezier_curve_arm(uint32_t curr_step) {
|
||||
* uint32_t flo = 0;
|
||||
* uint32_t fhi = bezier_AV * curr_step;
|
||||
* uint32_t t = fhi;
|
||||
* int32_t _eval_bezier_curve_arm(uint64_t curr_step) {
|
||||
* uint64_t flo = 0;
|
||||
* uint64_t fhi = bezier_AV * curr_step;
|
||||
* uint64_t t = fhi;
|
||||
* int32_t alo = bezier_F;
|
||||
* int32_t ahi = 0;
|
||||
* int32_t A = bezier_A;
|
||||
@@ -849,7 +866,7 @@ void Stepper::apply_directions() {
|
||||
*
|
||||
* And for each curve, estimate its coefficients with:
|
||||
*
|
||||
* void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint32_t av) {
|
||||
* void _calc_bezier_curve_coeffs(int32_t v0, int32_t v1, uint64_t av) {
|
||||
* // Calculate the Bézier coefficients
|
||||
* if (v1 < v0) {
|
||||
* A_negative = true;
|
||||
@@ -874,14 +891,14 @@ void Stepper::apply_directions() {
|
||||
* }
|
||||
* // unsigned multiplication of 16 bits x 16bits, return upper 16 bits
|
||||
* void umul16x16to16hi(uint16_t& r, uint16_t op1, uint16_t op2) {
|
||||
* r = (uint32_t(op1) * op2) >> 16;
|
||||
* r = (uint64_t(op1) * op2) >> 16;
|
||||
* }
|
||||
* // unsigned multiplication of 16 bits x 24bits, return upper 24 bits
|
||||
* void umul16x24to24hi(uint24_t& r, uint16_t op1, uint24_t op2) {
|
||||
* r = uint24_t((uint64_t(op1) * op2) >> 16);
|
||||
* }
|
||||
*
|
||||
* int32_t _eval_bezier_curve(uint32_t curr_step) {
|
||||
* int32_t _eval_bezier_curve(uint64_t curr_step) {
|
||||
* // To save computing, the first step is always the initial speed
|
||||
* if (!curr_step)
|
||||
* return bezier_F;
|
||||
@@ -923,7 +940,7 @@ void Stepper::apply_directions() {
|
||||
#ifdef __AVR__
|
||||
|
||||
// For AVR we use assembly to maximize speed
|
||||
void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av) {
|
||||
void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) {
|
||||
|
||||
// Store advance
|
||||
bezier_AV = av;
|
||||
@@ -1025,7 +1042,7 @@ void Stepper::apply_directions() {
|
||||
);
|
||||
}
|
||||
|
||||
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) {
|
||||
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) {
|
||||
|
||||
// If dealing with the first step, save expensive computing and return the initial speed
|
||||
if (!curr_step)
|
||||
@@ -1407,28 +1424,36 @@ void Stepper::apply_directions() {
|
||||
:
|
||||
:"cc","r0","r1"
|
||||
);
|
||||
return (r2 | (uint16_t(r3) << 8)) | (uint32_t(r4) << 16);
|
||||
return (r2 | (uint16_t(r3) << 8)) | (uint64_t(r4) << 16);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// For all the other 32bit CPUs
|
||||
FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av) {
|
||||
FORCE_INLINE void Stepper::_calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av) {
|
||||
// Calculate the Bézier coefficients
|
||||
bezier_A = 768 * (v1 - v0);
|
||||
bezier_B = 1920 * (v0 - v1);
|
||||
bezier_C = 1280 * (v1 - v0);
|
||||
#ifndef S_CURVE_FACTOR
|
||||
bezier_A = 768 * (v1 - v0);
|
||||
bezier_B = 1920 * (v0 - v1);
|
||||
bezier_C = 1280 * (v1 - v0);
|
||||
#else
|
||||
// Must convert from S_CURVE_FACTOR to int only once.
|
||||
constexpr int FACTOR128 = S_CURVE_FACTOR * 128;
|
||||
bezier_A = (2 * (128 - FACTOR128)) * (v0 - v1);
|
||||
bezier_B = (3 * (128 - FACTOR128)) * (v1 - v0);
|
||||
bezier_C = FACTOR128 * (v1 - v0);
|
||||
#endif
|
||||
bezier_F = 128 * v0;
|
||||
bezier_AV = av;
|
||||
}
|
||||
|
||||
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint32_t curr_step) {
|
||||
FORCE_INLINE int32_t Stepper::_eval_bezier_curve(const uint64_t curr_step) {
|
||||
#if (defined(__arm__) || defined(__thumb__)) && __ARM_ARCH >= 6 && !defined(STM32G0B1xx) // TODO: Test define STM32G0xx versus STM32G0B1xx
|
||||
|
||||
// For ARM Cortex M3/M4 CPUs, we have the optimized assembler version, that takes 43 cycles to execute
|
||||
uint32_t flo = 0;
|
||||
uint32_t fhi = bezier_AV * curr_step;
|
||||
uint32_t t = fhi;
|
||||
uint64_t flo = 0;
|
||||
uint64_t fhi = bezier_AV * curr_step;
|
||||
uint64_t t = fhi;
|
||||
int32_t alo = bezier_F;
|
||||
int32_t ahi = 0;
|
||||
int32_t A = bezier_A;
|
||||
@@ -1439,8 +1464,10 @@ void Stepper::apply_directions() {
|
||||
".syntax unified" "\n\t" // is to prevent CM0,CM1 non-unified syntax
|
||||
A("lsrs %[ahi],%[alo],#1") // a = F << 31 1 cycles
|
||||
A("lsls %[alo],%[alo],#31") // 1 cycles
|
||||
A("umull %[flo],%[fhi],%[fhi],%[t]") // f *= t 5 cycles [fhi:flo=64bits]
|
||||
A("umull %[flo],%[fhi],%[fhi],%[t]") // f>>=32; f*=t 5 cycles [fhi:flo=64bits]
|
||||
#ifndef S_CURVE_FACTOR
|
||||
A("umull %[flo],%[fhi],%[fhi],%[t]") // f *= t 5 cycles [fhi:flo=64bits]
|
||||
A("umull %[flo],%[fhi],%[fhi],%[t]") // f>>=32; f*=t 5 cycles [fhi:flo=64bits]
|
||||
#endif
|
||||
A("lsrs %[flo],%[fhi],#1") // 1 cycles [31bits]
|
||||
A("smlal %[alo],%[ahi],%[flo],%[C]") // a+=(f>>33)*C; 5 cycles
|
||||
A("umull %[flo],%[fhi],%[fhi],%[t]") // f>>=32; f*=t 5 cycles [fhi:flo=64bits]
|
||||
@@ -1468,20 +1495,22 @@ void Stepper::apply_directions() {
|
||||
// For non ARM targets, we provide a fallback implementation. Really doubt it
|
||||
// will be useful, unless the processor is fast and 32bit
|
||||
|
||||
uint32_t t = bezier_AV * curr_step; // t: Range 0 - 1^32 = 32 bits
|
||||
uint64_t t = bezier_AV * curr_step; // t: Range 32 bits
|
||||
uint64_t f = t;
|
||||
f *= t; // Range 32*2 = 64 bits (unsigned)
|
||||
f >>= 32; // Range 32 bits (unsigned)
|
||||
f *= t; // Range 32*2 = 64 bits (unsigned)
|
||||
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
|
||||
#ifndef S_CURVE_FACTOR
|
||||
f *= t; // Range 32*2 = 64 bits (unsigned)
|
||||
f >>= 32; // Range 32 bits (unsigned)
|
||||
f *= t; // Range 32*2 = 64 bits (unsigned)
|
||||
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
|
||||
#endif
|
||||
int64_t acc = (int64_t) bezier_F << 31; // Range 63 bits (signed)
|
||||
acc += ((uint32_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign)
|
||||
acc += ((uint64_t) f >> 1) * (int64_t) bezier_C; // Range 29bits + 31 = 60bits (plus sign)
|
||||
f *= t; // Range 32*2 = 64 bits
|
||||
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
|
||||
acc += ((uint32_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign)
|
||||
acc += ((uint64_t) f >> 1) * (int64_t) bezier_B; // Range 29bits + 31 = 60bits (plus sign)
|
||||
f *= t; // Range 32*2 = 64 bits
|
||||
f >>= 32; // Range 32 bits : f = t^3 (unsigned)
|
||||
acc += ((uint32_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign)
|
||||
acc += ((uint64_t) f >> 1) * (int64_t) bezier_A; // Range 28bits + 31 = 59bits (plus sign)
|
||||
acc >>= (31 + 7); // Range 24bits (plus sign)
|
||||
return (int32_t) acc;
|
||||
|
||||
@@ -1496,7 +1525,14 @@ void Stepper::apply_directions() {
|
||||
* Directly pulses the stepper motors at high frequency.
|
||||
*/
|
||||
|
||||
HAL_STEP_TIMER_ISR() {
|
||||
|
||||
extern "C" [[gnu::section(".ramcode")]] void TIMER0_IRQHandler() {
|
||||
#ifndef __AVR__
|
||||
// Disable interrupts, to avoid ISR preemption while we reprogram the period
|
||||
// (AVR enters the ISR with global interrupts disabled, so no need to do it here)
|
||||
hal.isr_off();
|
||||
#endif
|
||||
|
||||
HAL_timer_isr_prologue(MF_TIMER_STEP);
|
||||
|
||||
Stepper::isr();
|
||||
@@ -1514,12 +1550,6 @@ void Stepper::isr() {
|
||||
|
||||
static hal_timer_t nextMainISR = 0; // Interval until the next main Stepper Pulse phase (0 = Now)
|
||||
|
||||
#ifndef __AVR__
|
||||
// Disable interrupts, to avoid ISR preemption while we reprogram the period
|
||||
// (AVR enters the ISR with global interrupts disabled, so no need to do it here)
|
||||
hal.isr_off();
|
||||
#endif
|
||||
|
||||
// Program timer compare for the maximum period, so it does NOT
|
||||
// flag an interrupt while this ISR is running - So changes from small
|
||||
// periods to big periods are respected and the timer does not reset to 0
|
||||
@@ -1540,8 +1570,6 @@ void Stepper::isr() {
|
||||
// We need this variable here to be able to use it in the following loop
|
||||
hal_timer_t min_ticks;
|
||||
do {
|
||||
// Enable ISRs to reduce USART processing latency
|
||||
hal.isr_on();
|
||||
|
||||
hal_timer_t interval = 0;
|
||||
|
||||
@@ -1562,6 +1590,9 @@ void Stepper::isr() {
|
||||
NOLESS(nextBabystepISR, nextMainISR / 2); // TODO: Only look at axes enabled for baby-stepping
|
||||
#endif
|
||||
|
||||
// Enable ISRs to reduce latency for higher priority ISRs, or all ISRs if no prioritization.
|
||||
hal.isr_on();
|
||||
|
||||
interval = nextMainISR; // Interval is either some old nextMainISR or FTM_MIN_TICKS
|
||||
TERN_(BABYSTEPPING, NOMORE(interval, nextBabystepISR)); // Come back early for Babystepping?
|
||||
|
||||
@@ -1590,6 +1621,9 @@ void Stepper::isr() {
|
||||
if (is_babystep) nextBabystepISR = babystepping_isr();
|
||||
#endif
|
||||
|
||||
// Enable ISRs to reduce latency for higher priority ISRs, or all ISRs if no prioritization.
|
||||
hal.isr_on();
|
||||
|
||||
// ^== Time critical. NOTHING besides pulse generation should be above here!!!
|
||||
|
||||
if (!nextMainISR) nextMainISR = block_phase_isr(); // Manage acc/deceleration, get next block
|
||||
@@ -1603,7 +1637,7 @@ void Stepper::isr() {
|
||||
#endif
|
||||
|
||||
// Get the interval to the next ISR call
|
||||
interval = _MIN(nextMainISR, uint32_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase
|
||||
interval = _MIN(nextMainISR, uint64_t(HAL_TIMER_TYPE_MAX)); // Time until the next Pulse / Block phase
|
||||
TERN_(INPUT_SHAPING_X, NOMORE(interval, ShapingQueue::peek_x())); // Time until next input shaping echo for X
|
||||
TERN_(INPUT_SHAPING_Y, NOMORE(interval, ShapingQueue::peek_y())); // Time until next input shaping echo for Y
|
||||
TERN_(INPUT_SHAPING_Z, NOMORE(interval, ShapingQueue::peek_z())); // Time until next input shaping echo for Z
|
||||
@@ -1723,7 +1757,7 @@ void Stepper::isr() {
|
||||
#if MINIMUM_STEPPER_PULSE || MAXIMUM_STEPPER_RATE
|
||||
#define ISR_PULSE_CONTROL 1
|
||||
#endif
|
||||
#if ISR_PULSE_CONTROL && DISABLED(I2S_STEPPER_STREAM)
|
||||
#if ISR_PULSE_CONTROL && MULTISTEPPING_LIMIT > 1 && DISABLED(I2S_STEPPER_STREAM)
|
||||
#define ISR_MULTI_STEPS 1
|
||||
#endif
|
||||
|
||||
@@ -1766,17 +1800,15 @@ void Stepper::pulse_phase_isr() {
|
||||
if (TERN0(FREEZE_FEATURE, frozen)) return;
|
||||
|
||||
// Count of pending loops and events for this iteration
|
||||
const uint32_t pending_events = step_event_count - step_events_completed;
|
||||
const uint64_t pending_events = step_event_count - step_events_completed;
|
||||
uint8_t events_to_do = _MIN(pending_events, steps_per_isr);
|
||||
|
||||
// Just update the value we will get at the end of the loop
|
||||
step_events_completed += events_to_do;
|
||||
|
||||
TERN_(ISR_PULSE_CONTROL, USING_TIMED_PULSE());
|
||||
// Take multiple steps per interrupt (For high speed moves)
|
||||
#if ISR_MULTI_STEPS
|
||||
bool firstStep = true;
|
||||
USING_TIMED_PULSE();
|
||||
#endif
|
||||
TERN_(ISR_MULTI_STEPS, bool firstStep = true);
|
||||
|
||||
// Direct Stepping page?
|
||||
const bool is_page = current_block->is_page();
|
||||
@@ -1965,7 +1997,7 @@ void Stepper::pulse_phase_isr() {
|
||||
|
||||
if (!is_page) {
|
||||
// Give the compiler a clue to store advance_divisor in registers for what follows
|
||||
const uint32_t advance_divisor_cached = advance_divisor;
|
||||
const uint64_t advance_divisor_cached = advance_divisor;
|
||||
|
||||
// Determine if pulses are needed
|
||||
#if HAS_X_STEP
|
||||
@@ -2081,7 +2113,7 @@ void Stepper::pulse_phase_isr() {
|
||||
TERN_(I2S_STEPPER_STREAM, i2s_push_sample());
|
||||
|
||||
// TODO: need to deal with MINIMUM_STEPPER_PULSE over i2s
|
||||
#if ISR_MULTI_STEPS
|
||||
#if ISR_PULSE_CONTROL
|
||||
START_TIMED_PULSE();
|
||||
AWAIT_HIGH_PULSE();
|
||||
#endif
|
||||
@@ -2196,24 +2228,24 @@ void Stepper::pulse_phase_isr() {
|
||||
#endif // HAS_ZV_SHAPING
|
||||
|
||||
// Calculate timer interval, with all limits applied.
|
||||
hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
|
||||
hal_timer_t Stepper::calc_timer_interval(uint64_t step_rate) {
|
||||
|
||||
constexpr uint64_t min_step_rate = MINIMAL_STEP_RATE;
|
||||
|
||||
#ifdef CPU_32_BIT
|
||||
|
||||
// A fast processor can just do integer division
|
||||
constexpr uint32_t min_step_rate = uint32_t(STEPPER_TIMER_RATE) / HAL_TIMER_TYPE_MAX;
|
||||
return step_rate > min_step_rate ? uint32_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX;
|
||||
return step_rate > min_step_rate ? uint64_t(STEPPER_TIMER_RATE) / step_rate : HAL_TIMER_TYPE_MAX;
|
||||
|
||||
#else
|
||||
|
||||
constexpr uint32_t min_step_rate = (F_CPU) / 500000U; // i.e., 32 or 40
|
||||
if (step_rate >= 0x0800) { // higher step rate
|
||||
// AVR is able to keep up at around 65kHz Stepping ISR rate at most.
|
||||
// So values for step_rate > 65535 might as well be truncated.
|
||||
// Handle it as quickly as possible. i.e., assume highest byte is zero
|
||||
// because non-zero would represent a step rate far beyond AVR capabilities.
|
||||
if (uint8_t(step_rate >> 16))
|
||||
return uint32_t(STEPPER_TIMER_RATE) / 0x10000;
|
||||
return uint64_t(STEPPER_TIMER_RATE) / 0x10000;
|
||||
|
||||
const uintptr_t table_address = uintptr_t(&speed_lookuptable_fast[uint8_t(step_rate >> 8)]);
|
||||
const uint16_t base = uint16_t(pgm_read_word(table_address));
|
||||
@@ -2233,8 +2265,8 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
|
||||
}
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
void Stepper::calc_nonlinear_e(uint32_t step_rate) {
|
||||
const uint32_t velocity = ne_scale * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
|
||||
void Stepper::calc_nonlinear_e(uint64_t step_rate) {
|
||||
const uint64_t velocity = ne_scale * step_rate; // Scale step_rate first so all intermediate values stay in range of 8.24 fixed point math
|
||||
int32_t vd = (((int64_t)ne_fix.A * velocity) >> 24) + (((((int64_t)ne_fix.B * velocity) >> 24) * velocity) >> 24);
|
||||
NOLESS(vd, 0);
|
||||
|
||||
@@ -2243,19 +2275,19 @@ hal_timer_t Stepper::calc_timer_interval(uint32_t step_rate) {
|
||||
#endif
|
||||
|
||||
// Get the timer interval and the number of loops to perform per tick
|
||||
hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) {
|
||||
hal_timer_t Stepper::calc_multistep_timer_interval(uint64_t step_rate) {
|
||||
|
||||
#if ENABLED(OLD_ADAPTIVE_MULTISTEPPING)
|
||||
|
||||
#if MULTISTEPPING_LIMIT == 1
|
||||
|
||||
// Just make sure the step rate is doable
|
||||
NOMORE(step_rate, uint32_t(MAX_STEP_ISR_FREQUENCY_1X));
|
||||
NOMORE(step_rate, uint64_t(MAX_STEP_ISR_FREQUENCY_1X));
|
||||
|
||||
#else
|
||||
|
||||
// The stepping frequency limits for each multistepping rate
|
||||
static const uint32_t limit[] PROGMEM = {
|
||||
static const uint64_t limit[] PROGMEM = {
|
||||
( MAX_STEP_ISR_FREQUENCY_1X )
|
||||
, (((F_CPU) / ISR_EXECUTION_CYCLES(1)) >> 1)
|
||||
#if MULTISTEPPING_LIMIT >= 4
|
||||
@@ -2280,7 +2312,7 @@ hal_timer_t Stepper::calc_multistep_timer_interval(uint32_t step_rate) {
|
||||
|
||||
// Find a doable step rate using multistepping
|
||||
uint8_t multistep = 1;
|
||||
for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint32_t(pgm_read_dword(&limit[i])); ++i) {
|
||||
for (uint8_t i = 0; i < COUNT(limit) && step_rate > uint64_t(pgm_read_dword(&limit[i])); ++i) {
|
||||
step_rate >>= 1;
|
||||
multistep <<= 1;
|
||||
}
|
||||
@@ -2439,7 +2471,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
// Get the next speed to use (Jerk limited!)
|
||||
uint32_t acc_step_rate = acceleration_time < current_block->acceleration_time
|
||||
uint64_t acc_step_rate = acceleration_time < current_block->acceleration_time
|
||||
? _eval_bezier_curve(acceleration_time)
|
||||
: current_block->cruise_rate;
|
||||
#else
|
||||
@@ -2460,7 +2492,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
if (la_active) {
|
||||
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
|
||||
const uint64_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
|
||||
la_interval = calc_timer_interval((acc_step_rate + la_step_rate) >> current_block->la_scaling);
|
||||
}
|
||||
#endif
|
||||
@@ -2490,7 +2522,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
}
|
||||
// Are we in Deceleration phase ?
|
||||
else if (step_events_completed >= decelerate_start) {
|
||||
uint32_t step_rate;
|
||||
uint64_t step_rate;
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
// If this is the 1st time we process the 2nd half of the trapezoid...
|
||||
@@ -2525,7 +2557,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
if (la_active) {
|
||||
const uint32_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
|
||||
const uint64_t la_step_rate = la_advance_steps > current_block->final_adv_steps ? current_block->la_advance_rate : 0;
|
||||
if (la_step_rate != step_rate) {
|
||||
const bool forward_e = la_step_rate < step_rate;
|
||||
la_interval = calc_timer_interval((forward_e ? step_rate - la_step_rate : la_step_rate - step_rate) >> current_block->la_scaling);
|
||||
@@ -2600,6 +2632,25 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
// The timer interval is just the nominal value for the nominal speed
|
||||
interval = ticks_nominal;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust Laser Power - Cruise
|
||||
* power - direct or floor adjusted active laser power.
|
||||
*/
|
||||
#if ENABLED(LASER_POWER_TRAP)
|
||||
if (cutter.cutter_mode == CUTTER_MODE_CONTINUOUS) {
|
||||
if (step_events_completed + 1 == accelerate_before) {
|
||||
if (planner.laser_inline.status.isPowered && planner.laser_inline.status.isEnabled) {
|
||||
if (current_block->laser.trap_ramp_entry_incr > 0) {
|
||||
current_block->laser.trap_ramp_active_pwr = current_block->laser.power;
|
||||
cutter.apply_power(current_block->laser.power);
|
||||
}
|
||||
}
|
||||
// Not a powered move.
|
||||
else cutter.apply_power(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if ENABLED(LASER_FEATURE)
|
||||
@@ -2691,8 +2742,85 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
}
|
||||
#endif
|
||||
|
||||
// Set flags for all moving axes, accounting for kinematics
|
||||
set_axis_moved_for_current_block();
|
||||
// Flag all moving axes for proper endstop handling
|
||||
|
||||
#if IS_CORE
|
||||
// Define conditions for checking endstops
|
||||
#define S_(N) current_block->steps[CORE_AXIS_##N]
|
||||
#define D_(N) current_block->direction_bits[CORE_AXIS_##N]
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_XZ
|
||||
/**
|
||||
* Head direction in -X axis for CoreXY and CoreXZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving.
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z, handled below)
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X)
|
||||
*/
|
||||
#if ANY(COREXY, COREXZ)
|
||||
#define X_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define X_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define X_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && X_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_XY)
|
||||
#define X_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define X_MOVE_TEST !!current_block->steps.a
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XY || CORE_IS_YZ
|
||||
/**
|
||||
* Head direction in -Y axis for CoreXY / CoreYZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y)
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Y or Z)
|
||||
*/
|
||||
#if ANY(COREYX, COREYZ)
|
||||
#define Y_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define Y_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Y_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Y_CMP(D_(1),D_(2))) )
|
||||
#elif ENABLED(MARKFORGED_YX)
|
||||
#define Y_MOVE_TEST (current_block->steps.a != current_block->steps.b)
|
||||
#else
|
||||
#define Y_MOVE_TEST !!current_block->steps.b
|
||||
#endif
|
||||
|
||||
#if CORE_IS_XZ || CORE_IS_YZ
|
||||
/**
|
||||
* Head direction in -Z axis for CoreXZ or CoreYZ bots.
|
||||
*
|
||||
* If steps differ, both axes are moving
|
||||
* If DeltaA == DeltaB, the movement is only in the 1st axis (X or Y, already handled above)
|
||||
* If DeltaA == -DeltaB, the movement is only in the 2nd axis (Z)
|
||||
*/
|
||||
#if ANY(COREZX, COREZY)
|
||||
#define Z_CMP(A,B) ((A)==(B))
|
||||
#else
|
||||
#define Z_CMP(A,B) ((A)!=(B))
|
||||
#endif
|
||||
#define Z_MOVE_TEST ( S_(1) != S_(2) || (S_(1) > 0 && Z_CMP(D_(1),D_(2))) )
|
||||
#else
|
||||
#define Z_MOVE_TEST !!current_block->steps.c
|
||||
#endif
|
||||
|
||||
AxisBits didmove;
|
||||
NUM_AXIS_CODE(
|
||||
if (X_MOVE_TEST) didmove.a = true,
|
||||
if (Y_MOVE_TEST) didmove.b = true,
|
||||
if (Z_MOVE_TEST) didmove.c = true,
|
||||
if (!!current_block->steps.i) didmove.i = true,
|
||||
if (!!current_block->steps.j) didmove.j = true,
|
||||
if (!!current_block->steps.k) didmove.k = true,
|
||||
if (!!current_block->steps.u) didmove.u = true,
|
||||
if (!!current_block->steps.v) didmove.v = true,
|
||||
if (!!current_block->steps.w) didmove.w = true
|
||||
);
|
||||
axis_did_move = didmove;
|
||||
|
||||
#if ENABLED(ADAPTIVE_STEP_SMOOTHING)
|
||||
// Nonlinear Extrusion needs at least 2x oversampling to permit increase of E step rate
|
||||
@@ -2701,7 +2829,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
|
||||
// Decide if axis smoothing is possible
|
||||
if (stepper.adaptive_step_smoothing_enabled) {
|
||||
uint32_t max_rate = current_block->nominal_rate; // Get the step event rate
|
||||
uint64_t max_rate = current_block->nominal_rate; // Get the step event rate
|
||||
while (max_rate < MIN_STEP_ISR_FREQUENCY) { // As long as more ISRs are possible...
|
||||
max_rate <<= 1; // Try to double the rate
|
||||
if (max_rate < MIN_STEP_ISR_FREQUENCY) // Don't exceed the estimated ISR limit
|
||||
@@ -2852,7 +2980,7 @@ hal_timer_t Stepper::block_phase_isr() {
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
if (la_active) {
|
||||
const uint32_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
|
||||
const uint64_t la_step_rate = la_advance_steps < current_block->max_adv_steps ? current_block->la_advance_rate : 0;
|
||||
la_interval = calc_timer_interval((current_block->initial_rate + la_step_rate) >> current_block->la_scaling);
|
||||
}
|
||||
#endif
|
||||
@@ -3272,7 +3400,7 @@ void Stepper::init() {
|
||||
const bool was_on = hal.isr_state();
|
||||
hal.isr_off();
|
||||
|
||||
const shaping_time_t delay = freq ? float(uint32_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1);
|
||||
const shaping_time_t delay = freq ? float(uint64_t(STEPPER_TIMER_RATE) / 2) / freq : shaping_time_t(-1);
|
||||
#define SHAPING_SET_FREQ_FOR_AXIS(AXISN, AXISL) \
|
||||
if (axis == AXISN) { \
|
||||
ShapingQueue::set_delay(AXISN, delay); \
|
||||
@@ -3757,7 +3885,7 @@ void Stepper::report_positions() {
|
||||
|
||||
#if EXTRA_CYCLES_BABYSTEP > 20
|
||||
#define _SAVE_START() const hal_timer_t pulse_start = HAL_timer_get_count(MF_TIMER_PULSE)
|
||||
#define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint32_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
#define _PULSE_WAIT() while (EXTRA_CYCLES_BABYSTEP > uint64_t(HAL_timer_get_count(MF_TIMER_PULSE) - pulse_start) * (PULSE_TIMER_PRESCALE)) { /* nada */ }
|
||||
#else
|
||||
#define _SAVE_START() NOOP
|
||||
#if EXTRA_CYCLES_BABYSTEP > 0
|
||||
|
||||
+19
-19
@@ -309,11 +309,11 @@ class Stepper {
|
||||
#endif
|
||||
#define MOTOR_CURRENT_COUNT 3
|
||||
#elif HAS_MOTOR_CURRENT_SPI
|
||||
static constexpr uint32_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
|
||||
static constexpr uint64_t digipot_count[] = DIGIPOT_MOTOR_CURRENT;
|
||||
#define MOTOR_CURRENT_COUNT COUNT(Stepper::digipot_count)
|
||||
#endif
|
||||
static bool initialized;
|
||||
static uint32_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
|
||||
static uint64_t motor_current_setting[MOTOR_CURRENT_COUNT]; // Initialized by settings.load()
|
||||
#endif
|
||||
|
||||
// Last-moved extruder, as set when the last movement was fetched from planner
|
||||
@@ -363,7 +363,7 @@ class Stepper {
|
||||
;
|
||||
#endif
|
||||
|
||||
static uint32_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
|
||||
static uint64_t acceleration_time, deceleration_time; // time measured in Stepper Timer ticks
|
||||
|
||||
#if MULTISTEPPING_LIMIT == 1
|
||||
static constexpr uint8_t steps_per_isr = 1; // Count of steps to perform per Stepper ISR call
|
||||
@@ -384,10 +384,10 @@ class Stepper {
|
||||
// Delta error variables for the Bresenham line tracer
|
||||
static xyze_long_t delta_error;
|
||||
static xyze_long_t advance_dividend;
|
||||
static uint32_t advance_divisor,
|
||||
static uint64_t advance_divisor,
|
||||
step_events_completed, // The number of step events executed in the current block
|
||||
accelerate_before, // The count at which to start cruising
|
||||
decelerate_start, // The count at which to start decelerating
|
||||
accelerate_before, // The point from where we need to stop acceleration
|
||||
decelerate_start, // The point from where we need to start decelerating
|
||||
step_event_count; // The total event count for the current block
|
||||
|
||||
#if ANY(HAS_MULTI_EXTRUDER, MIXING_EXTRUDER)
|
||||
@@ -400,7 +400,7 @@ class Stepper {
|
||||
static int32_t bezier_A, // A coefficient in Bézier speed curve
|
||||
bezier_B, // B coefficient in Bézier speed curve
|
||||
bezier_C; // C coefficient in Bézier speed curve
|
||||
static uint32_t bezier_F, // F coefficient in Bézier speed curve
|
||||
static uint64_t bezier_F, // F/free coefficient in Bézier speed curve
|
||||
bezier_AV; // AV coefficient in Bézier speed curve
|
||||
#ifdef __AVR__
|
||||
static bool A_negative; // If A coefficient was negative
|
||||
@@ -432,7 +432,7 @@ class Stepper {
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
static int32_t ne_edividend;
|
||||
static uint32_t ne_scale;
|
||||
static uint64_t ne_scale;
|
||||
static ne_fix_t ne_fix;
|
||||
#endif
|
||||
|
||||
@@ -447,7 +447,7 @@ class Stepper {
|
||||
|
||||
static hal_timer_t ticks_nominal;
|
||||
#if DISABLED(S_CURVE_ACCELERATION)
|
||||
static uint32_t acc_step_rate; // needed for deceleration start point
|
||||
static uint64_t acc_step_rate; // needed for deceleration start point
|
||||
#endif
|
||||
|
||||
// Exact steps at which an endstop was triggered
|
||||
@@ -478,21 +478,21 @@ class Stepper {
|
||||
}
|
||||
|
||||
// The ISR scheduler
|
||||
static void isr();
|
||||
FORCE_INLINE static void isr();
|
||||
|
||||
// The stepper pulse ISR phase
|
||||
static void pulse_phase_isr();
|
||||
FORCE_INLINE static void pulse_phase_isr();
|
||||
|
||||
// The stepper block processing ISR phase
|
||||
static hal_timer_t block_phase_isr();
|
||||
FORCE_INLINE static hal_timer_t block_phase_isr();
|
||||
|
||||
#if HAS_ZV_SHAPING
|
||||
static void shaping_isr();
|
||||
FORCE_INLINE static void shaping_isr();
|
||||
#endif
|
||||
|
||||
#if ENABLED(LIN_ADVANCE)
|
||||
// The Linear advance ISR phase
|
||||
static void advance_isr();
|
||||
FORCE_INLINE static void advance_isr();
|
||||
#endif
|
||||
|
||||
#if ENABLED(BABYSTEPPING)
|
||||
@@ -677,21 +677,21 @@ class Stepper {
|
||||
static void _set_position(const abce_long_t &spos);
|
||||
|
||||
// Calculate the timing interval for the given step rate
|
||||
static hal_timer_t calc_timer_interval(uint32_t step_rate);
|
||||
static hal_timer_t calc_timer_interval(uint64_t step_rate);
|
||||
|
||||
// Calculate timing interval and steps-per-ISR for the given step rate
|
||||
static hal_timer_t calc_multistep_timer_interval(uint32_t step_rate);
|
||||
static hal_timer_t calc_multistep_timer_interval(uint64_t step_rate);
|
||||
|
||||
// Evaluate axis motions and set bits in axis_did_move
|
||||
static void set_axis_moved_for_current_block();
|
||||
|
||||
#if ENABLED(NONLINEAR_EXTRUSION)
|
||||
static void calc_nonlinear_e(uint32_t step_rate);
|
||||
static void calc_nonlinear_e(uint64_t step_rate);
|
||||
#endif
|
||||
|
||||
#if ENABLED(S_CURVE_ACCELERATION)
|
||||
static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint32_t av);
|
||||
static int32_t _eval_bezier_curve(const uint32_t curr_step);
|
||||
static void _calc_bezier_curve_coeffs(const int32_t v0, const int32_t v1, const uint64_t av);
|
||||
static int32_t _eval_bezier_curve(const uint64_t curr_step);
|
||||
#endif
|
||||
|
||||
#if HAS_MOTOR_CURRENT_SPI || HAS_MOTOR_CURRENT_PWM
|
||||
|
||||
@@ -0,0 +1,604 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#ifndef BOARD_INFO_NAME
|
||||
#define BOARD_INFO_NAME "Extra Big Ass Board"
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_MACHINE_NAME
|
||||
#define DEFAULT_MACHINE_NAME "XtraBigAssBoard"
|
||||
#endif
|
||||
|
||||
#define LED_PIN P3_18 // PWM0_3
|
||||
|
||||
// EXTRA PINS
|
||||
#define FIL_RUNOUT_PIN P1_12
|
||||
|
||||
// DRIVERS EXTRA PINS
|
||||
#define DRIVERS_SCK P1_20
|
||||
#define DRIVERS_MISO P1_23
|
||||
#define DRIVERS_MOSI P1_24
|
||||
|
||||
|
||||
//
|
||||
// Servos
|
||||
//
|
||||
#define SERVO0_PIN P2_05 // PWM1_6
|
||||
#define SERVO1_PIN P2_04 // PWM1_5
|
||||
#define SERVO2_PIN P2_03 // PWM1_4
|
||||
#define SERVO3_PIN P2_02 // PWM1_3
|
||||
|
||||
|
||||
//
|
||||
// Limit Switches
|
||||
//
|
||||
#define X_MIN_PIN P0_19
|
||||
#define X_MAX_PIN P0_18
|
||||
#define Y_MIN_PIN P0_20
|
||||
#define Y_MAX_PIN P0_17
|
||||
#define Z_MIN_PIN P0_21
|
||||
#define Z_MAX_PIN P0_15
|
||||
|
||||
//
|
||||
// Z Probe (when not Z_MIN_PIN)
|
||||
//
|
||||
#ifndef Z_MIN_PROBE_PIN
|
||||
#define Z_MIN_PROBE_PIN P0_21
|
||||
#endif
|
||||
|
||||
//
|
||||
// Steppers
|
||||
//
|
||||
#define X_STEP_PIN P0_10
|
||||
#define X_DIR_PIN P4_03
|
||||
#define X_ENABLE_PIN P0_01
|
||||
#define X_CS_PIN P0_00
|
||||
#define X_DIAG_PIN P2_17
|
||||
|
||||
#define Y_STEP_PIN P1_29
|
||||
#define Y_DIR_PIN P2_14
|
||||
#define Y_ENABLE_PIN P1_28
|
||||
#define Y_CS_PIN P2_22
|
||||
#define Y_DIAG_PIN P2_16
|
||||
|
||||
#define Z_STEP_PIN P4_02
|
||||
#define Z_DIR_PIN P1_26
|
||||
#define Z_ENABLE_PIN P1_25
|
||||
#define Z_CS_PIN P4_01
|
||||
#define Z_DIAG_PIN P2_21
|
||||
|
||||
#define E0_STEP_PIN P1_19
|
||||
#define E0_DIR_PIN P0_14
|
||||
#define E0_ENABLE_PIN P1_22
|
||||
#define E0_CS_PIN P4_00
|
||||
#define E0_DIAG_PIN P2_20
|
||||
|
||||
#define E1_STEP_PIN P2_23
|
||||
#define E1_DIR_PIN P2_18
|
||||
#define E1_ENABLE_PIN P3_23
|
||||
#define E1_CS_PIN P1_18
|
||||
#define E1_DIAG_PIN P2_19
|
||||
|
||||
#define E2_STEP_PIN P3_26
|
||||
#define E2_DIR_PIN P2_25
|
||||
#define E2_ENABLE_PIN P3_25
|
||||
#define E2_CS_PIN P3_24
|
||||
#define E2_DIAG_PIN P2_26
|
||||
|
||||
#define E3_STEP_PIN P4_19
|
||||
#define E3_DIR_PIN P4_20
|
||||
#define E3_ENABLE_PIN P4_26
|
||||
#define E3_CS_PIN P4_21
|
||||
#define E3_DIAG_PIN P0_22
|
||||
|
||||
#define E4_STEP_PIN P4_17
|
||||
#define E4_DIR_PIN P4_18
|
||||
#define E4_ENABLE_PIN P4_05
|
||||
#define E4_CS_PIN P2_12
|
||||
#define E4_DIAG_PIN P2_11
|
||||
|
||||
#define E5_STEP_PIN P0_11
|
||||
#define E5_DIR_PIN P2_15
|
||||
#define E5_ENABLE_PIN P4_04
|
||||
#define E5_CS_PIN P4_16
|
||||
#define E5_DIAG_PIN P2_13
|
||||
|
||||
#define E6_STEP_PIN P2_28
|
||||
#define E6_DIR_PIN P0_28
|
||||
#define E6_ENABLE_PIN P0_31
|
||||
#define E6_CS_PIN P0_27
|
||||
#define E6_DIAG_PIN P2_24
|
||||
|
||||
#define E7_STEP_PIN P1_30
|
||||
#define E7_DIR_PIN P0_12
|
||||
#define E7_ENABLE_PIN P0_13
|
||||
#define E7_CS_PIN P2_29
|
||||
#define E7_DIAG_PIN P2_27
|
||||
|
||||
#define E8_STEP_PIN P3_15
|
||||
#define E8_DIR_PIN P3_07
|
||||
#define E8_ENABLE_PIN P2_30
|
||||
#define E8_CS_PIN P5_01
|
||||
#define E8_DIAG_PIN P2_31
|
||||
|
||||
|
||||
#if HAS_TMC_UART
|
||||
#define X_SERIAL_TX_PIN P0_00
|
||||
#define X_SERIAL_RX_PIN P0_00
|
||||
#define Y_SERIAL_TX_PIN P2_22
|
||||
#define Y_SERIAL_RX_PIN P2_22
|
||||
#define Z_SERIAL_TX_PIN P4_01
|
||||
#define Z_SERIAL_RX_PIN P4_01
|
||||
#define E0_SERIAL_TX_PIN P4_00
|
||||
#define E0_SERIAL_RX_PIN P4_00
|
||||
#define E1_SERIAL_TX_PIN P1_18
|
||||
#define E1_SERIAL_RX_PIN P1_18
|
||||
#define E2_SERIAL_TX_PIN P3_24
|
||||
#define E2_SERIAL_RX_PIN P3_24
|
||||
#define E3_SERIAL_TX_PIN P4_21
|
||||
#define E3_SERIAL_RX_PIN P4_21
|
||||
#define E4_SERIAL_TX_PIN P2_12
|
||||
#define E4_SERIAL_RX_PIN P2_12
|
||||
#define E5_SERIAL_TX_PIN P4_16
|
||||
#define E5_SERIAL_RX_PIN P4_16
|
||||
#define E6_SERIAL_TX_PIN P0_27
|
||||
#define E6_SERIAL_RX_PIN P0_27
|
||||
#define E7_SERIAL_TX_PIN P2_29
|
||||
#define E7_SERIAL_RX_PIN P2_29
|
||||
#define E8_SERIAL_TX_PIN P5_01
|
||||
#define E8_SERIAL_RX_PIN P5_01
|
||||
|
||||
// Reduce baud rate to improve software serial reliability
|
||||
#define TMC_BAUD_RATE 19200
|
||||
#endif // HAS_TMC_UART
|
||||
|
||||
//
|
||||
// Temperature Sensors
|
||||
//
|
||||
#define TEMP_0_PIN P0_23
|
||||
#define TEMP_1_PIN P0_24
|
||||
#define TEMP_2_PIN P0_25
|
||||
#define TEMP_3_PIN P0_26
|
||||
#define TEMP_BED_PIN P1_31
|
||||
|
||||
//
|
||||
// Heaters / Fans
|
||||
//
|
||||
|
||||
#define HEATER_0_PIN P1_02
|
||||
#define HEATER_1_PIN P1_10
|
||||
#define HEATER_2_PIN P4_30
|
||||
#define HEATER_3_PIN P1_09
|
||||
#define HEATER_BED_PIN P4_23
|
||||
|
||||
#define FAN0_PIN P3_08
|
||||
#define FAN1_PIN P3_00
|
||||
#define FAN2_PIN P3_27 //PWM1_4
|
||||
#define FAN3_PIN P5_04
|
||||
|
||||
#define EFAN0_PIN P1_08
|
||||
#define EFAN1_PIN P4_31
|
||||
#define EFAN2_PIN P3_01
|
||||
#define EFAN3_PIN P3_10
|
||||
//
|
||||
// Misc. Functions
|
||||
//
|
||||
#if SD_CONNECTION_IS(LCD)
|
||||
#define SD_DETECT_PIN P3_02
|
||||
#define SD_SCK_PIN P1_00
|
||||
#define SD_MISO_PIN P1_04
|
||||
#define SD_MOSI_PIN P1_01
|
||||
#define SD_SS_PIN P3_03
|
||||
#define SDSS SD_SS_PIN
|
||||
#elif SD_CONNECTION_IS(ONBOARD)
|
||||
#define SD_DETECT_PIN P_NC
|
||||
#define SD_SCK_PIN P0_07
|
||||
#define SD_MISO_PIN P0_08
|
||||
#define SD_MOSI_PIN P0_09
|
||||
#define ONBOARD_SD_CS_PIN P0_06
|
||||
#define SD_SS_PIN ONBOARD_SD_CS_PIN
|
||||
#define SDSS SD_SS_PIN
|
||||
#endif
|
||||
|
||||
#ifndef NEOPIXEL_PIN
|
||||
#define NEOPIXEL_PIN P_NC
|
||||
#endif
|
||||
|
||||
#ifndef FILWIDTH_PIN
|
||||
#define FILWIDTH_PIN P_NC
|
||||
#endif
|
||||
|
||||
#ifndef FIL_RUNOUT_PIN
|
||||
#define FIL_RUNOUT_PIN P_NC
|
||||
#endif
|
||||
|
||||
#ifndef PS_ON_PIN
|
||||
//#define PS_ON_PIN P_NC
|
||||
#endif
|
||||
|
||||
//
|
||||
// Průša i3 MK2 Multiplexer Support
|
||||
//
|
||||
#if HAS_PRUSA_MMU1
|
||||
#ifndef E_MUX0_PIN
|
||||
#define E_MUX0_PIN P_NC
|
||||
#endif
|
||||
#ifndef E_MUX1_PIN
|
||||
#define E_MUX1_PIN P_NC
|
||||
#endif
|
||||
#ifndef E_MUX2_PIN
|
||||
#define E_MUX2_PIN P_NC
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Default pins for TMC software SPI
|
||||
*/
|
||||
#if ENABLED(TMC_USE_SW_SPI)
|
||||
#ifndef TMC_SPI_MOSI
|
||||
#define TMC_SPI_MOSI P1_24
|
||||
#endif
|
||||
#ifndef TMC_SPI_MISO
|
||||
#define TMC_SPI_MISO P1_23
|
||||
#endif
|
||||
#ifndef TMC_SPI_SCK
|
||||
#define TMC_SPI_SCK P1_20
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// LCDs and Controllers //
|
||||
//////////////////////////
|
||||
|
||||
#if ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI)
|
||||
|
||||
#define TFT_A0_PIN 43
|
||||
#define TFT_CS_PIN 49
|
||||
#define TFT_DC_PIN 43
|
||||
#define TFT_SCK_PIN SD_SCK_PIN
|
||||
#define TFT_MOSI_PIN SD_MOSI_PIN
|
||||
#define TFT_MISO_PIN SD_MISO_PIN
|
||||
#define LCD_USE_DMA_SPI
|
||||
|
||||
#define BTN_EN1 40
|
||||
#define BTN_EN2 63
|
||||
#define BTN_ENC 59
|
||||
#define BEEPER_PIN 42
|
||||
|
||||
#define TOUCH_CS_PIN 33
|
||||
|
||||
#define SD_DETECT_PIN 41
|
||||
|
||||
#define SPI_FLASH
|
||||
#if ENABLED(SPI_FLASH)
|
||||
#define SPI_DEVICE 1
|
||||
#define SPI_FLASH_SIZE 0x1000000 // 16MB
|
||||
#define SPI_FLASH_CS_PIN 31
|
||||
#define SPI_FLASH_MOSI_PIN SD_MOSI_PIN
|
||||
#define SPI_FLASH_MISO_PIN SD_MISO_PIN
|
||||
#define SPI_FLASH_SCK_PIN SD_SCK_PIN
|
||||
#endif
|
||||
|
||||
#define TFT_BUFFER_SIZE 0xFFFF
|
||||
#ifndef TFT_DRIVER
|
||||
#define TFT_DRIVER ST7796
|
||||
#endif
|
||||
#ifndef TOUCH_SCREEN_CALIBRATION
|
||||
#if ENABLED(TFT_RES_320x240)
|
||||
#ifndef TOUCH_CALIBRATION_X
|
||||
#define TOUCH_CALIBRATION_X 20525
|
||||
#endif
|
||||
#ifndef TOUCH_CALIBRATION_Y
|
||||
#define TOUCH_CALIBRATION_Y 15335
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_X
|
||||
#define TOUCH_OFFSET_X -1
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_Y
|
||||
#define TOUCH_OFFSET_Y 0
|
||||
#endif
|
||||
#elif ENABLED(TFT_RES_480x272)
|
||||
#ifndef TOUCH_CALIBRATION_X
|
||||
#define TOUCH_CALIBRATION_X 30715
|
||||
#endif
|
||||
#ifndef TOUCH_CALIBRATION_Y
|
||||
#define TOUCH_CALIBRATION_Y 17415
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_X
|
||||
#define TOUCH_OFFSET_X 0
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_Y
|
||||
#define TOUCH_OFFSET_Y -1
|
||||
#endif
|
||||
#elif ENABLED(TFT_RES_480x320)
|
||||
#ifndef TOUCH_CALIBRATION_X
|
||||
#define TOUCH_CALIBRATION_X 30595
|
||||
#endif
|
||||
#ifndef TOUCH_CALIBRATION_Y
|
||||
#define TOUCH_CALIBRATION_Y 20415
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_X
|
||||
#define TOUCH_OFFSET_X 2
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_Y
|
||||
#define TOUCH_OFFSET_Y 1
|
||||
#endif
|
||||
#elif ENABLED(TFT_RES_1024x600)
|
||||
#ifndef TOUCH_CALIBRATION_X
|
||||
#define TOUCH_CALIBRATION_X 65533
|
||||
#endif
|
||||
#ifndef TOUCH_CALIBRATION_Y
|
||||
#define TOUCH_CALIBRATION_Y 38399
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_X
|
||||
#define TOUCH_OFFSET_X 2
|
||||
#endif
|
||||
#ifndef TOUCH_OFFSET_Y
|
||||
#define TOUCH_OFFSET_Y 1
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BTN_BACK 70
|
||||
|
||||
#elif HAS_WIRED_LCD
|
||||
|
||||
//
|
||||
// LCD Display output pins
|
||||
//
|
||||
#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
|
||||
|
||||
#define LCD_PINS_RS P3_06 // CS chip select /SS chip slave select
|
||||
#define LCD_PINS_EN P3_14 // SID (MOSI)
|
||||
#define LCD_PINS_D4 P3_30 // SCK (CLK) clock
|
||||
|
||||
#elif ALL(IS_NEWPANEL, PANEL_ONE)
|
||||
|
||||
#define LCD_PINS_RS 40
|
||||
#define LCD_PINS_EN 42
|
||||
#define LCD_PINS_D4 65
|
||||
#define LCD_PINS_D5 66
|
||||
#define LCD_PINS_D6 44
|
||||
#define LCD_PINS_D7 64
|
||||
|
||||
#else
|
||||
|
||||
#if ENABLED(CR10_STOCKDISPLAY)
|
||||
|
||||
#define LCD_PINS_RS 27
|
||||
#define LCD_PINS_EN 29
|
||||
#define LCD_PINS_D4 25
|
||||
|
||||
#if !IS_NEWPANEL
|
||||
#define BEEPER_PIN 37
|
||||
#endif
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
|
||||
#define LCD_PINS_RS 64
|
||||
#define LCD_PINS_EN 44
|
||||
#define LCD_PINS_D4 63
|
||||
#define LCD_PINS_D5 40
|
||||
#define LCD_PINS_D6 42
|
||||
#define LCD_PINS_D7 65
|
||||
|
||||
#else
|
||||
|
||||
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306)
|
||||
#define LCD_PINS_DC 25 // Set as output on init
|
||||
#define LCD_PINS_RS 27 // Pull low for 1s to init
|
||||
// DOGM SPI LCD Support
|
||||
#define DOGLCD_CS 16
|
||||
#define DOGLCD_MOSI 17
|
||||
#define DOGLCD_SCK 23
|
||||
#define DOGLCD_A0 LCD_PINS_DC
|
||||
#else
|
||||
#define LCD_PINS_RS P3_06
|
||||
#define LCD_PINS_EN P3_14
|
||||
#define LCD_PINS_D4 P3_30
|
||||
#define LCD_PINS_D5 P3_05
|
||||
#define LCD_PINS_D6 P3_29
|
||||
#endif
|
||||
|
||||
#define LCD_PINS_D7 P5_00
|
||||
|
||||
#if !IS_NEWPANEL
|
||||
#define BEEPER_PIN 33
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !IS_NEWPANEL
|
||||
// Buttons attached to a shift register
|
||||
// Not wired yet
|
||||
//#define SHIFT_CLK_PIN 38
|
||||
//#define SHIFT_LD_PIN 42
|
||||
//#define SHIFT_OUT_PIN 40
|
||||
//#define SHIFT_EN_PIN 17
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// LCD Display input pins
|
||||
//
|
||||
#if IS_NEWPANEL
|
||||
|
||||
#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
|
||||
|
||||
#define BEEPER_PIN P3_31
|
||||
|
||||
#if ENABLED(CR10_STOCKDISPLAY)
|
||||
#define BTN_EN1 17
|
||||
#define BTN_EN2 23
|
||||
#else
|
||||
#define BTN_EN1 P3_11
|
||||
#define BTN_EN2 P3_12
|
||||
#endif
|
||||
|
||||
#define BTN_ENC P3_28
|
||||
#define SD_DETECT_PIN P3_02
|
||||
//#define KILL_PIN P_NC
|
||||
|
||||
#if ENABLED(BQ_LCD_SMART_CONTROLLER)
|
||||
#define LCD_BACKLIGHT_PIN 39
|
||||
#endif
|
||||
|
||||
#elif ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
|
||||
|
||||
#define BTN_EN1 64
|
||||
#define BTN_EN2 59
|
||||
#define BTN_ENC 63
|
||||
#define SD_DETECT_PIN 42
|
||||
|
||||
#elif ENABLED(LCD_I2C_PANELOLU2)
|
||||
|
||||
#define BTN_EN1 47
|
||||
#define BTN_EN2 43
|
||||
#define BTN_ENC 32
|
||||
#define LCD_SDSS SDSS
|
||||
#define KILL_PIN 41
|
||||
|
||||
#elif ENABLED(LCD_I2C_VIKI)
|
||||
|
||||
#define BTN_EN1 22 // https://files.panucatt.com/datasheets/viki_wiring_diagram.pdf explains 40/42.
|
||||
#define BTN_EN2 7 // 22/7 are unused on RAMPS_14. 22 is unused and 7 the SERVO0_PIN on RAMPS_13.
|
||||
#define BTN_ENC -1
|
||||
|
||||
#define LCD_SDSS SDSS
|
||||
#define SD_DETECT_PIN 49
|
||||
|
||||
#elif ANY(VIKI2, miniVIKI)
|
||||
|
||||
#define DOGLCD_CS 45
|
||||
#define DOGLCD_A0 44
|
||||
|
||||
#define BEEPER_PIN 33
|
||||
#define STAT_LED_RED_PIN 32
|
||||
#define STAT_LED_BLUE_PIN 35
|
||||
|
||||
#define BTN_EN1 22
|
||||
#define BTN_EN2 7
|
||||
#define BTN_ENC 39
|
||||
|
||||
#define SD_DETECT_PIN -1 // Pin 49 for display sd interface, 72 for easy adapter board
|
||||
#define KILL_PIN 31
|
||||
|
||||
#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
|
||||
|
||||
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
|
||||
|
||||
#define DOGLCD_CS 29
|
||||
#define DOGLCD_A0 27
|
||||
|
||||
#define BEEPER_PIN 23
|
||||
#define LCD_BACKLIGHT_PIN 33
|
||||
|
||||
#define BTN_EN1 35
|
||||
#define BTN_EN2 37
|
||||
#define BTN_ENC 31
|
||||
|
||||
#define LCD_SDSS SDSS
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 41
|
||||
|
||||
#elif ENABLED(MKS_MINI_12864)
|
||||
|
||||
#define DOGLCD_A0 27
|
||||
#define DOGLCD_CS 25
|
||||
|
||||
#define BEEPER_PIN 37
|
||||
// not connected to a pin
|
||||
#define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65
|
||||
|
||||
#define BTN_EN1 31
|
||||
#define BTN_EN2 33
|
||||
#define BTN_ENC 35
|
||||
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 64
|
||||
|
||||
//#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
|
||||
|
||||
#elif ENABLED(MINIPANEL)
|
||||
|
||||
#define BEEPER_PIN 42
|
||||
// not connected to a pin
|
||||
#define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65
|
||||
|
||||
#define DOGLCD_A0 44
|
||||
#define DOGLCD_CS 66
|
||||
|
||||
#define BTN_EN1 40
|
||||
#define BTN_EN2 63
|
||||
#define BTN_ENC 59
|
||||
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 64
|
||||
|
||||
//#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
|
||||
#define ADC_KEYPAD_PIN 12
|
||||
|
||||
#elif ENABLED(AZSMZ_12864)
|
||||
|
||||
// Pins only defined for RAMPS_SMART currently
|
||||
|
||||
#else
|
||||
|
||||
// Beeper on AUX-4
|
||||
#define BEEPER_PIN P3_31
|
||||
|
||||
// Buttons are directly attached to AUX-2
|
||||
#if IS_RRW_KEYPAD
|
||||
#define SHIFT_OUT_PIN 40
|
||||
#define SHIFT_CLK_PIN 44
|
||||
#define SHIFT_LD_PIN 42
|
||||
#define BTN_EN1 64
|
||||
#define BTN_EN2 59
|
||||
#define BTN_ENC 63
|
||||
#elif ENABLED(PANEL_ONE)
|
||||
#define BTN_EN1 59 // AUX2 PIN 3
|
||||
#define BTN_EN2 63 // AUX2 PIN 4
|
||||
#define BTN_ENC 49 // AUX3 PIN 7
|
||||
#else
|
||||
#define BTN_EN1 P3_11
|
||||
#define BTN_EN2 P3_12
|
||||
#define BTN_ENC P3_28
|
||||
#endif
|
||||
|
||||
#if ENABLED(G3D_PANEL)
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 41
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// CUSTOM SIMULATOR INPUTS
|
||||
#define BTN_BACK 70
|
||||
|
||||
#endif // IS_NEWPANEL
|
||||
|
||||
#endif // HAS_WIRED_LCD
|
||||
@@ -22,11 +22,31 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Native with a RAMPS like board with additional pins
|
||||
* Arduino Mega with RAMPS v1.4 (or v1.3) pin assignments
|
||||
*
|
||||
* Applies to the following boards:
|
||||
*
|
||||
* RAMPS_14_EFB (Hotend, Fan, Bed)
|
||||
* RAMPS_14_EEB (Hotend0, Hotend1, Bed)
|
||||
* RAMPS_14_EFF (Hotend, Fan0, Fan1)
|
||||
* RAMPS_14_EEF (Hotend0, Hotend1, Fan)
|
||||
* RAMPS_14_SF (Spindle, Controller Fan)
|
||||
*
|
||||
* RAMPS_13_EFB (Hotend, Fan, Bed)
|
||||
* RAMPS_13_EEB (Hotend0, Hotend1, Bed)
|
||||
* RAMPS_13_EFF (Hotend, Fan0, Fan1)
|
||||
* RAMPS_13_EEF (Hotend0, Hotend1, Fan)
|
||||
* RAMPS_13_SF (Spindle, Controller Fan)
|
||||
*
|
||||
* Other pins_MYBOARD.h files may override these defaults
|
||||
*
|
||||
* Differences between
|
||||
* RAMPS_13 | RAMPS_14
|
||||
* 7 | 11
|
||||
*/
|
||||
|
||||
#ifndef BOARD_INFO_NAME
|
||||
#define BOARD_INFO_NAME "RAMPS Native"
|
||||
#define BOARD_INFO_NAME "RAMPS 1.4"
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_MACHINE_NAME
|
||||
@@ -40,24 +60,28 @@
|
||||
//
|
||||
// Servos
|
||||
//
|
||||
#define SERVO0_PIN 151
|
||||
#define SERVO1_PIN 152
|
||||
#define SERVO2_PIN 153
|
||||
#ifdef IS_RAMPS_13
|
||||
#define SERVO0_PIN 7 // RAMPS_13 // Will conflict with BTN_EN2 on LCD_I2C_VIKI
|
||||
#else
|
||||
#define SERVO0_PIN 11
|
||||
#endif
|
||||
#define SERVO1_PIN 6
|
||||
#define SERVO2_PIN 5
|
||||
#ifndef SERVO3_PIN
|
||||
#define SERVO3_PIN 154
|
||||
#define SERVO3_PIN 4
|
||||
#endif
|
||||
|
||||
//
|
||||
// Limit Switches
|
||||
//
|
||||
#define X_MIN_PIN 155
|
||||
#define X_MIN_PIN 3
|
||||
#ifndef X_MAX_PIN
|
||||
#define X_MAX_PIN 156
|
||||
#define X_MAX_PIN 2
|
||||
#endif
|
||||
#define Y_MIN_PIN 157
|
||||
#define Y_MAX_PIN 158
|
||||
#define Z_MIN_PIN 159
|
||||
#define Z_MAX_PIN 160
|
||||
#define Y_MIN_PIN 14
|
||||
#define Y_MAX_PIN 15
|
||||
#define Z_MIN_PIN 18
|
||||
#define Z_MAX_PIN 19
|
||||
|
||||
//
|
||||
// Z Probe (when not Z_MIN_PIN)
|
||||
@@ -104,60 +128,24 @@
|
||||
#define E1_CS_PIN 44
|
||||
#endif
|
||||
|
||||
#define E2_STEP_PIN 100
|
||||
#define E2_DIR_PIN 101
|
||||
#define E2_ENABLE_PIN 102
|
||||
#ifndef E2_CS_PIN
|
||||
#define E2_CS_PIN 103
|
||||
#endif
|
||||
#define Z4_STEP_PIN 13
|
||||
#define Z4_DIR_PIN 71
|
||||
#define Z4_ENABLE_PIN 12
|
||||
|
||||
#define E3_STEP_PIN 104
|
||||
#define E3_DIR_PIN 105
|
||||
#define E3_ENABLE_PIN 106
|
||||
#ifndef E3_CS_PIN
|
||||
#define E3_CS_PIN 107
|
||||
#endif
|
||||
#define Z2_STEP_PIN 4
|
||||
#define Z2_DIR_PIN 5
|
||||
#define Z2_ENABLE_PIN 6
|
||||
|
||||
#define E4_STEP_PIN 108
|
||||
#define E4_DIR_PIN 109
|
||||
#define E4_ENABLE_PIN 110
|
||||
#ifndef E4_CS_PIN
|
||||
#define E4_CS_PIN 111
|
||||
#endif
|
||||
|
||||
#define E5_STEP_PIN 112
|
||||
#define E5_DIR_PIN 113
|
||||
#define E5_ENABLE_PIN 114
|
||||
#ifndef E5_CS_PIN
|
||||
#define E5_CS_PIN 115
|
||||
#endif
|
||||
|
||||
#define E6_STEP_PIN 116
|
||||
#define E6_DIR_PIN 117
|
||||
#define E6_ENABLE_PIN 118
|
||||
#ifndef E6_CS_PIN
|
||||
#define E6_CS_PIN 119
|
||||
#endif
|
||||
|
||||
#define E7_STEP_PIN 120
|
||||
#define E7_DIR_PIN 121
|
||||
#define E7_ENABLE_PIN 122
|
||||
#ifndef E7_CS_PIN
|
||||
#define E7_CS_PIN 123
|
||||
#endif
|
||||
#define Z3_STEP_PIN 12
|
||||
#define Z3_DIR_PIN 40
|
||||
#define Z3_ENABLE_PIN 44
|
||||
|
||||
//
|
||||
// Temperature Sensors
|
||||
//
|
||||
#define TEMP_0_PIN 0 // Analog Input
|
||||
#define TEMP_1_PIN 1 // Analog Input
|
||||
#define TEMP_2_PIN 2 // Analog Input
|
||||
#define TEMP_3_PIN 3 // Analog Input
|
||||
#define TEMP_4_PIN 4 // Analog Input
|
||||
#define TEMP_5_PIN 5 // Analog Input
|
||||
#define TEMP_6_PIN 6 // Analog Input
|
||||
#define TEMP_7_PIN 7 // Analog Input
|
||||
#define TEMP_BED_PIN 8 // Analog Input
|
||||
#define TEMP_BED_PIN 2 // Analog Input
|
||||
|
||||
// SPI for MAX Thermocouple
|
||||
#if !HAS_MEDIA
|
||||
@@ -169,33 +157,55 @@
|
||||
//
|
||||
// Heaters / Fans
|
||||
//
|
||||
#define HEATER_0_PIN 10
|
||||
#define HEATER_1_PIN 9
|
||||
#define HEATER_2_PIN 8
|
||||
#define HEATER_3_PIN 125
|
||||
#define HEATER_4_PIN 126
|
||||
#define HEATER_5_PIN 127
|
||||
#define HEATER_6_PIN 128
|
||||
#define HEATER_7_PIN 129
|
||||
#define HEATER_BED_PIN 108
|
||||
#ifndef MOSFET_A_PIN
|
||||
#define MOSFET_A_PIN 10
|
||||
#endif
|
||||
#ifndef MOSFET_B_PIN
|
||||
#define MOSFET_B_PIN 9
|
||||
#endif
|
||||
#ifndef MOSFET_C_PIN
|
||||
#define MOSFET_C_PIN 8
|
||||
#endif
|
||||
#ifndef MOSFET_D_PIN
|
||||
#define MOSFET_D_PIN -1
|
||||
#endif
|
||||
|
||||
#define HEATER_0_PIN MOSFET_A_PIN
|
||||
|
||||
#if FET_ORDER_EFB // Hotend, Fan, Bed
|
||||
#define FAN0_PIN MOSFET_B_PIN
|
||||
#define HEATER_BED_PIN MOSFET_C_PIN
|
||||
#elif FET_ORDER_EEF // Hotend, Hotend, Fan
|
||||
#define HEATER_1_PIN MOSFET_B_PIN
|
||||
#define FAN0_PIN MOSFET_C_PIN
|
||||
#elif FET_ORDER_EEB // Hotend, Hotend, Bed
|
||||
#define HEATER_1_PIN MOSFET_B_PIN
|
||||
#define HEATER_BED_PIN MOSFET_C_PIN
|
||||
#elif FET_ORDER_EFF // Hotend, Fan, Fan
|
||||
#define FAN0_PIN MOSFET_B_PIN
|
||||
#define FAN1_PIN MOSFET_C_PIN
|
||||
#elif FET_ORDER_SF // Spindle, Fan
|
||||
#define FAN0_PIN MOSFET_C_PIN
|
||||
#else // Non-specific are "EFB" (i.e., "EFBF" or "EFBE")
|
||||
#define FAN0_PIN MOSFET_B_PIN
|
||||
#define HEATER_BED_PIN MOSFET_C_PIN
|
||||
#if HOTENDS == 1 && DISABLED(HEATERS_PARALLEL)
|
||||
#define FAN1_PIN MOSFET_D_PIN
|
||||
#else
|
||||
#define HEATER_1_PIN MOSFET_D_PIN
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef FAN0_PIN
|
||||
#define FAN0_PIN 161 // IO pin. Buffer needed
|
||||
#define FAN0_PIN 4 // IO pin. Buffer needed
|
||||
#endif
|
||||
#define FAN1_PIN 162 // IO pin. Buffer needed
|
||||
#define FAN2_PIN 163 // IO pin. Buffer needed
|
||||
#define FAN3_PIN 164 // IO pin. Buffer needed
|
||||
#define FAN4_PIN 165 // IO pin. Buffer needed
|
||||
#define FAN5_PIN 166 // IO pin. Buffer needed
|
||||
#define FAN6_PIN 167 // IO pin. Buffer needed
|
||||
#define FAN7_PIN 168 // IO pin. Buffer needed
|
||||
|
||||
//
|
||||
// Misc. Functions
|
||||
//
|
||||
#define SDSS 53
|
||||
#define LED_PIN 13
|
||||
#define BOARD_NEOPIXEL_PIN 71
|
||||
#define NEOPIXEL_PIN 71
|
||||
|
||||
#ifndef FILWIDTH_PIN
|
||||
#define FILWIDTH_PIN 5 // Analog Input on AUX2
|
||||
@@ -373,37 +383,9 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Faux Expansion Headers
|
||||
* ------ ------
|
||||
* (BEEP) 37 | 1 2 | 35 (ENC) (MISO) 50 | 1 2 | 52 (SCK)
|
||||
* (LCD_EN) 17 | 3 4 | 16 (LCD_RS) (EN1) 31 | 3 4 | 53 (SDSS)
|
||||
* (LCD_D4) 23 5 6 | 25 (LCD_D5) (EN2) 33 5 6 | 51 (MOSI)
|
||||
* (LCD_D6) 27 | 7 8 | 29 (LCD_D7) (SD_DET) 49 | 7 8 | 41 (KILL)
|
||||
* -- | 9 10 | -- -- | 9 10 | --
|
||||
* ------ ------
|
||||
* EXP1 EXP2
|
||||
*/
|
||||
#define EXP1_01_PIN 37 // BEEPER
|
||||
#define EXP1_02_PIN 35 // ENC
|
||||
#define EXP1_03_PIN 17 // LCD_EN
|
||||
#define EXP1_04_PIN 16 // LCD_RS
|
||||
#define EXP1_05_PIN 23 // LCD_D4
|
||||
#define EXP1_06_PIN 25 // LCD_D5
|
||||
#define EXP1_07_PIN 27 // LCD_D6
|
||||
#define EXP1_08_PIN 29 // LCD_D7
|
||||
|
||||
#define EXP2_01_PIN 50 // MISO
|
||||
#define EXP2_02_PIN 52 // SCK
|
||||
#define EXP2_03_PIN 31 // EN1
|
||||
#define EXP2_04_PIN 53 // SDSS
|
||||
#define EXP2_05_PIN 33 // EN2
|
||||
#define EXP2_06_PIN 51 // MOSI
|
||||
#define EXP2_07_PIN 49 // SD_DET
|
||||
#define EXP2_08_PIN 41 // KILL
|
||||
|
||||
//
|
||||
// LCD / Controller
|
||||
//
|
||||
//////////////////////////
|
||||
// LCDs and Controllers //
|
||||
//////////////////////////
|
||||
|
||||
#if ANY(TFT_COLOR_UI, TFT_CLASSIC_UI, TFT_LVGL_UI)
|
||||
|
||||
@@ -415,11 +397,10 @@
|
||||
#define TFT_MOSI_PIN SD_MOSI_PIN
|
||||
#define LCD_USE_DMA_SPI
|
||||
|
||||
#define BEEPER_PIN 42
|
||||
|
||||
#define BTN_ENC 59
|
||||
#define BTN_EN1 40
|
||||
#define BTN_EN2 63
|
||||
#define BTN_ENC 59
|
||||
#define BEEPER_PIN 42
|
||||
|
||||
#define TOUCH_CS_PIN 33
|
||||
|
||||
@@ -504,9 +485,9 @@
|
||||
//
|
||||
#if ENABLED(REPRAPWORLD_GRAPHICAL_LCD)
|
||||
|
||||
#define LCD_PINS_RS EXP2_07_PIN // CS chip select /SS chip slave select
|
||||
#define LCD_PINS_EN EXP2_06_PIN // SID (MOSI)
|
||||
#define LCD_PINS_D4 EXP2_02_PIN // SCK (CLK) clock
|
||||
#define LCD_PINS_RS 49 // CS chip select /SS chip slave select
|
||||
#define LCD_PINS_EN 51 // SID (MOSI)
|
||||
#define LCD_PINS_D4 52 // SCK (CLK) clock
|
||||
|
||||
#elif ALL(IS_NEWPANEL, PANEL_ONE)
|
||||
|
||||
@@ -521,12 +502,12 @@
|
||||
|
||||
#if ENABLED(CR10_STOCKDISPLAY)
|
||||
|
||||
#define LCD_PINS_RS EXP1_07_PIN
|
||||
#define LCD_PINS_EN EXP1_08_PIN
|
||||
#define LCD_PINS_D4 EXP1_06_PIN
|
||||
#define LCD_PINS_RS 27
|
||||
#define LCD_PINS_EN 29
|
||||
#define LCD_PINS_D4 25
|
||||
|
||||
#if !IS_NEWPANEL
|
||||
#define BEEPER_PIN EXP1_01_PIN
|
||||
#define BEEPER_PIN 37
|
||||
#endif
|
||||
|
||||
#elif ENABLED(ZONESTAR_LCD)
|
||||
@@ -541,28 +522,38 @@
|
||||
#else
|
||||
|
||||
#if ANY(MKS_12864OLED, MKS_12864OLED_SSD1306)
|
||||
#define LCD_PINS_DC EXP1_06_PIN // Set as output on init
|
||||
#define LCD_PINS_RS EXP1_07_PIN // Pull low for 1s to init
|
||||
#define LCD_PINS_DC 25 // Set as output on init
|
||||
#define LCD_PINS_RS 27 // Pull low for 1s to init
|
||||
// DOGM SPI LCD Support
|
||||
#define DOGLCD_CS EXP1_04_PIN
|
||||
#define DOGLCD_MOSI EXP1_03_PIN
|
||||
#define DOGLCD_SCK EXP1_05_PIN
|
||||
#define DOGLCD_CS 16
|
||||
#define DOGLCD_MOSI 17
|
||||
#define DOGLCD_SCK 23
|
||||
#define DOGLCD_A0 LCD_PINS_DC
|
||||
#else
|
||||
#define LCD_PINS_RS EXP1_04_PIN
|
||||
#define LCD_PINS_EN EXP1_03_PIN
|
||||
#define LCD_PINS_D4 EXP1_05_PIN
|
||||
#define LCD_PINS_D5 EXP1_06_PIN
|
||||
#define LCD_PINS_D6 EXP1_07_PIN
|
||||
#define LCD_PINS_RS 16
|
||||
#define LCD_PINS_EN 17
|
||||
#define LCD_PINS_D4 23
|
||||
#define LCD_PINS_D5 25
|
||||
#define LCD_PINS_D6 27
|
||||
#endif
|
||||
|
||||
#define LCD_PINS_D7 EXP1_08_PIN
|
||||
#define LCD_PINS_D7 29
|
||||
|
||||
#if !IS_NEWPANEL
|
||||
#define BEEPER_PIN EXP2_05_PIN
|
||||
#define BEEPER_PIN 33
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if !IS_NEWPANEL
|
||||
// Buttons attached to a shift register
|
||||
// Not wired yet
|
||||
//#define SHIFT_CLK_PIN 38
|
||||
//#define SHIFT_LD_PIN 42
|
||||
//#define SHIFT_OUT_PIN 40
|
||||
//#define SHIFT_EN_PIN 17
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -572,19 +563,19 @@
|
||||
|
||||
#if ENABLED(REPRAP_DISCOUNT_SMART_CONTROLLER)
|
||||
|
||||
#define BEEPER_PIN EXP1_01_PIN
|
||||
#define BEEPER_PIN 37
|
||||
|
||||
#if ENABLED(CR10_STOCKDISPLAY)
|
||||
#define BTN_EN1 EXP1_03_PIN
|
||||
#define BTN_EN2 EXP1_05_PIN
|
||||
#define BTN_EN1 17
|
||||
#define BTN_EN2 23
|
||||
#else
|
||||
#define BTN_EN1 EXP2_03_PIN
|
||||
#define BTN_EN2 EXP2_05_PIN
|
||||
#define BTN_EN1 31
|
||||
#define BTN_EN2 33
|
||||
#endif
|
||||
|
||||
#define BTN_ENC EXP1_02_PIN
|
||||
#define SD_DETECT_PIN EXP2_07_PIN
|
||||
#define KILL_PIN EXP2_08_PIN
|
||||
#define BTN_ENC 35
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 41
|
||||
|
||||
#if ENABLED(BQ_LCD_SMART_CONTROLLER)
|
||||
#define LCD_BACKLIGHT_PIN 39
|
||||
@@ -634,34 +625,34 @@
|
||||
|
||||
#elif ENABLED(ELB_FULL_GRAPHIC_CONTROLLER)
|
||||
|
||||
#define DOGLCD_CS EXP1_08_PIN
|
||||
#define DOGLCD_A0 EXP1_07_PIN
|
||||
#define DOGLCD_CS 29
|
||||
#define DOGLCD_A0 27
|
||||
|
||||
#define BEEPER_PIN EXP1_05_PIN
|
||||
#define LCD_BACKLIGHT_PIN EXP2_05_PIN
|
||||
#define BEEPER_PIN 23
|
||||
#define LCD_BACKLIGHT_PIN 33
|
||||
|
||||
#define BTN_EN1 EXP1_02_PIN
|
||||
#define BTN_EN2 EXP1_01_PIN
|
||||
#define BTN_ENC EXP2_03_PIN
|
||||
#define BTN_EN1 35
|
||||
#define BTN_EN2 37
|
||||
#define BTN_ENC 31
|
||||
|
||||
#define LCD_SDSS SDSS
|
||||
#define SD_DETECT_PIN EXP2_07_PIN
|
||||
#define KILL_PIN EXP2_08_PIN
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 41
|
||||
|
||||
#elif ENABLED(MKS_MINI_12864)
|
||||
|
||||
#define DOGLCD_A0 EXP1_07_PIN
|
||||
#define DOGLCD_CS EXP1_06_PIN
|
||||
#define DOGLCD_A0 27
|
||||
#define DOGLCD_CS 25
|
||||
|
||||
#define BEEPER_PIN EXP1_01_PIN
|
||||
#define BEEPER_PIN 37
|
||||
// not connected to a pin
|
||||
#define LCD_BACKLIGHT_PIN 65 // backlight LED on A11/D65
|
||||
|
||||
#define BTN_EN1 EXP2_03_PIN
|
||||
#define BTN_EN2 EXP2_05_PIN
|
||||
#define BTN_ENC EXP1_02_PIN
|
||||
#define BTN_EN1 31
|
||||
#define BTN_EN2 33
|
||||
#define BTN_ENC 35
|
||||
|
||||
#define SD_DETECT_PIN EXP2_07_PIN
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 64
|
||||
|
||||
//#define LCD_SCREEN_ROTATE 180 // 0, 90, 180, 270
|
||||
@@ -694,6 +685,7 @@
|
||||
|
||||
#else
|
||||
|
||||
// Beeper on AUX-4
|
||||
#define BEEPER_PIN 33
|
||||
|
||||
// Buttons are directly attached to AUX-2
|
||||
@@ -709,15 +701,15 @@
|
||||
#define BTN_EN2 63 // AUX2 PIN 4
|
||||
#define BTN_ENC 49 // AUX3 PIN 7
|
||||
#else
|
||||
#define BTN_EN1 EXP1_01_PIN
|
||||
#define BTN_EN2 EXP1_02_PIN
|
||||
#define BTN_ENC EXP2_03_PIN
|
||||
#define SD_DETECT_PIN EXP2_08_PIN
|
||||
#define BTN_EN1 37
|
||||
#define BTN_EN2 35
|
||||
#define BTN_ENC 31
|
||||
#define SD_DETECT_PIN 41
|
||||
#endif
|
||||
|
||||
#if ENABLED(G3D_PANEL)
|
||||
#define SD_DETECT_PIN EXP2_07_PIN
|
||||
#define KILL_PIN EXP2_08_PIN
|
||||
#define SD_DETECT_PIN 49
|
||||
#define KILL_PIN 41
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -727,7 +719,3 @@
|
||||
#endif // IS_NEWPANEL
|
||||
|
||||
#endif // HAS_WIRED_LCD
|
||||
|
||||
#ifndef KILL_PIN
|
||||
#define KILL_PIN EXP2_08_PIN
|
||||
#endif
|
||||
|
||||
@@ -504,6 +504,13 @@
|
||||
#include "lpc1769/pins_BTT_SKR_E3_TURBO.h" // LPC1769 env:LPC1769
|
||||
#elif MB(FLY_CDY)
|
||||
#include "lpc1769/pins_FLY_CDY.h" // LPC1769 env:LPC1769
|
||||
//
|
||||
// LPC4078 ARM Cortex M4
|
||||
//
|
||||
|
||||
#elif MB(EBAB)
|
||||
#include "lpc4078/pins_EBAB.h" // LPC4078 env:LPC4078
|
||||
|
||||
|
||||
//
|
||||
// Due (ATSAM) boards
|
||||
|
||||
@@ -477,7 +477,7 @@
|
||||
#undef PS_ON_PIN
|
||||
#define PS_ON_PIN -1
|
||||
#endif
|
||||
#if DISABLED(PSU_OFF_REDUNDANT) || !defined(PS_ON1_PIN)
|
||||
#if DISABLED(PSU_OFF_REDUNDANT) || DISABLED(PSU_CONTROL) || !defined(PS_ON1_PIN)
|
||||
#undef PS_ON1_PIN
|
||||
#define PS_ON1_PIN -1
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@ set -e
|
||||
# Build with the default configurations
|
||||
#
|
||||
restore_configs
|
||||
opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_V1_1 SERIAL_PORT 1 SERIAL_PORT_2 -1 TEMP_SENSOR_SOC 100
|
||||
opt_set MOTHERBOARD BOARD_BTT_SKR_MINI_V1_1 SERIAL_PORT 1 SERIAL_PORT_2 -1 TEMP_SENSOR_SOC 1
|
||||
exec_test $1 $2 "BigTreeTech SKR Mini v1.1 - SOC Temperature" "$3"
|
||||
|
||||
# clean up
|
||||
|
||||
@@ -42,3 +42,28 @@ board = nxp_lpc1768
|
||||
[env:LPC1769]
|
||||
extends = common_LPC
|
||||
board = nxp_lpc1769
|
||||
|
||||
#
|
||||
# NXP LPC4078 ARM Cortex-M4
|
||||
#
|
||||
[env:LPC4078]
|
||||
board = nxp_lpc4078
|
||||
#platform = symlink:///home/p3p/workspace/EBAB_workspace/platform-mcui
|
||||
#platform_packages = framework-arduino-mcui@symlink:///home/p3p/workspace/EBAB_workspace/framework-arduino-mcui
|
||||
platform = https://github.com/p3p/pio-platform-mcui/archive/refs/heads/master.zip
|
||||
framework = arduino
|
||||
upload_protocol = jlink
|
||||
debug_tool = jlink
|
||||
monitor_speed = 500000
|
||||
lib_ldf_mode = off
|
||||
lib_compat_mode = strict
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
Marlin/src/HAL/LPC1768/upload_extra_script.py
|
||||
build_src_filter = ${common.default_src_filter} +<src/HAL/LPC4078> +<src/HAL/shared/backtrace>
|
||||
build_flags = ${common.build_flags} -IMarlin/src/HAL/LPC4078/include -DTARGET_LPC4078 -DU8G_HAL_LINKS -IMarlin/src/HAL/LPC4078/u8g -DPLATFORM_M997_SUPPORT -O3
|
||||
build_unflags = -Os
|
||||
lib_deps = ${common.lib_deps}
|
||||
Servo
|
||||
SoftwareSerial
|
||||
custom_marlin.USES_LIQUIDCRYSTAL = arduino-libraries/LiquidCrystal@~1.0.7
|
||||
custom_marlin.NEOPIXEL_LED = Adafruit NeoPixel=https://github.com/p3p/Adafruit_NeoPixel/archive/1.5.0.zip
|
||||
|
||||
+1
-2
@@ -15,12 +15,11 @@
|
||||
[env:SAMD51_grandcentral_m4]
|
||||
platform = atmelsam
|
||||
board = adafruit_grandcentral_m4
|
||||
build_flags = ${common.build_flags} -std=gnu++17 -DUSE_TINYUSB
|
||||
build_flags = ${common.build_flags} -std=gnu++17
|
||||
build_unflags = -std=gnu++11
|
||||
build_src_filter = ${common.default_src_filter} +<src/HAL/SAMD51>
|
||||
lib_deps = ${common.lib_deps}
|
||||
SoftwareSerialM
|
||||
Adafruit TinyUSB Library
|
||||
extra_scripts = ${common.extra_scripts}
|
||||
pre:buildroot/share/PlatformIO/scripts/SAMD51_grandcentral_m4.py
|
||||
custom_marlin.HAS_MEDIA = SdFat - Adafruit Fork, Adafruit SPIFlash
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
[platformio]
|
||||
src_dir = Marlin
|
||||
boards_dir = buildroot/share/PlatformIO/boards
|
||||
default_envs = mega2560
|
||||
default_envs = LPC4078
|
||||
include_dir = Marlin
|
||||
extra_configs =
|
||||
Marlin/config.ini
|
||||
|
||||
Reference in New Issue
Block a user