Bump to head

This commit is contained in:
InsanityAutomation
2019-12-07 17:19:58 -05:00
parent d05461e488
commit 1ccfbaa39f
795 changed files with 130533 additions and 28992 deletions
-274
View File
@@ -1,274 +0,0 @@
# Python CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-python/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
# use `-browsers` prefix for selenium tests, e.g. `3.6.1-browsers`
- image: circleci/python:2.7.13
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/postgres:9.4
environment:
TEST_PLATFORM: "-e megaatmega2560"
working_directory: ~/Marlin
steps:
- checkout
- restore_cache:
paths:
- ~/.platformio
- ~/Marlin/.piolibdeps
keys:
- v1-dependencies-{{ checksum "~/Marlin/platformio.ini" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run:
name: install dependencies
command: |
sudo pip install -U platformio
# run tests!
- run:
name: run tests
command: |
#
#
# Fetch the tag information for the current branch
ls -la
git fetch origin --tags
#
# Publish the buildroot script folder
chmod +x buildroot/bin/*
export PATH=`pwd`/buildroot/bin/:${PATH}
# Generate custom version include
generate_version ./Marlin/src/inc
cat ./Marlin/src/inc/_Version.h
#
# Back up pins_RAMPS.h
#
backup_ramps
env_backup
#################################
# Build all sample configurations
#################################
echo testing megaatmega2560 targets...
export TEST_PLATFORM="-e megaatmega2560"
echo use_example_configs adafruit/ST7565
use_example_configs adafruit/ST7565
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs BQ/Hephestos
use_example_configs BQ/Hephestos
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs BQ/Hephestos_2
use_example_configs BQ/Hephestos_2
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs BQ/WITBOX
use_example_configs BQ/WITBOX
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs AliExpress/CL-260
use_example_configs AliExpress/CL-260
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
#echo use_example_configs Cartesio
#use_example_configs Cartesio
#build_marlin_pio ./ ${TEST_PLATFORM}
#restore_configs
echo use_example_configs delta/FLSUN/auto_calibrate
use_example_configs delta/FLSUN/auto_calibrate
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs delta/FLSUN/kossel_mini
use_example_configs delta/FLSUN/kossel_mini
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs delta/generic
use_example_configs delta/generic
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs delta/kossel_mini
use_example_configs delta/kossel_mini
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs delta/kossel_xl
use_example_configs delta/kossel_xl
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Felix
use_example_configs Felix
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Felix/DUAL
use_example_configs Felix/DUAL
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs FolgerTech/i3-2020
use_example_configs FolgerTech/i3-2020
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs gCreate/gMax1.5+
use_example_configs gCreate/gMax1.5+
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Geeetech/GT2560
use_example_configs Geeetech/GT2560
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
#echo use_example_configs Geeetech/I3_Pro_X-GT2560
#use_example_configs Geeetech/I3_Pro_X-GT2560
#build_marlin_pio ./ ${TEST_PLATFORM}
#restore_configs
echo use_example_configs Infitary/i3-M508
use_example_configs Infitary/i3-M508
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
use_example_configs Malyan/M200
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Micromake/C1/basic
use_example_configs Micromake/C1/basic
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Micromake/C1/enhanced
use_example_configs Micromake/C1/enhanced
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs RepRapWorld/Megatronics
use_example_configs RepRapWorld/Megatronics
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs RigidBot
use_example_configs RigidBot
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs SCARA
use_example_configs SCARA
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Velleman/K8200
use_example_configs Velleman/K8200
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Velleman/K8400/Dual-head
use_example_configs Velleman/K8400/Dual-head
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Velleman/K8400
use_example_configs Velleman/K8400
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Wanhao/Duplicator6
use_example_configs Wanhao/Duplicator6
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
# Requires manual load of https://github.com/stawel/SlowSoftI2CMaster
#use_example_configs wt150
#build_marlin_pio ./ ${TEST_PLATFORM}
#restore_configs
echo testing melzi targets...
export TEST_PLATFORM="-e melzi"
echo use_example_configs Anet/A6
use_example_configs Anet/A6
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Anet/A8
use_example_configs Anet/A8
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Creality/CR-10
use_example_configs Creality/CR-10
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Malyan/M150
use_example_configs Malyan/M150
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs Sanguinololu
use_example_configs Sanguinololu
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs TinyBoy2
use_example_configs TinyBoy2
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo testing rambo targets...
export TEST_PLATFORM="-e rambo"
echo use_example_configs AlephObjects/TAZ4
use_example_configs AlephObjects/TAZ4
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo testing at90usb1286_* targets...
export TEST_PLATFORM="-e at90usb1286_dfu"
#echo se_example_configs delta/kossel_pro
#use_example_configs delta/kossel_pro
#build_marlin_pio ./ ${TEST_PLATFORM}
#restore_configs
echo use_example_configs makibox
use_example_configs makibox
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo testing sanguino_atmega644p targets...
export TEST_PLATFORM="-e sanguino_atmega644p"
echo use_example_configs tvrrug/Round2
use_example_configs tvrrug/Round2
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo testing LPC1768 targets...
export TEST_PLATFORM="-e LPC1768"
echo use_example_configs Mks/Sbase
use_example_configs Mks/Sbase
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo testing STM32F1 targets...
export TEST_PLATFORM="-e STM32F103RE"
restore_configs
echo use_example_configs STM32/STM32F103RE
use_example_configs STM32/STM32F103RE
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo use_example_configs STM32/stm32f103ret6
use_example_configs STM32/stm32f103ret6
build_marlin_pio ./ ${TEST_PLATFORM}
restore_configs
echo testing DUE targets...
export TEST_PLATFORM="-e DUE"
#echo use_example_configs UltiMachine/Archim2
#use_example_configs UltiMachine/Archim2
#build_marlin_pio ./ ${TEST_PLATFORM}
#restore_configs
#
# Remove temp files from dependencies tree prior to caching
rm -rf ~/Marlin/.piolibdeps/_tmp_*
#
# Restore the environment
#
env_restore
- save_cache:
paths:
- ~/.platformio
- ~/Marlin/.piolibdeps
key: v1-dependencies-{{ checksum "~/Marlin/platformio.ini" }}
+15 -13
View File
@@ -14,44 +14,46 @@ env:
- TEST_PLATFORM="esp32"
- TEST_PLATFORM="linux_native"
- TEST_PLATFORM="megaatmega2560"
- TEST_PLATFORM="STM32F103RE"
- TEST_PLATFORM="teensy31"
- TEST_PLATFORM="teensy35"
# Extended AVR Environments
- TEST_PLATFORM="fysetc_f6_13"
- TEST_PLATFORM="FYSETC_F6_13"
- TEST_PLATFORM="megaatmega1280"
- TEST_PLATFORM="rambo"
- TEST_PLATFORM="sanguino_atmega1284p"
- TEST_PLATFORM="sanguino_atmega644p"
# Extended STM32 Environments
- TEST_PLATFORM="ARMED"
- TEST_PLATFORM="BIGTREE_BTT002"
- TEST_PLATFORM="BIGTREE_SKR_PRO"
- TEST_PLATFORM="STM32F103RC_bigtree"
- TEST_PLATFORM="STM32F103RC_bigtree_USB"
- TEST_PLATFORM="STM32F103RE_bigtree"
- TEST_PLATFORM="STM32F103RE_bigtree_USB"
- TEST_PLATFORM="STM32F103RC_fysetc"
- TEST_PLATFORM="jgaurora_a5s_a1"
- TEST_PLATFORM="STM32F103VE_longer"
- TEST_PLATFORM="STM32F407VE_black"
- TEST_PLATFORM="BIGTREE_SKR_PRO"
- TEST_PLATFORM="mks_robin"
- TEST_PLATFORM="ARMED"
# STM32 with non-STM framework. both broken for now. they should use HAL_STM32 which is working.
#- TEST_PLATFORM="STM32F4"
#- TEST_PLATFORM="STM32F7"
# Put lengthy tests last
- TEST_PLATFORM="LPC1768"
- TEST_PLATFORM="LPC1769"
# Non-working environment tests
#- TEST_PLATFORM="BIGTREE_BTT002" this board isn't released yet. we need pinout to be sure about what we do
#- TEST_PLATFORM="at90usb1286_cdc"
#- TEST_PLATFORM="at90usb1286_dfu"
#- TEST_PLATFORM="STM32F103CB_malyan"
#- TEST_PLATFORM="mks_robin"
#- TEST_PLATFORM="mks_robin_lite"
#- TEST_PLATFORM="mks_robin_mini"
#- TEST_PLATFORM="mks_robin_nano"
#- TEST_PLATFORM="SAMD51_grandcentral_m4"
#- TEST_PLATFORM="STM32F103RC_bigtree"
#- TEST_PLATFORM="STM32F103RC_bigtree_USB"
#- TEST_PLATFORM="STM32F103RC_fysetc"
#- TEST_PLATFORM="STM32F4"
#- TEST_PLATFORM="STM32F7"
before_install:
#
@@ -75,8 +77,8 @@ before_script:
- cd ${TRAVIS_BUILD_DIR}
#
# Generate custom version include
- generate_version ${TRAVIS_BUILD_DIR}/Marlin/src/inc
- cat ${TRAVIS_BUILD_DIR}/Marlin/src/inc/_Version.h
- generate_version ${TRAVIS_BUILD_DIR}/Marlin/
- cat ${TRAVIS_BUILD_DIR}/Marlin/Version.h
#
script:
- run_tests ${TRAVIS_BUILD_DIR} ${TEST_PLATFORM}
+33 -35
View File
@@ -79,6 +79,7 @@
// Author info of this build printed to the host during boot and M115
#define STRING_CONFIG_H_AUTHOR "Tinymachines 3D" // Who made the changes.
#define CUSTOM_VERSION_FILE Version.h // Path from the root directory (no quotes)
/**
* *** VENDORS PLEASE READ ***
@@ -332,9 +333,10 @@
//#define PSU_NAME "Power Supply"
#if ENABLED(PSU_CONTROL)
#define PSU_ACTIVE_HIGH false // Set 'false' for ATX (1), 'true' for X-Box (2)
#define PSU_ACTIVE_HIGH false // Set 'false' for ATX, 'true' for X-Box
//#define PS_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_DEFAULT_OFF // Keep power off until enabled directly with M80
//#define PSU_POWERUP_DELAY 100 // (ms) Delay for the PSU to warm up to full power
//#define AUTO_POWER_CONTROL // Enable automatic control of the PS_ON pin
#if ENABLED(AUTO_POWER_CONTROL)
@@ -359,9 +361,10 @@
*
* Temperature sensors available:
*
* -5 : PT100 / PT1000 with MAX31865 (only for sensors 0-1)
* -3 : thermocouple with MAX31855 (only for sensors 0-1)
* -2 : thermocouple with MAX6675 (only for sensors 0-1)
* -4 : thermocouple with AD8495
* -3 : thermocouple with MAX31855 (only for sensor 0)
* -2 : thermocouple with MAX6675 (only for sensor 0)
* -1 : thermocouple with AD595
* 0 : not used
* 1 : 100k thermistor - best choice for EPCOS 100k (4.7k pullup)
@@ -391,6 +394,7 @@
* 67 : 450C thermistor from SliceEngineering
* 70 : the 100K thermistor found in the bq Hephestos 2
* 75 : 100k Generic Silicon Heat Pad with NTC 100K MGB18-104F39050L32 thermistor
* 99 : 100k thermistor with a 10K pull-up resistor (found on some Wanhao i3 machines)
*
* 1k ohm pullup tables - This is atypical, and requires changing out the 4.7k pullup for 1k.
* (but gives greater accuracy and more stable PID)
@@ -408,8 +412,6 @@
* Use these for Testing or Development purposes. NEVER for production machine.
* 998 : Dummy Table that ALWAYS reads 25°C or the temperature defined below.
* 999 : Dummy Table that ALWAYS reads 100°C or the temperature defined below.
*
* :{ '0':"Not used", '1':"100k / 4.7k - EPCOS", '331':"(3.3V thermistor 1)", '2':"200k / 4.7k - ATC Semitec 204GT-2", '3':"Mendel-parts / 4.7k", '4':"10k !! do not use for a hotend. Bad resolution at high temp. !!", '5':"100K / 4.7k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '501':"100K Zonestar (Tronxy X3A)", '512':"100k RPW-Ultra hotend thermistor", '6':"100k / 4.7k EPCOS - Not as accurate as Table 1", '7':"100k / 4.7k Honeywell 135-104LAG-J01", '8':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT", '9':"100k / 4.7k GE Sensing AL03006-58.2K-97-G1", '10':"100k / 4.7k RS 198-961", '11':"100k / 4.7k beta 3950 1%", '12':"100k / 4.7k 0603 SMD Vishay NTCS0603E3104FXT (calibrated for Makibox hot bed)", '13':"100k Hisens 3950 1% up to 300°C for hotend 'Simple ONE ' & hotend 'All In ONE'", '18':"ATC Semitec 204GT-2 (4.7k pullup) Dagoma.Fr - MKS_Base_DKU001327" '20':"Pt100 (Ultimainboard V2.x)", '201':"Pt100 (Overlord)", '51':"100k / 1k - EPCOS", '52':"200k / 1k - ATC Semitec 204GT-2", '55':"100k / 1k - ATC Semitec 104GT-2 (Used in ParCan & J-Head)", '60':"100k Maker's Tool Works Kapton Bed Thermistor beta=3950", '61':"100k Formbot / Vivedino 3950 350C thermistor 4.7k pullup", '66':"Dyze Design 4.7M High Temperature thermistor", '67':"Slice Engineering 450C High Temperature thermistor", '70':"the 100K thermistor found in the bq Hephestos 2", '71':"100k / 4.7k Honeywell 135-104LAF-J01", '147':"Pt100 / 4.7k", '1047':"Pt1000 / 4.7k", '110':"Pt100 / 1k (non-standard)", '1010':"Pt1000 / 1k (non standard)", '-4':"Thermocouple + AD8495", '-3':"Thermocouple + MAX31855 (only for sensor 0)", '-2':"Thermocouple + MAX6675 (only for sensor 0)", '-1':"Thermocouple + AD595", '998':"Dummy 1", '999':"Dummy 2", '1000':"Custom thermistor params" }
*/
#define TEMP_SENSOR_0 1
#define TEMP_SENSOR_1 0
@@ -744,14 +746,14 @@
/**
* Default Axis Steps Per Unit (steps/mm)
* Override with M92
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_AXIS_STEPS_PER_UNIT { 80.121, 80.121, 399.778, 445 }
/**
* Default Max Feed Rate (mm/s)
* Override with M203
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_FEEDRATE { 300, 300, 50, 70 }
@@ -764,7 +766,7 @@
* Default Max Acceleration (change/s) change = mm/s
* (Maximum start speed for accelerated moves)
* Override with M201
* X, Y, Z, E0 [, E1[, E2[, E3[, E4[, E5]]]]]
* X, Y, Z, E0 [, E1[, E2...]]
*/
#define DEFAULT_MAX_ACCELERATION { 1500, 1500, 100, 10000 }
@@ -786,30 +788,17 @@
#define DEFAULT_TRAVEL_ACCELERATION 3000 // X, Y, Z acceleration for travel (non printing) moves
/**
* Junction Deviation
*
* Use Junction Deviation instead of traditional Jerk Limiting
*
* See:
* https://reprap.org/forum/read.php?1,739819
* http://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html
*/
#define JUNCTION_DEVIATION
#if ENABLED(JUNCTION_DEVIATION)
#define JUNCTION_DEVIATION_MM 0.08 // (mm) Distance from real junction edge
#endif
/**
* Default Jerk (mm/s)
* Default Jerk limits (mm/s)
* Override with M205 X Y Z E
*
* "Jerk" specifies the minimum speed change that requires acceleration.
* When changing speed and direction, if the difference is less than the
* value set here, it may happen instantaneously.
*/
#if DISABLED(JUNCTION_DEVIATION)
#define DEFAULT_XJERK 8.0
#define DEFAULT_YJERK 8.0
//#define CLASSIC_JERK
#if ENABLED(CLASSIC_JERK)
#define DEFAULT_XJERK 10.0
#define DEFAULT_YJERK 10.0
#define DEFAULT_ZJERK 0.3
//#define LIMITED_JERK_EDITING // Limit edit via M205 or LCD to DEFAULT_aJERK * 2
@@ -820,6 +809,17 @@
#define DEFAULT_EJERK 5.0 // May be used by Linear Advance
/**
* Junction Deviation Factor
*
* See:
* https://reprap.org/forum/read.php?1,739819
* http://blog.kyneticcnc.com/2018/10/computing-junction-deviation-for-marlin.html
*/
#if DISABLED(CLASSIC_JERK)
#define JUNCTION_DEVIATION_MM 0.08 // (mm) Distance from real junction edge
#endif
/**
* S-Curve Acceleration
*
@@ -934,8 +934,6 @@
/**
* Z Probe to nozzle (X,Y) offset, relative to (0, 0).
* Default X and Y offsets must be integers.
* Floats may be set with M851 if required.
*
* In the following example the X and Y offsets are both positive:
*
@@ -1630,10 +1628,10 @@
*
* Select the language to display on the LCD. These languages are available:
*
* en, an, bg, ca, cz, da, de, el, el-gr, es, eu, fi, fr, gl, hr, it, jp-kana,
* ko_KR, nl, pl, pt, pt-br, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
* en, an, bg, ca, cz, da, de, el, el_gr, es, eu, fi, fr, gl, hr, it, jp_kana,
* ko_KR, nl, pl, pt, pt_br, ru, sk, tr, uk, vi, zh_CN, zh_TW, test
*
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el-gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'jp-kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt-br':'Portuguese (Brazilian)', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
* :{ 'en':'English', 'an':'Aragonese', 'bg':'Bulgarian', 'ca':'Catalan', 'cz':'Czech', 'da':'Danish', 'de':'German', 'el':'Greek', 'el_gr':'Greek (Greece)', 'es':'Spanish', 'eu':'Basque-Euskera', 'fi':'Finnish', 'fr':'French', 'gl':'Galician', 'hr':'Croatian', 'it':'Italian', 'jp_kana':'Japanese', 'ko_KR':'Korean (South Korea)', 'nl':'Dutch', 'pl':'Polish', 'pt':'Portuguese', 'pt_br':'Portuguese (Brazilian)', 'ru':'Russian', 'sk':'Slovak', 'tr':'Turkish', 'uk':'Ukrainian', 'vi':'Vietnamese', 'zh_CN':'Chinese (Simplified)', 'zh_TW':'Chinese (Traditional)', 'test':'TEST' }
*/
#define LCD_LANGUAGE en
@@ -2022,7 +2020,7 @@
//
// AZSMZ 12864 LCD with SD
// https://www.aliexpress.com/store/product/3D-printer-smart-controller-SMART-RAMPS-OR-RAMPS-1-4-LCD-12864-LCD-control-panel-green/2179173_32213636460.html
// https://www.aliexpress.com/item/32837222770.html
//
//#define AZSMZ_12864
@@ -2089,10 +2087,10 @@
//#define MALYAN_LCD
//
// LulzBot Color Touch UI for FTDI EVE (FT800/FT810) displays
// Touch UI for FTDI EVE (FT800/FT810) displays
// See Configuration_adv.h for all configuration options.
//
//#define LULZBOT_TOUCH_UI
//#define TOUCH_UI_FTDI_EVE
//
// Third-party or vendor-customized controller interfaces.
+165 -64
View File
@@ -138,7 +138,7 @@
*/
#if ENABLED(THERMAL_PROTECTION_HOTENDS)
#define THERMAL_PROTECTION_PERIOD 40 // Seconds
#define THERMAL_PROTECTION_HYSTERESIS 4 // Degrees Celsius
#define THERMAL_PROTECTION_HYSTERESIS 10 // Degrees Celsius
#define ADAPTIVE_FAN_SLOWING // Slow part cooling fan if temperature drops
#if BOTH(ADAPTIVE_FAN_SLOWING, PIDTEMP)
@@ -197,6 +197,56 @@
#define DEFAULT_Kc (100) //heating power=Kc*(e_speed)
#define LPQ_MAX_LEN 50
#endif
/**
* Add an experimental additional term to the heater power, proportional to the fan speed.
* A well-chosen Kf value should add just enough power to compensate for power-loss from the cooling fan.
* You can either just add a constant compensation with the DEFAULT_Kf value
* or follow the instruction below to get speed-dependent compensation.
*
* Constant compensation (use only with fanspeeds of 0% and 100%)
* ---------------------------------------------------------------------
* A good starting point for the Kf-value comes from the calculation:
* kf = (power_fan * eff_fan) / power_heater * 255
* where eff_fan is between 0.0 and 1.0, based on fan-efficiency and airflow to the nozzle / heater.
*
* Example:
* Heater: 40W, Fan: 0.1A * 24V = 2.4W, eff_fan = 0.8
* Kf = (2.4W * 0.8) / 40W * 255 = 12.24
*
* Fan-speed dependent compensation
* --------------------------------
* 1. To find a good Kf value, set the hotend temperature, wait for it to settle, and enable the fan (100%).
* Make sure PID_FAN_SCALING_LIN_FACTOR is 0 and PID_FAN_SCALING_ALTERNATIVE_DEFINITION is not enabled.
* If you see the temperature drop repeat the test, increasing the Kf value slowly, until the temperature
* drop goes away. If the temperature overshoots after enabling the fan, the Kf value is too big.
* 2. Note the Kf-value for fan-speed at 100%
* 3. Determine a good value for PID_FAN_SCALING_MIN_SPEED, which is around the speed, where the fan starts moving.
* 4. Repeat step 1. and 2. for this fan speed.
* 5. Enable PID_FAN_SCALING_ALTERNATIVE_DEFINITION and enter the two identified Kf-values in
* PID_FAN_SCALING_AT_FULL_SPEED and PID_FAN_SCALING_AT_MIN_SPEED. Enter the minimum speed in PID_FAN_SCALING_MIN_SPEED
*/
//#define PID_FAN_SCALING
#if ENABLED(PID_FAN_SCALING)
//#define PID_FAN_SCALING_ALTERNATIVE_DEFINITION
#if ENABLED(PID_FAN_SCALING_ALTERNATIVE_DEFINITION)
// The alternative definition is used for an easier configuration.
// Just figure out Kf at fullspeed (255) and PID_FAN_SCALING_MIN_SPEED.
// DEFAULT_Kf and PID_FAN_SCALING_LIN_FACTOR are calculated accordingly.
#define PID_FAN_SCALING_AT_FULL_SPEED 13.0 //=PID_FAN_SCALING_LIN_FACTOR*255+DEFAULT_Kf
#define PID_FAN_SCALING_AT_MIN_SPEED 6.0 //=PID_FAN_SCALING_LIN_FACTOR*PID_FAN_SCALING_MIN_SPEED+DEFAULT_Kf
#define PID_FAN_SCALING_MIN_SPEED 10.0 // Minimum fan speed at which to enable PID_FAN_SCALING
#define DEFAULT_Kf (255.0*PID_FAN_SCALING_AT_MIN_SPEED-PID_FAN_SCALING_AT_FULL_SPEED*PID_FAN_SCALING_MIN_SPEED)/(255.0-PID_FAN_SCALING_MIN_SPEED)
#define PID_FAN_SCALING_LIN_FACTOR (PID_FAN_SCALING_AT_FULL_SPEED-DEFAULT_Kf)/255.0
#else
#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
#endif
#endif
/**
@@ -214,7 +264,7 @@
#define AUTOTEMP_OLDWEIGHT 0.98
#endif
// Show extra position information in M114
// Show extra position information with 'M114 D'
//#define M114_DETAIL
// Show Temperature ADC value
@@ -290,6 +340,9 @@
// before setting a PWM value. (Does not work with software PWM for fan on Sanguinololu)
//#define FAN_KICKSTART_TIME 100
// Some coolers may require a non-zero "off" state.
//#define FAN_OFF_PWM 1
/**
* PWM Fan Scaling
*
@@ -605,18 +658,32 @@
#endif
#if ENABLED(Z_STEPPER_AUTO_ALIGN)
// Define probe X and Y positions for Z1, Z2 [, Z3]
#define Z_STEPPER_ALIGN_XY { { 30, 150 }, { 270, 150 } }
#define Z_STEPPER_ALIGN_XY { { 270, 150 }, { 30, 150 } }
// Provide Z stepper positions for more rapid convergence in bed alignment.
// Currently requires triple stepper drivers.
//#define Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS
#if ENABLED(Z_STEPPER_ALIGN_KNOWN_STEPPER_POSITIONS)
// Define Stepper XY positions for Z1, Z2, Z3 corresponding to
// the Z screw positions in the bed carriage.
// Define one position per Z stepper in stepper driver order.
#define Z_STEPPER_ALIGN_STEPPER_XY { { 210.7, 102.5 }, { 152.6, 220.0 }, { 94.5, 102.5 } }
#else
// Amplification factor. Used to scale the correction step up or down.
// In case the stepper (spindle) position is further out than the test point.
// Use a value > 1. NOTE: This may cause instability
#define Z_STEPPER_ALIGN_AMP 1.0
#endif
// Set number of iterations to align
#define Z_STEPPER_ALIGN_ITERATIONS 3
// Enable to restore leveling setup after operation
#define RESTORE_LEVELING_AFTER_G34
// On a 300mm bed a 5% grade would give a misalignment of ~1.5cm
#define G34_MAX_GRADE 5 // (%) Maximum incline G34 will handle
// Use the amplification factor to de-/increase correction step.
// In case the stepper (spindle) position is further out than the test point
// Use a value > 1. NOTE: This may cause instability
#define Z_STEPPER_ALIGN_AMP 1.0
// Stop criterion. If the accuracy is better than this stop iterating early
#define Z_STEPPER_ALIGN_ACC 0.02
#endif
@@ -891,6 +958,17 @@
#if ENABLED(GraphicalLCD)
#define LCD_SET_PROGRESS_MANUALLY
#endif
// Show the E position (filament used) during printing
//#define LCD_SHOW_E_TOTAL
#if HAS_GRAPHICAL_LCD && HAS_PRINT_PROGRESS
//#define PRINT_PROGRESS_SHOW_DECIMALS // Show progress with decimal digits
//#define SHOW_REMAINING_TIME // Display estimated time to completion
#if ENABLED(SHOW_REMAINING_TIME)
//#define USE_M73_REMAINING_TIME // Use remaining time from M73 command instead of estimation
//#define ROTATE_PROGRESS_DISPLAY // Display (P)rogress, (E)lapsed, and (R)emaining time
#endif
#endif
#if HAS_CHARACTER_LCD && HAS_PRINT_PROGRESS
//#define LCD_PROGRESS_BAR // Show a progress bar on HD44780 LCDs for SD printing
@@ -935,6 +1013,8 @@
*/
//#define POWER_LOSS_RECOVERY
#if ENABLED(POWER_LOSS_RECOVERY)
//#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
//#define POWER_LOSS_STATE HIGH // State of pin indicating power loss
//#define POWER_LOSS_PULL // Set pullup / pulldown as appropriate
@@ -1167,9 +1247,9 @@
#endif // HAS_GRAPHICAL_LCD
//
// Lulzbot Touch UI
// Touch UI for the FTDI Embedded Video Engine (EVE)
//
#if ENABLED(LULZBOT_TOUCH_UI)
#if ENABLED(TOUCH_UI_FTDI_EVE)
// Display board used
//#define LCD_FTDI_VM800B35A // FTDI 3.5" with FT800 (320x240)
//#define LCD_4DSYSTEMS_4DLCD_FT843 // 4D Systems 4.3" (480x272)
@@ -1247,6 +1327,9 @@
// Output extra debug info for Touch UI events
//#define TOUCH_UI_DEBUG
// Developer menu (accessed by touching "About Printer" copyright text)
//#define TOUCH_UI_DEVELOPER_MENU
#endif
//
@@ -1291,7 +1374,8 @@
//#define BABYSTEP_WITHOUT_HOMING
//#define BABYSTEP_XY // Also enable X/Y Babystepping. Not supported on DELTA!
#define BABYSTEP_INVERT_Z false // Change if Z babysteps should go the other way
#define BABYSTEP_MULTIPLICATOR 10 // Babysteps are very small. Increase for faster motion.
#define BABYSTEP_MULTIPLICATOR_Z 10 // Babysteps are very small. Increase for faster motion.
#define BABYSTEP_MULTIPLICATOR_XY 1
#if ENABLED(GraphicalLCD)
#define DOUBLECLICK_FOR_Z_BABYSTEPPING // Double-click on the Status Screen for Z Babystepping.
@@ -1811,94 +1895,101 @@
#define INTERPOLATE true // Interpolate X/Y/Z_MICROSTEPS to 256
#if AXIS_IS_TMC(X)
#define X_CURRENT 800 // (mA) RMS current. Multiply by 1.414 for peak current.
#define X_MICROSTEPS 16 // 0..256
#define X_RSENSE 0.11
#define X_CHAIN_POS -1 // <=0 : Not chained. 1 : MCU MOSI connected. 2 : Next in chain, ...
#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_CHAIN_POS -1 // <=0 : Not chained. 1 : MCU MOSI connected. 2 : Next in chain, ...
#endif
#if AXIS_IS_TMC(X2)
#define X2_CURRENT 800
#define X2_MICROSTEPS 16
#define X2_RSENSE 0.11
#define X2_CHAIN_POS -1
#define X2_CURRENT 800
#define X2_CURRENT_HOME X2_CURRENT
#define X2_MICROSTEPS 16
#define X2_RSENSE 0.11
#define X2_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(Y)
#define Y_CURRENT 800
#define Y_MICROSTEPS 16
#define Y_RSENSE 0.11
#define Y_CHAIN_POS -1
#define Y_CURRENT 800
#define Y_CURRENT_HOME Y_CURRENT
#define Y_MICROSTEPS 16
#define Y_RSENSE 0.11
#define Y_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(Y2)
#define Y2_CURRENT 800
#define Y2_MICROSTEPS 16
#define Y2_RSENSE 0.11
#define Y2_CHAIN_POS -1
#define Y2_CURRENT 800
#define Y2_CURRENT_HOME Y2_CURRENT
#define Y2_MICROSTEPS 16
#define Y2_RSENSE 0.11
#define Y2_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(Z)
#define Z_CURRENT 800
#define Z_MICROSTEPS 16
#define Z_RSENSE 0.11
#define Z_CHAIN_POS -1
#define Z_CURRENT 800
#define Z_CURRENT_HOME Z_CURRENT
#define Z_MICROSTEPS 16
#define Z_RSENSE 0.11
#define Z_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(Z2)
#define Z2_CURRENT 800
#define Z2_MICROSTEPS 16
#define Z2_RSENSE 0.11
#define Z2_CHAIN_POS -1
#define Z2_CURRENT 800
#define Z2_CURRENT_HOME Z2_CURRENT
#define Z2_MICROSTEPS 16
#define Z2_RSENSE 0.11
#define Z2_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(Z3)
#define Z3_CURRENT 800
#define Z3_MICROSTEPS 16
#define Z3_RSENSE 0.11
#define Z3_CHAIN_POS -1
#define Z3_CURRENT 800
#define Z3_CURRENT_HOME Z3_CURRENT
#define Z3_MICROSTEPS 16
#define Z3_RSENSE 0.11
#define Z3_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(E0)
#define E0_CURRENT 800
#define E0_MICROSTEPS 16
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
#define E0_CURRENT 800
#define E0_MICROSTEPS 16
#define E0_RSENSE 0.11
#define E0_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(E1)
#define E1_CURRENT 800
#define E1_MICROSTEPS 16
#define E1_RSENSE 0.11
#define E1_CHAIN_POS -1
#define E1_CURRENT 800
#define E1_MICROSTEPS 16
#define E1_RSENSE 0.11
#define E1_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(E2)
#define E2_CURRENT 800
#define E2_MICROSTEPS 16
#define E2_RSENSE 0.11
#define E2_CHAIN_POS -1
#define E2_CURRENT 800
#define E2_MICROSTEPS 16
#define E2_RSENSE 0.11
#define E2_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(E3)
#define E3_CURRENT 800
#define E3_MICROSTEPS 16
#define E3_RSENSE 0.11
#define E3_CHAIN_POS -1
#define E3_CURRENT 800
#define E3_MICROSTEPS 16
#define E3_RSENSE 0.11
#define E3_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(E4)
#define E4_CURRENT 800
#define E4_MICROSTEPS 16
#define E4_RSENSE 0.11
#define E4_CHAIN_POS -1
#define E4_CURRENT 800
#define E4_MICROSTEPS 16
#define E4_RSENSE 0.11
#define E4_CHAIN_POS -1
#endif
#if AXIS_IS_TMC(E5)
#define E5_CURRENT 800
#define E5_MICROSTEPS 16
#define E5_RSENSE 0.11
#define E5_CHAIN_POS -1
#define E5_CURRENT 800
#define E5_MICROSTEPS 16
#define E5_RSENSE 0.11
#define E5_CHAIN_POS -1
#endif
/**
@@ -2066,6 +2157,8 @@
*
* IMPROVE_HOMING_RELIABILITY tunes acceleration and jerk when
* homing and adds a guard period for endstop triggering.
*
* TMC2209 requires STEALTHCHOP enabled for SENSORLESS_HOMING
*/
//#define SENSORLESS_HOMING // StallGuard capable drivers only
@@ -2084,6 +2177,7 @@
#define Y_STALL_SENSITIVITY 8
//#define Z_STALL_SENSITIVITY 8
//#define SPI_ENDSTOPS // TMC2130 only
//#define HOME_USING_SPREADCYCLE
//#define IMPROVE_HOMING_RELIABILITY
#endif
@@ -2106,8 +2200,8 @@
*
* Example:
* #define TMC_ADV() { \
* stepperX.diag0_temp_prewarn(1); \
* stepperY.interpolate(0); \
* stepperX.diag0_otpw(1); \
* stepperY.intpol(0); \
* }
*/
#define TMC_ADV() { }
@@ -2571,6 +2665,13 @@
#define HOST_PROMPT_SUPPORT
#endif
/**
* Cancel Objects
*
* Implement M486 to allow Marlin to skip objects
*/
//#define CANCEL_OBJECTS
/**
* I2C position encoders for closed loop control.
* Developed by Chris Barr at Aus3D.
+76
View File
@@ -0,0 +1,76 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
////////////////////////////
// VENDOR VERSION EXAMPLE //
////////////////////////////
/**
* Marlin release version identifier
*/
#define SHORT_BUILD_VERSION "TM3D_X1_04"
/**
* Verbose version identifier which should contain a reference to the location
* from where the binary was downloaded or the source code was compiled.
*/
#define DETAILED_BUILD_VERSION SHORT_BUILD_VERSION " 2.0.x"
/**
* The STRING_DISTRIBUTION_DATE represents when the binary file was built,
* here we define this default string as the date where the latest release
* version was tagged.
*/
#define STRING_DISTRIBUTION_DATE "2019-12-07"
/**
* Defines a generic printer name to be output to the LCD after booting Marlin.
*/
#define MACHINE_NAME "TM3D X1"
/**
* The SOURCE_CODE_URL is the location where users will find the Marlin Source
* Code which is installed on the device. In most cases —unless the manufacturer
* has a distinct Github fork— the Source Code URL should just be the main
* Marlin repository.
*/
//#define SOURCE_CODE_URL "https://github.com/InsanityAutomation/Marlin/tree/ArtilleryX1_2.0_Devel"
/**
* Default generic printer UUID.
*/
//#define DEFAULT_MACHINE_UUID "cede2a2f-41a2-4748-9b12-c55c62f367ff"
/**
* The WEBSITE_URL is the location where users can get more information such as
* documentation about a specific Marlin release.
*/
#define WEBSITE_URL "tinymachines3d.com"
/**
* Set the vendor info the serial USB interface, if changable
* Currently only supported by DUE platform
*/
//#define USB_DEVICE_VENDOR_ID 0x0000
//#define USB_DEVICE_PRODUCT_ID 0x0000
//#define USB_DEVICE_MANUFACTURE_NAME WEBSITE_URL
+2
View File
@@ -25,6 +25,8 @@
#include HAL_PATH(.,HAL.h)
#define HAL_ADC_RANGE _BV(HAL_ADC_RESOLUTION)
inline void watchdog_refresh() {
#if ENABLED(USE_WATCHDOG)
HAL_watchdog_refresh();
+10 -1
View File
@@ -25,7 +25,7 @@
#include "math.h"
#ifdef USBCON
#include "HardwareSerial.h"
#include <HardwareSerial.h>
#else
#define HardwareSerial_h // Hack to prevent HardwareSerial.h header inclusion
#include "MarlinSerial.h"
@@ -38,6 +38,14 @@
#include <avr/interrupt.h>
#include <avr/io.h>
#ifndef pgm_read_ptr
// Compatibility for avr-libc 1.8.0-4.1 included with Ubuntu for
// Windows Subsystem for Linux on Windows 10 as of 10/18/2019
#define pgm_read_ptr_far(address_long) (void*)__ELPM_word((uint32_t)(address_long))
#define pgm_read_ptr_near(address_short) (void*)__LPM_word((uint16_t)(address_short))
#define pgm_read_ptr(address_short) pgm_read_ptr_near(address_short)
#endif
// ------------------------
// Defines
// ------------------------
@@ -357,6 +365,7 @@ inline void HAL_adc_init() {
#define HAL_START_ADC(pin) ADCSRB = 0; SET_ADMUX_ADCSRA(pin)
#endif
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() ADC
#define HAL_ADC_READY() !TEST(ADCSRA, ADSC)
+51 -35
View File
@@ -46,39 +46,55 @@ void endstop_ISR() { endstops.update(); }
/**
* Patch for pins_arduino.h (...\Arduino\hardware\arduino\avr\variants\mega\pins_arduino.h)
*
* These macros for the Arduino MEGA do not include the two connected pins on Port J (D13, D14).
* These macros for the Arduino MEGA do not include the two connected pins on Port J (D14, D15).
* So we extend them here because these are the normal pins for Y_MIN and Y_MAX on RAMPS.
* There are more PCI-enabled processor pins on Port J, but they are not connected to Arduino MEGA.
*/
#if defined(ARDUINO_AVR_MEGA2560) || defined(ARDUINO_AVR_MEGA)
#define digitalPinHasPCICR(p) (WITHIN(p, 10, 15) || WITHIN(p, 50, 53) || WITHIN(p, 62, 69))
#undef digitalPinToPCICR
#define digitalPinToPCICR(p) ( WITHIN(p, 10, 15) || \
WITHIN(p, 50, 53) || \
WITHIN(p, 62, 69) ? &PCICR : nullptr )
#define digitalPinToPCICR(p) (digitalPinHasPCICR(p) ? (&PCICR) : nullptr)
#undef digitalPinToPCICRbit
#define digitalPinToPCICRbit(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \
WITHIN(p, 14, 15) ? 1 : \
WITHIN(p, 62, 69) ? 2 : \
0 )
#define digitalPinToPCICRbit(p) (WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? 0 : \
WITHIN(p, 14, 15) ? 1 : \
WITHIN(p, 62, 69) ? 2 : \
0)
#undef digitalPinToPCMSK
#define digitalPinToPCMSK(p) ( WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? &PCMSK0 : \
WITHIN(p, 14, 15) ? &PCMSK1 : \
WITHIN(p, 62, 69) ? &PCMSK2 : \
nullptr )
#define digitalPinToPCMSK(p) (WITHIN(p, 10, 13) || WITHIN(p, 50, 53) ? (&PCMSK0) : \
WITHIN(p, 14, 15) ? (&PCMSK1) : \
WITHIN(p, 62, 69) ? (&PCMSK2) : \
nullptr)
#undef digitalPinToPCMSKbit
#define digitalPinToPCMSKbit(p) ( WITHIN(p, 10, 13) ? ((p) - 6) : \
(p) == 14 || (p) == 51 ? 2 : \
(p) == 15 || (p) == 52 ? 1 : \
(p) == 50 ? 3 : \
(p) == 53 ? 0 : \
WITHIN(p, 62, 69) ? ((p) - 62) : \
0 )
#define digitalPinToPCMSKbit(p) (WITHIN(p, 10, 13) ? ((p) - 6) : \
(p) == 14 || (p) == 51 ? 2 : \
(p) == 15 || (p) == 52 ? 1 : \
(p) == 50 ? 3 : \
(p) == 53 ? 0 : \
WITHIN(p, 62, 69) ? ((p) - 62) : \
0)
#elif defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__) || defined(__AVR_ATmega324A__) || \
defined(__AVR_ATmega324P__) || defined(__AVR_ATmega324PA__) || defined(__AVR_ATmega324PB__) || \
defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__) || defined(__AVR_ATmega1284__) || \
defined(__AVR_ATmega1284P__)
#define digitalPinHasPCICR(p) WITHIN(p, 0, NUM_DIGITAL_PINS)
#else
#error "Unsupported AVR variant!"
#endif
// Install Pin change interrupt for a pin. Can be called multiple times.
void pciSetup(const int8_t pin) {
if (digitalPinToPCMSK(pin) != nullptr) {
if (digitalPinHasPCICR(pin)) {
SBI(*digitalPinToPCMSK(pin), digitalPinToPCMSKbit(pin)); // enable pin
SBI(PCIFR, digitalPinToPCICRbit(pin)); // clear any outstanding interrupt
SBI(PCICR, digitalPinToPCICRbit(pin)); // enable interrupt for the group
@@ -108,7 +124,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MAX_PIN);
#else
static_assert(digitalPinToPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X_MAX_PIN), "X_MAX_PIN is not interrupt-capable");
pciSetup(X_MAX_PIN);
#endif
#endif
@@ -116,7 +132,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X_MIN_PIN);
#else
static_assert(digitalPinToPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X_MIN_PIN), "X_MIN_PIN is not interrupt-capable");
pciSetup(X_MIN_PIN);
#endif
#endif
@@ -124,7 +140,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MAX_PIN);
#else
static_assert(digitalPinToPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y_MAX_PIN), "Y_MAX_PIN is not interrupt-capable");
pciSetup(Y_MAX_PIN);
#endif
#endif
@@ -132,7 +148,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y_MIN_PIN);
#else
static_assert(digitalPinToPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y_MIN_PIN), "Y_MIN_PIN is not interrupt-capable");
pciSetup(Y_MIN_PIN);
#endif
#endif
@@ -140,7 +156,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MAX_PIN);
#else
static_assert(digitalPinToPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z_MAX_PIN), "Z_MAX_PIN is not interrupt-capable");
pciSetup(Z_MAX_PIN);
#endif
#endif
@@ -148,7 +164,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PIN);
#else
static_assert(digitalPinToPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z_MIN_PIN), "Z_MIN_PIN is not interrupt-capable");
pciSetup(Z_MIN_PIN);
#endif
#endif
@@ -156,7 +172,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MAX_PIN);
#else
static_assert(digitalPinToPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X2_MAX_PIN), "X2_MAX_PIN is not interrupt-capable");
pciSetup(X2_MAX_PIN);
#endif
#endif
@@ -164,7 +180,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(X2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(X2_MIN_PIN);
#else
static_assert(digitalPinToPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(X2_MIN_PIN), "X2_MIN_PIN is not interrupt-capable");
pciSetup(X2_MIN_PIN);
#endif
#endif
@@ -172,7 +188,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MAX_PIN);
#else
static_assert(digitalPinToPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y2_MAX_PIN), "Y2_MAX_PIN is not interrupt-capable");
pciSetup(Y2_MAX_PIN);
#endif
#endif
@@ -180,7 +196,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Y2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Y2_MIN_PIN);
#else
static_assert(digitalPinToPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Y2_MIN_PIN), "Y2_MIN_PIN is not interrupt-capable");
pciSetup(Y2_MIN_PIN);
#endif
#endif
@@ -188,7 +204,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MAX_PIN);
#else
static_assert(digitalPinToPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z2_MAX_PIN), "Z2_MAX_PIN is not interrupt-capable");
pciSetup(Z2_MAX_PIN);
#endif
#endif
@@ -196,7 +212,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z2_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z2_MIN_PIN);
#else
static_assert(digitalPinToPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z2_MIN_PIN), "Z2_MIN_PIN is not interrupt-capable");
pciSetup(Z2_MIN_PIN);
#endif
#endif
@@ -204,7 +220,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MAX_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MAX_PIN);
#else
static_assert(digitalPinToPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z3_MAX_PIN), "Z3_MAX_PIN is not interrupt-capable");
pciSetup(Z3_MAX_PIN);
#endif
#endif
@@ -212,7 +228,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z3_MIN_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z3_MIN_PIN);
#else
static_assert(digitalPinToPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z3_MIN_PIN), "Z3_MIN_PIN is not interrupt-capable");
pciSetup(Z3_MIN_PIN);
#endif
#endif
@@ -220,7 +236,7 @@ void setup_endstop_interrupts() {
#if (digitalPinToInterrupt(Z_MIN_PROBE_PIN) != NOT_AN_INTERRUPT)
_ATTACH(Z_MIN_PROBE_PIN);
#else
static_assert(digitalPinToPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
static_assert(digitalPinHasPCICR(Z_MIN_PROBE_PIN), "Z_MIN_PROBE_PIN is not interrupt-capable");
pciSetup(Z_MIN_PROBE_PIN);
#endif
#endif
+2 -2
View File
@@ -23,7 +23,7 @@
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(FAST_PWM_FAN)
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
#include "HAL.h"
@@ -278,5 +278,5 @@ void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255
}
}
#endif // FAST_PWM_FAN
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
#endif // __AVR__
+29 -11
View File
@@ -38,22 +38,39 @@
#include <stdint.h>
// Serial ports
#if !WITHIN(SERIAL_PORT, -1, 3)
#error "SERIAL_PORT must be from -1 to 3"
// Define MYSERIAL0/1 before MarlinSerial includes!
#if SERIAL_PORT == -1
#define MYSERIAL0 customizedSerial1
#elif SERIAL_PORT == 0
#define MYSERIAL0 Serial
#elif SERIAL_PORT == 1
#define MYSERIAL0 Serial1
#elif SERIAL_PORT == 2
#define MYSERIAL0 Serial2
#elif SERIAL_PORT == 3
#define MYSERIAL0 Serial3
#else
#error "The required SERIAL_PORT must be from -1 to 3. Please update your configuration."
#endif
// MYSERIAL0 required before MarlinSerial includes!
#define MYSERIAL0 customizedSerial1
#ifdef SERIAL_PORT_2
#if !WITHIN(SERIAL_PORT_2, -1, 3)
#error "SERIAL_PORT_2 must be from -1 to 3"
#elif SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different than SERIAL_PORT"
#if SERIAL_PORT_2 == SERIAL_PORT
#error "SERIAL_PORT_2 must be different from SERIAL_PORT. Please update your configuration."
#endif
#if SERIAL_PORT_2 == -1
#define MYSERIAL1 customizedSerial2
#elif SERIAL_PORT_2 == 0
#define MYSERIAL1 Serial
#elif SERIAL_PORT_2 == 1
#define MYSERIAL1 Serial1
#elif SERIAL_PORT_2 == 2
#define MYSERIAL1 Serial2
#elif SERIAL_PORT_2 == 3
#define MYSERIAL1 Serial3
#else
#error "SERIAL_PORT_2 must be from -1 to 3. Please update your configuration."
#endif
#define NUM_SERIAL 2
#define MYSERIAL1 customizedSerial2
#else
#define NUM_SERIAL 1
#endif
@@ -116,6 +133,7 @@ extern uint16_t HAL_adc_result; // result of last ADC conversion
inline void HAL_adc_init() {}//todo
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+2 -2
View File
@@ -444,8 +444,8 @@ typedef struct
#define ENABLE 1
#ifndef __cplusplus
#ifndef __bool_true_false_are_defined
#define false 0
#define true 1
#define false (1==0)
#define true (1==1)
#endif
#endif
#ifndef PASS
+1 -14
View File
@@ -48,9 +48,7 @@
#define _CONF_USB_H_
#undef UNUSED /* To avoid a macro clash as macros.h already defines it */
#include "../../../core/macros.h" /* For ENABLED()/DISABLED() */
#include "../../../core/boards.h" /* For MB() */
#include "../../../../Configuration.h" /* For CUSTOM_MACHINE_NAME definition - We just need the name, no C++ allowed! */
#include "../../../inc/MarlinConfigPre.h"
#include "compiler.h"
/**
@@ -59,8 +57,6 @@
*/
//! Device definition (mandatory)
#define USB_DEVICE_VENDOR_ID 0x03EB /* ATMEL VID */
#define USB_DEVICE_PRODUCT_ID 0x2424 /* MSC / CDC */
#define USB_DEVICE_MAJOR_VERSION 1
#define USB_DEVICE_MINOR_VERSION 0
#define USB_DEVICE_POWER 100 // Consumption on Vbus line (mA)
@@ -70,15 +66,6 @@
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_SELF_POWERED)
// (USB_CONFIG_ATTR_REMOTE_WAKEUP|USB_CONFIG_ATTR_BUS_POWERED)
//! USB Device string definitions (Optional)
#define USB_DEVICE_MANUFACTURE_NAME "marlinfw.org"
#ifdef CUSTOM_MACHINE_NAME
#define USB_DEVICE_PRODUCT_NAME CUSTOM_MACHINE_NAME
#else
#define USB_DEVICE_PRODUCT_NAME "3D Printer"
#endif
#define USB_DEVICE_SERIAL_NAME "123985739853"
/**
* Device speeds support
* Low speed not supported by CDC and MSC
@@ -19,6 +19,9 @@ void sd_mmc_spi_mem_init() {
}
Ctrl_status sd_mmc_spi_test_unit_ready() {
#ifdef DISABLE_DUE_SD_MMC
return CTRL_NO_PRESENT;
#endif
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
return CTRL_NO_PRESENT;
return CTRL_GOOD;
@@ -55,6 +58,9 @@ uint8_t sector_buf[SD_MMC_BLOCK_SIZE];
// #define DEBUG_MMC
Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
#ifdef DISABLE_DUE_SD_MMC
return CTRL_NO_PRESENT;
#endif
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
return CTRL_NO_PRESENT;
@@ -92,6 +98,9 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) {
}
Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) {
#ifdef DISABLE_DUE_SD_MMC
return CTRL_NO_PRESENT;
#endif
if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted())
return CTRL_NO_PRESENT;
+3 -2
View File
@@ -45,11 +45,12 @@
#ifdef ARDUINO_ARCH_SAM
#include "conf_usb.h"
#include "udc.h"
#include <Arduino.h>
#include <Reset.h>
#include "conf_usb.h"
#include "udc.h"
#if ENABLED(SDSUPPORT)
static volatile bool main_b_msc_enable = false;
#endif
+7 -5
View File
@@ -187,19 +187,21 @@ void HAL_adc_start_conversion(uint8_t adc_pin) {
const adc1_channel_t chan = get_channel(adc_pin);
uint32_t mv;
esp_adc_cal_get_voltage((adc_channel_t)chan, &characteristics[attenuations[chan]], &mv);
HAL_adc_result = mv * 1023.0 / 3300.0;
// Change the attenuation level based on the new reading
adc_atten_t atten;
if (mv < thresholds[ADC_ATTEN_DB_0] - 100)
adc1_set_attenuation(chan, ADC_ATTEN_DB_0);
atten = ADC_ATTEN_DB_0;
else if (mv > thresholds[ADC_ATTEN_DB_0] - 50 && mv < thresholds[ADC_ATTEN_DB_2_5] - 100)
adc1_set_attenuation(chan, ADC_ATTEN_DB_2_5);
atten = ADC_ATTEN_DB_2_5;
else if (mv > thresholds[ADC_ATTEN_DB_2_5] - 50 && mv < thresholds[ADC_ATTEN_DB_6] - 100)
adc1_set_attenuation(chan, ADC_ATTEN_DB_6);
atten = ADC_ATTEN_DB_6;
else if (mv > thresholds[ADC_ATTEN_DB_6] - 50)
adc1_set_attenuation(chan, ADC_ATTEN_DB_11);
atten = ADC_ATTEN_DB_11;
else return;
HAL_adc_result = mv * 1023.0 / 3300.0;
adc1_set_attenuation(chan, atten);
}
void analogWrite(pin_t pin, int value) {
+1
View File
@@ -111,6 +111,7 @@ void eeprom_update_block (const void *__src, void *__dst, size_t __n);
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+1 -1
View File
@@ -23,7 +23,7 @@
#include "../../inc/MarlinConfig.h"
#include "Stream.h"
#include <Stream.h>
#ifndef RX_BUFFER_SIZE
#define RX_BUFFER_SIZE 128
+4 -4
View File
@@ -26,10 +26,10 @@
#include "i2s.h"
#include "../shared/Marduino.h"
#include "driver/periph_ctrl.h"
#include "rom/lldesc.h"
#include "soc/i2s_struct.h"
#include "freertos/queue.h"
#include <driver/periph_ctrl.h>
#include <rom/lldesc.h>
#include <soc/i2s_struct.h>
#include <freertos/queue.h>
#include "../../module/stepper.h"
#define DMA_BUF_COUNT 8 // number of DMA buffers to store data
+1 -1
View File
@@ -27,7 +27,7 @@
#include <ESPmDNS.h>
#include <WiFiUdp.h>
#include <ArduinoOTA.h>
#include "driver/timer.h"
#include <driver/timer.h>
void OTA_init() {
ArduinoOTA
+4 -4
View File
@@ -23,10 +23,10 @@
#ifdef ARDUINO_ARCH_ESP32
#include <stdio.h>
#include "esp_types.h"
#include "soc/timer_group_struct.h"
#include "driver/periph_ctrl.h"
#include "driver/timer.h"
#include <esp_types.h>
#include <soc/timer_group_struct.h>
#include <driver/periph_ctrl.h>
#include <driver/timer.h>
#include "HAL.h"
+3 -3
View File
@@ -22,7 +22,7 @@
#pragma once
#include <stdint.h>
#include "driver/timer.h"
#include <driver/timer.h>
// Includes needed to get I2S_STEPPER_STREAM. Note that pins.h
// is included in case this header is being included early.
@@ -51,8 +51,8 @@ typedef uint64_t hal_timer_t;
#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
#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 STEP_TIMER_MIN_INTERVAL 8 // minimum time in µs between stepper interrupts
+1
View File
@@ -89,6 +89,7 @@ int freeMemory();
// ADC
#define HAL_ANALOG_SELECT(pin) HAL_adc_enable_channel(pin)
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
+3 -1
View File
@@ -30,6 +30,8 @@
#include "watchdog.h"
#endif
uint32_t HAL_adc_reading = 0;
// U8glib required functions
extern "C" void u8g_xMicroDelay(uint16_t val) {
DELAY_US(val);
@@ -61,7 +63,7 @@ int freeMemory() {
// 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) ? GET_PIN_MAP_INDEX((port << 5) | pin) : -2;
const int16_t ind = (port < ((NUM_DIGITAL_PINS) >> 5) && pin < 32) ? ((port << 5) | pin) : -2;
return ind > -1 ? ind : dval;
}
+35 -4
View File
@@ -131,12 +131,43 @@ int freeMemory();
// 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_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
using FilteredADC = LPC176x::ADC<ADC_LOWPASS_K_VALUE, ADC_MEDIAN_FILTER_SIZE>;
#define HAL_adc_init() FilteredADC::init()
extern uint32_t HAL_adc_reading;
[[gnu::always_inline]] inline void HAL_start_adc(const pin_t pin) {
HAL_adc_reading = FilteredADC::read(pin) >> (16 - HAL_ADC_RESOLUTION); // returns 16bit value, reduce to required bits
}
[[gnu::always_inline]] inline uint16_t HAL_read_adc() {
return HAL_adc_reading;
}
#define HAL_adc_init()
#define HAL_ANALOG_SELECT(pin) FilteredADC::enable_channel(pin)
#define HAL_START_ADC(pin) FilteredADC::start_conversion(pin)
#define HAL_READ_ADC() FilteredADC::get_result()
#define HAL_ADC_READY() FilteredADC::finished_conversion()
#define HAL_START_ADC(pin) HAL_start_adc(pin)
#define HAL_READ_ADC() HAL_read_adc()
#define HAL_ADC_READY() (true)
// Test whether the pin is valid
constexpr bool VALID_PIN(const pin_t pin) {
return LPC176x::pin_is_valid(pin);
}
// Get the analog index for a digital pin
constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) {
return (LPC176x::pin_is_valid(pin) && LPC176x::pin_has_adc(pin)) ? pin : -1;
}
// Return the index of a pin number
constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) {
return LPC176x::pin_index(pin);
}
// Get the pin number at the given index
constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) {
return LPC176x::pin_index(index);
}
// Parse a G-code word into a pin index
int16_t PARSED_PIN_INDEX(const char code, const int16_t dval);
+7 -7
View File
@@ -56,7 +56,7 @@
// ------------------------
#if ENABLED(LPC_SOFTWARE_SPI)
#include "SoftwareSPI.h"
#include <SoftwareSPI.h>
// Software SPI
@@ -125,18 +125,18 @@
PinCfg.Funcnum = 2;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = LPC1768_PIN_PIN(SCK_PIN);
PinCfg.Portnum = LPC1768_PIN_PORT(SCK_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(SCK_PIN);
PinCfg.Portnum = LPC176x::pin_port(SCK_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(SCK_PIN);
PinCfg.Pinnum = LPC1768_PIN_PIN(MISO_PIN);
PinCfg.Portnum = LPC1768_PIN_PORT(MISO_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(MISO_PIN);
PinCfg.Portnum = LPC176x::pin_port(MISO_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_INPUT(MISO_PIN);
PinCfg.Pinnum = LPC1768_PIN_PIN(MOSI_PIN);
PinCfg.Portnum = LPC1768_PIN_PORT(MOSI_PIN);
PinCfg.Pinnum = LPC176x::pin_bit(MOSI_PIN);
PinCfg.Portnum = LPC176x::pin_port(MOSI_PIN);
PINSEL_ConfigPin(&PinCfg);
SET_OUTPUT(MOSI_PIN);
// divide PCLK by 2 for SSP0
@@ -42,6 +42,8 @@ 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."
+4 -4
View File
@@ -24,17 +24,17 @@
#include "../../inc/MarlinConfigPre.h"
#if ENABLED(FAST_PWM_FAN)
#if ENABLED(FAST_PWM_FAN) || SPINDLE_LASER_PWM
#include <pwm.h>
void set_pwm_frequency(const pin_t pin, int f_desired) {
pwm_set_frequency(pin, f_desired);
LPC176x::pwm_set_frequency(pin, f_desired);
}
void set_pwm_duty(const pin_t pin, const uint16_t v, const uint16_t v_size/*=255*/, const bool invert/*=false*/) {
pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
LPC176x::pwm_write_ratio(pin, invert ? 1.0f - (float)v / v_size : (float)v / v_size);
}
#endif // FAST_PWM_FAN
#endif // FAST_PWM_FAN || SPINDLE_LASER_PWM
#endif // TARGET_LPC1768
+10 -10
View File
@@ -37,19 +37,19 @@
#define PWM_PIN(P) true // all pins are PWM capable
#define LPC_PIN(pin) gpio_pin(pin)
#define LPC_GPIO(port) gpio_port(port)
#define LPC_PIN(pin) LPC176x::gpio_pin(pin)
#define LPC_GPIO(port) LPC176x::gpio_port(port)
#define SET_DIR_INPUT(IO) gpio_set_input(IO)
#define SET_DIR_OUTPUT(IO) gpio_set_output(IO)
#define SET_DIR_INPUT(IO) LPC176x::gpio_set_input(IO)
#define SET_DIR_OUTPUT(IO) LPC176x::gpio_set_output(IO)
#define SET_MODE(IO, mode) pinMode(IO, mode)
#define WRITE_PIN_SET(IO) gpio_set(IO)
#define WRITE_PIN_CLR(IO) gpio_clear(IO)
#define WRITE_PIN_SET(IO) LPC176x::gpio_set(IO)
#define WRITE_PIN_CLR(IO) LPC176x::gpio_clear(IO)
#define READ_PIN(IO) gpio_get(IO)
#define WRITE_PIN(IO,V) gpio_set(IO, V)
#define READ_PIN(IO) LPC176x::gpio_get(IO)
#define WRITE_PIN(IO,V) LPC176x::gpio_set(IO, V)
/**
* Magic I/O routines
@@ -81,10 +81,10 @@
#define _PULLDOWN(IO,V) pinMode(IO, (V) ? INPUT_PULLDOWN : INPUT)
/// check if pin is an input
#define _IS_INPUT(IO) (!gpio_get_dir(IO))
#define _IS_INPUT(IO) (!LPC176x::gpio_get_dir(IO))
/// check if pin is an output
#define _IS_OUTPUT(IO) (gpio_get_dir(IO))
#define _IS_OUTPUT(IO) (LPC176x::gpio_get_dir(IO))
/// Read a pin wrapper
#define READ(IO) _READ(IO)
@@ -21,6 +21,42 @@
*/
#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 < 2002
#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 && _CAT(P,_PIN) != 2 && _CAT(P,_PIN) != 3
#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)."
#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.
*/
#if NUM_SERVOS > 0 && ENABLED(FAST_PWM_FAN)
#error "BLTOUCH and Servos are incompatible with FAST_PWM_FAN on LPC176x boards."
#endif
/**
* Test LPC176x-specific configuration values for errors at compile-time.
*/
@@ -46,7 +46,7 @@
#if ENABLED(FLASH_EEPROM_EMULATION)
extern "C" {
#include "lpc17xx_iap.h"
#include <lpc17xx_iap.h>
}
#define SECTOR_START(sector) ((sector < 16) ? (sector * 0x1000) : ((sector - 14) * 0x8000))
+7 -38
View File
@@ -33,52 +33,21 @@
#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("%d.%02d"), LPC1768_PIN_PORT(p), LPC1768_PIN_PIN(p)); SERIAL_ECHO(buffer); }while(0)
#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%d.%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0)
#define MULTI_NAME_PAD 16 // 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
// uses pin index
#ifndef M43_NEVER_TOUCH
#define M43_NEVER_TOUCH(Q) ((Q) == 29 || (Q) == 30 || (Q) == 73) // USB pins
#define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins
#endif
// active ADC function/mode/code values for PINSEL registers
constexpr int8_t ADC_pin_mode(pin_t pin) {
return (LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 2 ? 2 :
LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 3 ? 2 :
LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 23 ? 1 :
LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 24 ? 1 :
LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 25 ? 1 :
LPC1768_PIN_PORT(pin) == 0 && LPC1768_PIN_PIN(pin) == 26 ? 1 :
LPC1768_PIN_PORT(pin) == 1 && LPC1768_PIN_PIN(pin) == 30 ? 3 :
LPC1768_PIN_PORT(pin) == 1 && LPC1768_PIN_PIN(pin) == 31 ? 3 : -1);
}
int8_t get_pin_mode(pin_t pin) {
if (!VALID_PIN(pin)) return -1;
uint8_t pin_port = LPC1768_PIN_PORT(pin);
uint8_t pin_port_pin = LPC1768_PIN_PIN(pin);
//get appropriate PINSEL register
volatile uint32_t * pinsel_reg = (pin_port == 0 && pin_port_pin <= 15) ? &LPC_PINCON->PINSEL0 :
(pin_port == 0) ? &LPC_PINCON->PINSEL1 :
(pin_port == 1 && pin_port_pin <= 15) ? &LPC_PINCON->PINSEL2 :
pin_port == 1 ? &LPC_PINCON->PINSEL3 :
pin_port == 2 ? &LPC_PINCON->PINSEL4 :
pin_port == 3 ? &LPC_PINCON->PINSEL7 : &LPC_PINCON->PINSEL9;
uint8_t pinsel_start_bit = pin_port_pin > 15 ? 2 * (pin_port_pin - 16) : 2 * pin_port_pin;
int8_t pin_mode = (int8_t) ((*pinsel_reg >> pinsel_start_bit) & 0x3);
return pin_mode;
}
bool GET_PINMODE(pin_t pin) {
int8_t pin_mode = get_pin_mode(pin);
if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // found an invalid pin or active analog pin
bool GET_PINMODE(const pin_t pin) {
if (!LPC176x::pin_is_valid(pin) || LPC176x::pin_adc_enabled(pin)) // found an invalid pin or active analog pin
return false;
uint32_t * FIO_reg[5] PROGMEM = {(uint32_t*) 0x2009C000,(uint32_t*) 0x2009C020,(uint32_t*) 0x2009C040,(uint32_t*) 0x2009C060,(uint32_t*) 0x2009C080};
return ((*FIO_reg[LPC1768_PIN_PORT(pin)] >> LPC1768_PIN_PIN(pin) & 1) != 0); //input/output state
return LPC176x::gpio_direction(pin);
}
bool GET_ARRAY_IS_DIGITAL(pin_t pin) {
return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin));
bool GET_ARRAY_IS_DIGITAL(const pin_t pin) {
return (!LPC176x::pin_has_adc(pin) || !LPC176x::pin_adc_enabled(pin));
}
+1 -1
View File
@@ -59,7 +59,7 @@
typedef uint32_t hal_timer_t;
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF
#define HAL_TIMER_RATE ((SystemCoreClock) / 4) // frequency of timers peripherals
#define HAL_TIMER_RATE ((F_CPU) / 4) // frequency of timers peripherals
#define STEP_TIMER_NUM 0 // Timer Index for Stepper
#define TEMP_TIMER_NUM 1 // Timer Index for Temperature
@@ -25,6 +25,8 @@
#ifdef TARGET_LPC1768
extern int millis();
#ifdef __cplusplus
extern "C" {
#endif
@@ -35,6 +37,7 @@
#include "../../../core/millis_t.h"
//////////////////////////////////////////////////////////////////////////////////////
// These two routines are exact copies of the lpc17xx_i2c.c routines. Couldn't link to
@@ -151,14 +154,13 @@ void u8g_i2c_init(uint8_t clock_option) {
u8g_i2c_start(0); // send slave address and write bit
}
volatile extern millis_t _millis;
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
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;
}
@@ -60,7 +60,7 @@
#if ENABLED(U8GLIB_ST7920)
#include <U8glib.h>
#include "SoftwareSPI.h"
#include <SoftwareSPI.h>
#include "../../shared/Delay.h"
#undef SPI_SPEED
@@ -59,7 +59,7 @@
#if HAS_GRAPHICAL_LCD && DISABLED(U8GLIB_ST7920)
#include "SoftwareSPI.h"
#include <SoftwareSPI.h>
#undef SPI_SPEED
#define SPI_SPEED 2 // About 2 MHz
@@ -75,25 +75,25 @@ uint8_t swSpiTransfer_mode_0(uint8_t b, const uint8_t spi_speed, const pin_t sck
for (uint8_t i = 0; i < 8; i++) {
if (spi_speed == 0) {
gpio_set(mosi_pin, !!(b & 0x80));
gpio_set(sck_pin, HIGH);
LPC176x::gpio_set(mosi_pin, !!(b & 0x80));
LPC176x::gpio_set(sck_pin, HIGH);
b <<= 1;
if (miso_pin >= 0 && gpio_get(miso_pin)) b |= 1;
gpio_set(sck_pin, LOW);
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;
for (uint8_t j = 0; j < spi_speed; j++)
gpio_set(mosi_pin, state);
LPC176x::gpio_set(mosi_pin, state);
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
gpio_set(sck_pin, HIGH);
LPC176x::gpio_set(sck_pin, HIGH);
b <<= 1;
if (miso_pin >= 0 && gpio_get(miso_pin)) b |= 1;
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
for (uint8_t j = 0; j < spi_speed; j++)
gpio_set(sck_pin, LOW);
LPC176x::gpio_set(sck_pin, LOW);
}
}
@@ -105,23 +105,23 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck
for (uint8_t i = 0; i < 8; i++) {
const uint8_t state = (b & 0x80) ? HIGH : LOW;
if (spi_speed == 0) {
gpio_set(sck_pin, LOW);
gpio_set(mosi_pin, state);
gpio_set(mosi_pin, state); // need some setup time
gpio_set(sck_pin, HIGH);
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 {
for (uint8_t j = 0; j < spi_speed + (miso_pin >= 0 ? 0 : 1); j++)
gpio_set(sck_pin, LOW);
LPC176x::gpio_set(sck_pin, LOW);
for (uint8_t j = 0; j < spi_speed; j++)
gpio_set(mosi_pin, state);
LPC176x::gpio_set(mosi_pin, state);
for (uint8_t j = 0; j < spi_speed; j++)
gpio_set(sck_pin, HIGH);
LPC176x::gpio_set(sck_pin, HIGH);
}
b <<= 1;
if (miso_pin >= 0 && gpio_get(miso_pin)) b |= 1;
if (miso_pin >= 0 && LPC176x::gpio_get(miso_pin)) b |= 1;
}
return b;
@@ -130,7 +130,7 @@ uint8_t swSpiTransfer_mode_3(uint8_t b, const uint8_t spi_speed, const pin_t sck
static uint8_t SPI_speed = 0;
static void u8g_sw_spi_HAL_LPC1768_shift_out(uint8_t dataPin, uint8_t clockPin, uint8_t val) {
#if ENABLED(FYSETC_MINI_12864)
#if EITHER(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);
@@ -158,10 +158,10 @@ uint8_t u8g_com_HAL_LPC1768_sw_spi_fn(u8g_t *u8g, uint8_t msg, uint8_t arg_val,
break;
case U8G_COM_MSG_CHIP_SELECT:
#if ENABLED(FYSETC_MINI_12864) // LCD SPI is running mode 3 while SD card is running mode 0
if (arg_val) { // SCK idle state needs to be set to the proper idle state before
// the next chip select goes active
u8g_SetPILevel(u8g, U8G_PI_SCK, 1); // Set SCK to mode 3 idle state before CS goes active
#if EITHER(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 {
@@ -31,9 +31,11 @@ try:
#
import subprocess
# typical result (string): 'Drives: C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
driveStr = subprocess.check_output("fsutil fsinfo drives")
driveStr = str(subprocess.check_output("fsutil fsinfo drives"))
# typical result (string): 'C:\ D:\ E:\ F:\ G:\ H:\ I:\ J:\ K:\ L:\ M:\ Y:\ Z:\'
driveStr = driveStr.strip().lstrip('Drives: ')
# driveStr = driveStr.strip().lstrip('Drives: ') <- Doesn't work in other Languages as English. In German is "Drives:" = "Laufwerke:"
FirstFound = driveStr.find(':',0,-1) # Find the first ":" and
driveStr = driveStr[FirstFound + 1 : -1] # truncate to the rest
# typical result (array of stings): ['C:\\', 'D:\\', 'E:\\', 'F:\\',
# 'G:\\', 'H:\\', 'I:\\', 'J:\\', 'K:\\', 'L:\\', 'M:\\', 'Y:\\', 'Z:\\']
drives = driveStr.split()
@@ -44,7 +46,7 @@ try:
for drive in drives:
final_drive_name = drive.strip().rstrip('\\') # typical result (string): 'C:'
try:
volume_info = subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT)
volume_info = str(subprocess.check_output('cmd /C dir ' + final_drive_name, stderr=subprocess.STDOUT))
except Exception as e:
continue
else:
+1 -1
View File
@@ -26,7 +26,7 @@
#if ENABLED(USE_WATCHDOG)
#include "lpc17xx_wdt.h"
#include <lpc17xx_wdt.h>
#include "watchdog.h"
void watchdog_init() {
+5 -3
View File
@@ -22,8 +22,8 @@
#ifdef __SAMD51__
#include "../../inc/MarlinConfig.h"
#include "Adafruit_ZeroDMA.h"
#include "wiring_private.h"
#include <Adafruit_ZeroDMA.h>
#include <wiring_private.h>
// ------------------------
// Local defines
@@ -442,9 +442,11 @@ void HAL_adc_init() {
// Preloaded data (fixed for all ADC instances hence not loaded by DMA)
adc->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_AREFA_Val; // VRefA pin
SYNC(adc->SYNCBUSY.bit.REFCTRL);
adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val;
adc->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val;
SYNC(adc->SYNCBUSY.bit.CTRLB);
adc->SAMPCTRL.bit.SAMPLEN = (6 - 1); // Sampling clocks
adc->AVGCTRL.reg = ADC_AVGCTRL_SAMPLENUM_16 | ADC_AVGCTRL_ADJRES(4); // 16 Accumulated conversions and shift 4 to get oversampled 12 bits result
SYNC(adc->SYNCBUSY.bit.AVGCTRL);
// Registers loaded by DMA
adc->DSEQCTRL.bit.INPUTCTRL = true;
+2
View File
@@ -109,6 +109,8 @@ extern uint16_t HAL_adc_result; // result of last ADC conversion
void HAL_adc_init();
#define HAL_ADC_FILTERED // Disable oversampling done in Marlin as ADC values already filtered in HAL
#define HAL_ADC_RESOLUTION 12
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+1 -1
View File
@@ -99,7 +99,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
SYNC(tc->COUNT32.SYNCBUSY.bit.CTRLB);
// Set compare value
tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = HAL_TIMER_RATE / frequency;
tc->COUNT32.COUNT.reg = tc->COUNT32.CC[0].reg = (HAL_TIMER_RATE) / frequency;
// And start timer
tc->COUNT32.CTRLA.bit.ENABLE = true;
+16 -2
View File
@@ -28,11 +28,21 @@
#include "../../inc/MarlinConfig.h"
#include "../shared/Delay.h"
#if (__cplusplus == 201703L) && defined(__has_include)
#define HAS_SWSERIAL __has_include(<SoftwareSerial.h>)
#else
#define HAS_SWSERIAL HAS_TMC220x
#endif
#if HAS_SWSERIAL
#include "SoftwareSerial.h"
#endif
#if ENABLED(SRAM_EEPROM_EMULATION)
#if STM32F7xx
#include "stm32f7xx_ll_pwr.h"
#include <stm32f7xx_ll_pwr.h>
#elif STM32F4xx
#include "stm32f4xx_ll_pwr.h"
#include <stm32f4xx_ll_pwr.h>
#else
#error "SRAM_EEPROM_EMULATION is currently only supported for STM32F4xx and STM32F7xx"
#endif
@@ -82,6 +92,10 @@ void HAL_init() {
// Wait until backup regulator is initialized
while (!LL_PWR_IsActiveFlag_BRR());
#endif // EEPROM_EMULATED_SRAM
#if HAS_SWSERIAL
SoftwareSerial::setInterruptPriority(SWSERIAL_TIMER_IRQ_PRIO, 0);
#endif
}
void HAL_clear_reset_source() { __HAL_RCC_CLEAR_RESET_FLAGS(); }
+1
View File
@@ -188,6 +188,7 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n);
inline void HAL_adc_init() {}
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+395
View File
@@ -0,0 +1,395 @@
/*
* SoftwareSerial.cpp (formerly NewSoftSerial.cpp)
*
* Multi-instance software serial library for Arduino/Wiring
* -- Interrupt-driven receive and other improvements by ladyada
* (http://ladyada.net)
* -- Tuning, circular buffer, derivation from class Print/Stream,
* multi-instance support, porting to 8MHz processors,
* various optimizations, PROGMEM delay tables, inverse logic and
* direct port writing by Mikal Hart (http://www.arduiniana.org)
* -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
* -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
* -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
* -- STM32 support by Armin van der Togt
*
* 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
*
* The latest version of this library can always be found at
* http://arduiniana.org.
*/
//
// Includes
//
#if defined(ARDUINO_ARCH_STM32) && !defined(STM32GENERIC)
#include "SoftwareSerial.h"
#include "timers.h"
#define OVERSAMPLE 3 // in RX, Timer will generate interruption OVERSAMPLE time during a bit. Thus OVERSAMPLE ticks in a bit. (interrupt not synchonized with edge).
// defined in bit-periods
#define HALFDUPLEX_SWITCH_DELAY 5
// It's best to define TIMER_SERIAL in variant.h. If not defined, we choose one here
// The order is based on (lack of) features and compare channels, we choose the simplest available
// because we only need an update interrupt
#if !defined(TIMER_SERIAL)
#if defined (TIM18_BASE)
#define TIMER_SERIAL TIM18
#elif defined (TIM7_BASE)
#define TIMER_SERIAL TIM7
#elif defined (TIM6_BASE)
#define TIMER_SERIAL TIM6
#elif defined (TIM22_BASE)
#define TIMER_SERIAL TIM22
#elif defined (TIM21_BASE)
#define TIMER_SERIAL TIM21
#elif defined (TIM17_BASE)
#define TIMER_SERIAL TIM17
#elif defined (TIM16_BASE)
#define TIMER_SERIAL TIM16
#elif defined (TIM15_BASE)
#define TIMER_SERIAL TIM15
#elif defined (TIM14_BASE)
#define TIMER_SERIAL TIM14
#elif defined (TIM13_BASE)
#define TIMER_SERIAL TIM13
#elif defined (TIM11_BASE)
#define TIMER_SERIAL TIM11
#elif defined (TIM10_BASE)
#define TIMER_SERIAL TIM10
#elif defined (TIM12_BASE)
#define TIMER_SERIAL TIM12
#elif defined (TIM19_BASE)
#define TIMER_SERIAL TIM19
#elif defined (TIM9_BASE)
#define TIMER_SERIAL TIM9
#elif defined (TIM5_BASE)
#define TIMER_SERIAL TIM5
#elif defined (TIM4_BASE)
#define TIMER_SERIAL TIM4
#elif defined (TIM3_BASE)
#define TIMER_SERIAL TIM3
#elif defined (TIM2_BASE)
#define TIMER_SERIAL TIM2
#elif defined (TIM20_BASE)
#define TIMER_SERIAL TIM20
#elif defined (TIM8_BASE)
#define TIMER_SERIAL TIM8
#elif defined (TIM1_BASE)
#define TIMER_SERIAL TIM1
#else
#error No suitable timer found for SoftwareSerial, define TIMER_SERIAL in variant.h
#endif
#endif
//
// Statics
//
HardwareTimer SoftwareSerial::timer(TIMER_SERIAL);
const IRQn_Type SoftwareSerial::timer_interrupt_number = static_cast<IRQn_Type>(getTimerUpIrq(TIMER_SERIAL));
uint32_t SoftwareSerial::timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TIM_IRQ_PRIO, TIM_IRQ_SUBPRIO);
SoftwareSerial *SoftwareSerial::active_listener = nullptr;
SoftwareSerial *volatile SoftwareSerial::active_out = nullptr;
SoftwareSerial *volatile SoftwareSerial::active_in = nullptr;
int32_t SoftwareSerial::tx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
int32_t volatile SoftwareSerial::rx_tick_cnt = 0; // OVERSAMPLE ticks needed for a bit
uint32_t SoftwareSerial::tx_buffer = 0;
int32_t SoftwareSerial::tx_bit_cnt = 0;
uint32_t SoftwareSerial::rx_buffer = 0;
int32_t SoftwareSerial::rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
uint32_t SoftwareSerial::cur_speed = 0;
void SoftwareSerial::setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority) {
timer_interrupt_priority = NVIC_EncodePriority(NVIC_GetPriorityGrouping(), preemptPriority, subPriority);
}
//
// Private methods
//
void SoftwareSerial::setSpeed(uint32_t speed) {
if (speed != cur_speed) {
timer.pause();
if (speed != 0) {
// Disable the timer
uint32_t clock_rate, cmp_value;
// Get timer clock
clock_rate = timer.getTimerClkFreq();
int pre = 1;
// Calculate prescale an compare value
do {
cmp_value = clock_rate / (speed * OVERSAMPLE);
if (cmp_value >= UINT16_MAX) {
clock_rate /= 2;
pre *= 2;
}
} while (cmp_value >= UINT16_MAX);
timer.setPrescaleFactor(pre);
timer.setOverflow(cmp_value);
timer.setCount(0);
timer.attachInterrupt(&handleInterrupt);
timer.resume();
NVIC_SetPriority(timer_interrupt_number, timer_interrupt_priority);
}
else
timer.detachInterrupt();
cur_speed = speed;
}
}
// This function sets the current object as the "listening"
// one and returns true if it replaces another
bool SoftwareSerial::listen() {
if (active_listener != this) {
// wait for any transmit to complete as we may change speed
while (active_out);
active_listener->stopListening();
rx_tick_cnt = 1; // 1 : next interrupt will decrease rx_tick_cnt to 0 which means RX pin level will be considered.
rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
setSpeed(_speed);
active_listener = this;
if (!_half_duplex) active_in = this;
return true;
}
return false;
}
// Stop listening. Returns true if we were actually listening.
bool SoftwareSerial::stopListening() {
if (active_listener == this) {
// wait for any output to complete
while (active_out);
if (_half_duplex) setRXTX(false);
active_listener = nullptr;
active_in = nullptr;
// turn off ints
setSpeed(0);
return true;
}
return false;
}
inline void SoftwareSerial::setTX() {
if (_inverse_logic)
LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
else
LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
pinMode(_transmitPin, OUTPUT);
}
inline void SoftwareSerial::setRX() {
pinMode(_receivePin, _inverse_logic ? INPUT_PULLDOWN : INPUT_PULLUP); // pullup for normal logic!
}
inline void SoftwareSerial::setRXTX(bool input) {
if (_half_duplex) {
if (input) {
if (active_in != this) {
setRX();
rx_bit_cnt = -1; // rx_bit_cnt = -1 : waiting for start bit
rx_tick_cnt = 2; // 2 : next interrupt will be discarded. 2 interrupts required to consider RX pin level
active_in = this;
}
}
else {
if (active_in == this) {
setTX();
active_in = nullptr;
}
}
}
}
inline void SoftwareSerial::send() {
if (--tx_tick_cnt <= 0) { // if tx_tick_cnt > 0 interrupt is discarded. Only when tx_tick_cnt reaches 0 is TX pin set.
if (tx_bit_cnt++ < 10) { // tx_bit_cnt < 10 transmission is not finished (10 = 1 start +8 bits + 1 stop)
// Send data (including start and stop bits)
if (tx_buffer & 1)
LL_GPIO_SetOutputPin(_transmitPinPort, _transmitPinNumber);
else
LL_GPIO_ResetOutputPin(_transmitPinPort, _transmitPinNumber);
tx_buffer >>= 1;
tx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks to send next bit
}
else { // Transmission finished
tx_tick_cnt = 1;
if (_output_pending) {
active_out = nullptr;
// In half-duplex mode wait HALFDUPLEX_SWITCH_DELAY bit-periods after the byte has
// been transmitted before allowing the switch to RX mode
}
else if (tx_bit_cnt > 10 + OVERSAMPLE * HALFDUPLEX_SWITCH_DELAY) {
if (_half_duplex && active_listener == this) setRXTX(true);
active_out = nullptr;
}
}
}
}
//
// The receive routine called by the interrupt handler
//
inline void SoftwareSerial::recv() {
if (--rx_tick_cnt <= 0) { // if rx_tick_cnt > 0 interrupt is discarded. Only when rx_tick_cnt reaches 0 is RX pin considered
bool inbit = LL_GPIO_IsInputPinSet(_receivePinPort, _receivePinNumber) ^ _inverse_logic;
if (rx_bit_cnt == -1) { // rx_bit_cnt = -1 : waiting for start bit
if (!inbit) {
// got start bit
rx_bit_cnt = 0; // rx_bit_cnt == 0 : start bit received
rx_tick_cnt = OVERSAMPLE + 1; // Wait 1 bit (OVERSAMPLE ticks) + 1 tick in order to sample RX pin in the middle of the edge (and not too close to the edge)
rx_buffer = 0;
}
else
rx_tick_cnt = 1; // Waiting for start bit, but wrong level. Wait for next Interrupt to check RX pin level
}
else if (rx_bit_cnt >= 8) { // rx_bit_cnt >= 8 : waiting for stop bit
if (inbit) {
// Stop-bit read complete. Add to buffer.
uint8_t next = (_receive_buffer_tail + 1) % _SS_MAX_RX_BUFF;
if (next != _receive_buffer_head) {
// save new data in buffer: tail points to byte destination
_receive_buffer[_receive_buffer_tail] = rx_buffer; // save new byte
_receive_buffer_tail = next;
}
else // rx_bit_cnt = x with x = [0..7] correspond to new bit x received
_buffer_overflow = true;
}
// Full trame received. Restart waiting for start bit at next interrupt
rx_tick_cnt = 1;
rx_bit_cnt = -1;
}
else {
// data bits
rx_buffer >>= 1;
if (inbit) rx_buffer |= 0x80;
rx_bit_cnt++; // Prepare for next bit
rx_tick_cnt = OVERSAMPLE; // Wait OVERSAMPLE ticks before sampling next bit
}
}
}
//
// Interrupt handling
//
/* static */
inline void SoftwareSerial::handleInterrupt(HardwareTimer*) {
if (active_in) active_in->recv();
if (active_out) active_out->send();
}
//
// Constructor
//
SoftwareSerial::SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic /* = false */) :
_receivePin(receivePin),
_transmitPin(transmitPin),
_receivePinPort(digitalPinToPort(receivePin)),
_receivePinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(receivePin))),
_transmitPinPort(digitalPinToPort(transmitPin)),
_transmitPinNumber(STM_LL_GPIO_PIN(digitalPinToPinName(transmitPin))),
_speed(0),
_buffer_overflow(false),
_inverse_logic(inverse_logic),
_half_duplex(receivePin == transmitPin),
_output_pending(0),
_receive_buffer_tail(0),
_receive_buffer_head(0)
{
if ((receivePin < NUM_DIGITAL_PINS) || (transmitPin < NUM_DIGITAL_PINS)) {
/* Enable GPIO clock for tx and rx pin*/
set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(transmitPin)));
set_GPIO_Port_Clock(STM_PORT(digitalPinToPinName(receivePin)));
}
else
_Error_Handler("ERROR: invalid pin number\n", -1);
}
//
// Destructor
//
SoftwareSerial::~SoftwareSerial() { end(); }
//
// Public methods
//
void SoftwareSerial::begin(long speed) {
#ifdef FORCE_BAUD_RATE
speed = FORCE_BAUD_RATE;
#endif
_speed = speed;
if (!_half_duplex) {
setTX();
setRX();
listen();
}
else
setTX();
}
void SoftwareSerial::end() {
stopListening();
}
// Read data from buffer
int SoftwareSerial::read() {
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail) return -1;
// Read from "head"
uint8_t d = _receive_buffer[_receive_buffer_head]; // grab next byte
_receive_buffer_head = (_receive_buffer_head + 1) % _SS_MAX_RX_BUFF;
return d;
}
int SoftwareSerial::available() {
return (_receive_buffer_tail + _SS_MAX_RX_BUFF - _receive_buffer_head) % _SS_MAX_RX_BUFF;
}
size_t SoftwareSerial::write(uint8_t b) {
// wait for previous transmit to complete
_output_pending = 1;
while (active_out) { /* nada */ }
// add start and stop bits.
tx_buffer = b << 1 | 0x200;
if (_inverse_logic) tx_buffer = ~tx_buffer;
tx_bit_cnt = 0;
tx_tick_cnt = OVERSAMPLE;
setSpeed(_speed);
if (_half_duplex) setRXTX(false);
_output_pending = 0;
// make us active
active_out = this;
return 1;
}
void SoftwareSerial::flush() {
noInterrupts();
_receive_buffer_head = _receive_buffer_tail = 0;
interrupts();
}
int SoftwareSerial::peek() {
// Empty buffer?
if (_receive_buffer_head == _receive_buffer_tail) return -1;
// Read from "head"
return _receive_buffer[_receive_buffer_head];
}
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+119
View File
@@ -0,0 +1,119 @@
/**
* SoftwareSerial.h (formerly NewSoftSerial.h)
*
* Multi-instance software serial library for Arduino/Wiring
* -- Interrupt-driven receive and other improvements by ladyada
* (http://ladyada.net)
* -- Tuning, circular buffer, derivation from class Print/Stream,
* multi-instance support, porting to 8MHz processors,
* various optimizations, PROGMEM delay tables, inverse logic and
* direct port writing by Mikal Hart (http://www.arduiniana.org)
* -- Pin change interrupt macros by Paul Stoffregen (http://www.pjrc.com)
* -- 20MHz processor support by Garrett Mace (http://www.macetech.com)
* -- ATmega1280/2560 support by Brett Hagman (http://www.roguerobotics.com/)
*
* 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
*
* The latest version of this library can always be found at
* http://arduiniana.org.
*/
#ifndef SOFTWARESERIAL_H
#define SOFTWARESERIAL_H
#include <Arduino.h>
/******************************************************************************
* Definitions
******************************************************************************/
#define _SS_MAX_RX_BUFF 64 // RX buffer size
class SoftwareSerial : public Stream {
private:
// per object data
uint16_t _receivePin;
uint16_t _transmitPin;
GPIO_TypeDef *_receivePinPort;
uint32_t _receivePinNumber;
GPIO_TypeDef *_transmitPinPort;
uint32_t _transmitPinNumber;
uint32_t _speed;
uint16_t _buffer_overflow: 1;
uint16_t _inverse_logic: 1;
uint16_t _half_duplex: 1;
uint16_t _output_pending: 1;
unsigned char _receive_buffer[_SS_MAX_RX_BUFF];
volatile uint8_t _receive_buffer_tail;
volatile uint8_t _receive_buffer_head;
uint32_t delta_start = 0;
// static data
static bool initialised;
static HardwareTimer timer;
static const IRQn_Type timer_interrupt_number;
static uint32_t timer_interrupt_priority;
static SoftwareSerial *active_listener;
static SoftwareSerial *volatile active_out;
static SoftwareSerial *volatile active_in;
static int32_t tx_tick_cnt;
static volatile int32_t rx_tick_cnt;
static uint32_t tx_buffer;
static int32_t tx_bit_cnt;
static uint32_t rx_buffer;
static int32_t rx_bit_cnt;
static uint32_t cur_speed;
// private methods
void send();
void recv();
void setTX();
void setRX();
void setSpeed(uint32_t speed);
void setRXTX(bool input);
static void handleInterrupt(HardwareTimer *timer);
public:
// public methods
SoftwareSerial(uint16_t receivePin, uint16_t transmitPin, bool inverse_logic = false);
virtual ~SoftwareSerial();
void begin(long speed);
bool listen();
void end();
bool isListening() { return active_listener == this; }
bool stopListening();
bool overflow() {
bool ret = _buffer_overflow;
if (ret) _buffer_overflow = false;
return ret;
}
int peek();
virtual size_t write(uint8_t byte);
virtual int read();
virtual int available();
virtual void flush();
operator bool() { return true; }
static void setInterruptPriority(uint32_t preemptPriority, uint32_t subPriority);
using Print::write;
};
#endif // SOFTWARESERIAL_H
+73 -27
View File
@@ -32,62 +32,108 @@
#define NUM_HARDWARE_TIMERS 2
#define __TIMER_DEV(X) TIM##X
#define _TIMER_DEV(X) __TIMER_DEV(X)
#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
// ------------------------
// Private Variables
// ------------------------
stm32_timer_t TimerHandle[NUM_HARDWARE_TIMERS];
HardwareTimer *timer_instance[NUM_HARDWARE_TIMERS] = { NULL };
bool timer_enabled[NUM_HARDWARE_TIMERS] = { false };
// ------------------------
// Public functions
// ------------------------
bool timers_initialized[NUM_HARDWARE_TIMERS] = { false };
// frequency is in Hertz
void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
if (!HAL_timer_initialized(timer_num)) {
switch (timer_num) {
case STEP_TIMER_NUM: // STEPPER TIMER - use a 32bit timer if possible
timer_instance[timer_num] = new HardwareTimer(STEP_TIMER_DEV);
/* Set the prescaler to the final desired value.
* This will change the effective ISR callback frequency but when
* HAL_timer_start(timer_num=0) is called in the core for the first time
* the real frequency isn't important as long as, after boot, the ISR
* gets called with the correct prescaler and count register. So here
* we set the prescaler to the correct, final value and ignore the frequency
* asked. We will call back the ISR in 1 second to start at full speed.
*
* The proper fix, however, would be a correct initialization OR a
* HAL_timer_change(const uint8_t timer_num, const uint32_t frequency)
* which changes the prescaler when an IRQ frequency change is needed
* (for example when steppers are turned on)
*/
timer_instance[timer_num]->setPrescaleFactor(STEPPER_TIMER_PRESCALE); //the -1 is done internally
timer_instance[timer_num]->setOverflow(_MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (HAL_TIMER_RATE) / (STEPPER_TIMER_PRESCALE) /* /frequency */), TICK_FORMAT);
break;
case TEMP_TIMER_NUM: // TEMP TIMER - any available 16bit timer
timer_instance[timer_num] = new HardwareTimer(TEMP_TIMER_DEV);
// The prescale factor is computed automatically for HERTZ_FORMAT
timer_instance[timer_num]->setOverflow(frequency, HERTZ_FORMAT);
break;
}
if (!timers_initialized[timer_num]) {
uint32_t step_prescaler = STEPPER_TIMER_PRESCALE - 1,
temp_prescaler = TEMP_TIMER_PRESCALE - 1;
HAL_timer_enable_interrupt(timer_num);
/*
* Initializes (and unfortunately starts) the timer.
* This is needed to set correct IRQ priority at the moment but causes
* no harm since every call to HAL_timer_start() is actually followed by
* a call to HAL_timer_enable_interrupt() which means that there isn't
* a case in which you want the timer to run without a callback.
*/
timer_instance[timer_num]->resume(); // First call to resume() MUST follow the attachInterrupt()
// This is fixed in Arduino_Core_STM32 1.8.
// These calls can be removed and replaced with
// timer_instance[timer_num]->setInterruptPriority
switch (timer_num) {
case STEP_TIMER_NUM:
// STEPPER TIMER - use a 32bit timer if possible
TimerHandle[timer_num].timer = STEP_TIMER_DEV;
TimerHandle[timer_num].irqHandle = Step_Handler;
TimerHandleInit(&TimerHandle[timer_num], (((HAL_TIMER_RATE) / step_prescaler) / frequency) - 1, step_prescaler);
HAL_NVIC_SetPriority(STEP_TIMER_IRQ_NAME, STEP_TIMER_IRQ_PRIO, 0);
break;
case TEMP_TIMER_NUM:
// TEMP TIMER - any available 16bit Timer
TimerHandle[timer_num].timer = TEMP_TIMER_DEV;
TimerHandle[timer_num].irqHandle = Temp_Handler;
TimerHandleInit(&TimerHandle[timer_num], (((HAL_TIMER_RATE) / temp_prescaler) / frequency) - 1, temp_prescaler);
HAL_NVIC_SetPriority(TEMP_TIMER_IRQ_NAME, TEMP_TIMER_IRQ_PRIO, 0);
break;
}
timers_initialized[timer_num] = true;
}
}
void HAL_timer_enable_interrupt(const uint8_t timer_num) {
const IRQn_Type IRQ_Id = IRQn_Type(getTimerIrq(TimerHandle[timer_num].timer));
HAL_NVIC_EnableIRQ(IRQ_Id);
if (HAL_timer_initialized(timer_num) && !timer_enabled[timer_num]) {
timer_enabled[timer_num] = true;
switch (timer_num) {
case STEP_TIMER_NUM:
timer_instance[timer_num]->attachInterrupt(Step_Handler);
break;
case TEMP_TIMER_NUM:
timer_instance[timer_num]->attachInterrupt(Temp_Handler);
break;
}
}
}
void HAL_timer_disable_interrupt(const uint8_t timer_num) {
const IRQn_Type IRQ_Id = IRQn_Type(getTimerIrq(TimerHandle[timer_num].timer));
HAL_NVIC_DisableIRQ(IRQ_Id);
// 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();
if (HAL_timer_interrupt_enabled(timer_num)) {
timer_instance[timer_num]->detachInterrupt();
timer_enabled[timer_num] = false;
}
}
bool HAL_timer_interrupt_enabled(const uint8_t timer_num) {
const uint32_t IRQ_Id = getTimerIrq(TimerHandle[timer_num].timer);
return NVIC->ISER[IRQ_Id >> 5] & _BV32(IRQ_Id & 0x1F);
return HAL_timer_initialized(timer_num) && timer_enabled[timer_num];
}
// Only for use within the HAL
TIM_TypeDef * HAL_timer_device(const uint8_t timer_num) {
switch (timer_num) {
case STEP_TIMER_NUM: return STEP_TIMER_DEV;
case TEMP_TIMER_NUM: return TEMP_TIMER_DEV;
}
return nullptr;
}
#endif // ARDUINO_ARCH_STM32 && !STM32GENERIC
+33 -38
View File
@@ -33,6 +33,7 @@
#define hal_timer_t uint32_t
#define HAL_TIMER_TYPE_MAX 0xFFFFFFFF // Timers can be 16 or 32 bit
#ifdef STM32F0xx
#define HAL_TIMER_RATE (F_CPU) // frequency of timer peripherals
@@ -66,27 +67,30 @@
#endif
#ifndef TEMP_TIMER
#define TEMP_TIMER 7
#define TEMP_TIMER 14 // TIM7 is consumed by Software Serial if used.
#endif
#endif
#ifndef SWSERIAL_TIMER_IRQ_PRIO
#define SWSERIAL_TIMER_IRQ_PRIO 1
#endif
#ifndef STEP_TIMER_IRQ_PRIO
#define STEP_TIMER_IRQ_PRIO 1
#define STEP_TIMER_IRQ_PRIO 2
#endif
#ifndef TEMP_TIMER_IRQ_PRIO
#define TEMP_TIMER_IRQ_PRIO 2
#define TEMP_TIMER_IRQ_PRIO 14 //14 = after hardware ISRs
#endif
#define STEP_TIMER_NUM 0 // index of timer to use for stepper
#define TEMP_TIMER_NUM 1 // index of timer to use for temperature
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define TEMP_TIMER_RATE 72000 // 72 Khz
#define TEMP_TIMER_PRESCALE ((HAL_TIMER_RATE)/(TEMP_TIMER_RATE))
#define TEMP_TIMER_FREQUENCY 1000
#define TEMP_TIMER_FREQUENCY 1000 //Temperature::isr() is expected to be called at around 1kHz
//TODO: get rid of manual rate/prescale/ticks/cycles taken for procedures in stepper.cpp
#define STEPPER_TIMER_RATE 2000000 // 2 Mhz
#define STEPPER_TIMER_PRESCALE ((HAL_TIMER_RATE)/(STEPPER_TIMER_RATE))
#define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) // stepper timer ticks per µs
@@ -95,17 +99,6 @@
#define PULSE_TIMER_PRESCALE STEPPER_TIMER_PRESCALE
#define PULSE_TIMER_TICKS_PER_US STEPPER_TIMER_TICKS_PER_US
#define __TIMER_DEV(X) TIM##X
#define _TIMER_DEV(X) __TIMER_DEV(X)
#define STEP_TIMER_DEV _TIMER_DEV(STEP_TIMER)
#define TEMP_TIMER_DEV _TIMER_DEV(TEMP_TIMER)
#define __TIMER_CALLBACK(X) TIM##X##_IRQHandler
#define _TIMER_CALLBACK(X) __TIMER_CALLBACK(X)
#define STEP_TIMER_CALLBACK _TIMER_CALLBACK(STEP_TIMER)
#define TEMP_TIMER_CALLBACK _TIMER_CALLBACK(TEMP_TIMER)
#define __TIMER_IRQ_NAME(X) TIM##X##_IRQn
#define _TIMER_IRQ_NAME(X) __TIMER_IRQ_NAME(X)
@@ -119,22 +112,16 @@
#define ENABLE_TEMPERATURE_INTERRUPT() HAL_timer_enable_interrupt(TEMP_TIMER_NUM)
#define DISABLE_TEMPERATURE_INTERRUPT() HAL_timer_disable_interrupt(TEMP_TIMER_NUM)
extern void Step_Handler(stimer_t *htim);
extern void Temp_Handler(stimer_t *htim);
#define HAL_STEP_TIMER_ISR() void Step_Handler(stimer_t *htim)
#define HAL_TEMP_TIMER_ISR() void Temp_Handler(stimer_t *htim)
// ------------------------
// Types
// ------------------------
typedef stimer_t stm32_timer_t;
extern void Step_Handler(HardwareTimer *htim);
extern void Temp_Handler(HardwareTimer *htim);
#define HAL_STEP_TIMER_ISR() void Step_Handler(HardwareTimer *htim)
#define HAL_TEMP_TIMER_ISR() void Temp_Handler(HardwareTimer *htim)
// ------------------------
// Public Variables
// ------------------------
extern stm32_timer_t TimerHandle[];
extern HardwareTimer *timer_instance[];
// ------------------------
// Public functions
@@ -145,18 +132,26 @@ void HAL_timer_enable_interrupt(const uint8_t timer_num);
void HAL_timer_disable_interrupt(const uint8_t timer_num);
bool HAL_timer_interrupt_enabled(const uint8_t timer_num);
FORCE_INLINE static uint32_t HAL_timer_get_count(const uint8_t timer_num) {
return __HAL_TIM_GET_COUNTER(&TimerHandle[timer_num].handle);
//TIM_TypeDef* HAL_timer_device(const uint8_t timer_num); no need to be public for now. not public = not used externally
// FORCE_INLINE because these are used in performance-critical situations
FORCE_INLINE bool HAL_timer_initialized(const uint8_t timer_num) {
return timer_instance[timer_num] != NULL;
}
FORCE_INLINE static hal_timer_t HAL_timer_get_count(const uint8_t timer_num) {
return HAL_timer_initialized(timer_num) ? timer_instance[timer_num]->getCount() : 0;
}
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const uint32_t compare) {
__HAL_TIM_SET_AUTORELOAD(&TimerHandle[timer_num].handle, compare);
if (HAL_timer_get_count(timer_num) >= compare)
TimerHandle[timer_num].handle.Instance->EGR |= TIM_EGR_UG; // Generate an immediate update interrupt
}
FORCE_INLINE static hal_timer_t HAL_timer_get_compare(const uint8_t timer_num) {
return __HAL_TIM_GET_AUTORELOAD(&TimerHandle[timer_num].handle);
// NOTE: Method name may be misleading.
// STM32 has an Auto-Reload Register (ARR) as opposed to a "compare" register
FORCE_INLINE static void HAL_timer_set_compare(const uint8_t timer_num, const hal_timer_t overflow) {
if (HAL_timer_initialized(timer_num)) {
timer_instance[timer_num]->setOverflow(overflow + 1, TICK_FORMAT); // Value decremented by setOverflow()
// wiki: "force all registers (Autoreload, prescaler, compare) to be taken into account"
// So, if the new overflow value is less than the count it will trigger a rollover interrupt.
if (overflow < timer_instance[timer_num]->getCount()) // Added 'if' here because reports say it won't boot without it
timer_instance[timer_num]->refresh();
}
}
#define HAL_timer_isr_prologue(TIMER_NUM)
+11 -2
View File
@@ -27,8 +27,8 @@
#ifdef __STM32F1__
#include "HAL.h"
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#include <STM32ADC.h>
@@ -121,6 +121,9 @@ const uint8_t adc_pins[] = {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH_PIN,
#endif
#if ENABLED(ADC_KEYPAD)
ADC_KEYPAD_PIN,
#endif
#if HAS_JOY_ADC_X
JOY_X_PIN,
#endif
@@ -160,6 +163,9 @@ enum TEMP_PINS : char {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
FILWIDTH,
#endif
#if ENABLED(ADC_KEYPAD)
ADC_KEY,
#endif
#if HAS_JOY_ADC_X
JOY_X,
#endif
@@ -272,7 +278,7 @@ extern "C" {
// return free memory between end of heap (or end bss) and whatever is current
/*
#include "wirish/syscalls.c"
#include <wirish/syscalls.c>
//extern caddr_t _sbrk(int incr);
#ifndef CONFIG_HEAP_END
extern char _lm_heap_end;
@@ -352,6 +358,9 @@ void HAL_adc_start_conversion(const uint8_t adc_pin) {
#if ENABLED(FILAMENT_WIDTH_SENSOR)
case FILWIDTH_PIN: pin_index = FILWIDTH; break;
#endif
#if ENABLED(ADC_KEYPAD)
case ADC_KEYPAD_PIN: pin_index = ADC_KEY; break;
#endif
}
HAL_adc_result = (HAL_adc_results[(int)pin_index] >> 2) & 0x3FF; // shift to get 10 bits only.
}
+9
View File
@@ -51,6 +51,14 @@
// Defines
// ------------------------
#ifndef STM32_FLASH_SIZE
#ifdef MCU_STM32F103RE
#define STM32_FLASH_SIZE 512
#else
#define STM32_FLASH_SIZE 256
#endif
#endif
#ifdef SERIAL_USB
#ifndef USE_USB_COMPOSITE
#define UsbSerial Serial
@@ -238,6 +246,7 @@ void eeprom_update_block(const void *__src, void *__dst, size_t __n);
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+1 -1
View File
@@ -53,7 +53,7 @@ static const spi_pins* dev_to_spi_pins(spi_dev *dev);
static void configure_gpios(spi_dev *dev, bool as_master);
static spi_baud_rate determine_baud_rate(spi_dev *dev, uint32_t freq);
#if (BOARD_NR_SPI >= 3) && !defined(STM32_HIGH_DENSITY)
#if BOARD_NR_SPI >= 3 && !defined(STM32_HIGH_DENSITY)
#error "The SPI library is misconfigured: 3 SPI ports only available on high density STM32 devices"
#endif
+3 -1
View File
@@ -20,7 +20,9 @@
#include <stdint.h>
#define SW_SERIAL_PLACEHOLDER 1
#ifndef HAVE_SW_SERIAL
#define SW_SERIAL_PLACEHOLDER 1
#endif
class SoftwareSerial {
public:
+20 -19
View File
@@ -29,32 +29,33 @@
#include <libmaple/gpio.h>
#define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16))
#define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit))
#define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW)
#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << ((V) ? 0 : 16))
#define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit))
#define _GET_MODE(IO) gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit)
#define _SET_MODE(IO,M) gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M)
#define _SET_OUTPUT(IO) _SET_MODE(IO, GPIO_OUTPUT_PP)
#define _SET_OUTPUT_OD(IO) _SET_MODE(IO, GPIO_OUTPUT_OD)
#define _GET_MODE(IO) gpio_get_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit)
#define _SET_MODE(IO,M) gpio_set_mode(PIN_MAP[IO].gpio_device, PIN_MAP[IO].gpio_bit, M)
#define _SET_OUTPUT(IO) _SET_MODE(IO, GPIO_OUTPUT_PP)
#define _SET_OUTPUT_OD(IO) _SET_MODE(IO, GPIO_OUTPUT_OD)
#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
#define OUT_WRITE_OD(IO,V) do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0)
#define OUT_WRITE(IO,V) do{ _SET_OUTPUT(IO); WRITE(IO,V); }while(0)
#define OUT_WRITE_OD(IO,V) do{ _SET_OUTPUT_OD(IO); WRITE(IO,V); }while(0)
#define SET_INPUT(IO) _SET_MODE(IO, GPIO_INPUT_FLOATING)
#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, GPIO_INPUT_PU)
#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
#define SET_PWM(IO) pinMode(IO, PWM) // do{ gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_OUTPUT_PP); timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }while(0)
#define SET_PWM_OD(IO) pinMode(IO, PWM_OPEN_DRAIN)
#define SET_INPUT(IO) _SET_MODE(IO, GPIO_INPUT_FLOATING)
#define SET_INPUT_PULLUP(IO) _SET_MODE(IO, GPIO_INPUT_PU)
#define SET_INPUT_PULLDOWN(IO) _SET_MODE(IO, GPIO_INPUT_PD)
#define SET_OUTPUT(IO) OUT_WRITE(IO, LOW)
#define SET_PWM(IO) pinMode(IO, PWM) // do{ gpio_set_mode(PIN_MAP[pin].gpio_device, PIN_MAP[pin].gpio_bit, GPIO_AF_OUTPUT_PP); timer_set_mode(PIN_MAP[pin].timer_device, PIN_MAP[pin].timer_channel, TIMER_PWM); }while(0)
#define SET_PWM_OD(IO) pinMode(IO, PWM_OPEN_DRAIN)
#define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD)
#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP || _GET_MODE(IO) == GPIO_OUTPUT_OD)
#define IS_INPUT(IO) (_GET_MODE(IO) == GPIO_INPUT_FLOATING || _GET_MODE(IO) == GPIO_INPUT_ANALOG || _GET_MODE(IO) == GPIO_INPUT_PU || _GET_MODE(IO) == GPIO_INPUT_PD)
#define IS_OUTPUT(IO) (_GET_MODE(IO) == GPIO_OUTPUT_PP || _GET_MODE(IO) == GPIO_OUTPUT_OD)
#define PWM_PIN(IO) (PIN_MAP[IO].timer_device != nullptr)
#define PWM_PIN(IO) (PIN_MAP[IO].timer_device != nullptr)
// digitalRead/Write wrappers
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
#define extDigitalRead(IO) digitalRead(IO)
#define extDigitalWrite(IO,V) digitalWrite(IO,V)
//
// Pins Definitions
@@ -36,3 +36,8 @@
#if ENABLED(FAST_PWM_FAN)
#error "FAST_PWM_FAN is not yet implemented for this platform."
#endif
#if !defined(HAVE_SW_SERIAL) && HAS_TMC220x
#warning "With TMC2208/9 consider using SoftwareSerialM with HAVE_SW_SERIAL and appropriate SS_TIMER."
#error "Missing SoftwareSerial implementation."
#endif
+2 -2
View File
@@ -36,8 +36,8 @@
#define SPI_CLOCK_MAX SPI_BAUD_PCLK_DIV_2
#endif
#define CS_LOW() {WRITE(ONBOARD_SD_CS_PIN, LOW);} /* Set OnBoardSPI cs low */
#define CS_HIGH() {WRITE(ONBOARD_SD_CS_PIN, HIGH);} /* Set OnBoardSPI cs high */
#define CS_LOW() WRITE(ONBOARD_SD_CS_PIN, LOW) /* Set OnBoardSPI cs low */
#define CS_HIGH() WRITE(ONBOARD_SD_CS_PIN, HIGH) /* Set OnBoardSPI cs high */
#define FCLK_FAST() ONBOARD_SD_SPI.setClockDivider(SPI_CLOCK_MAX)
#define FCLK_SLOW() ONBOARD_SD_SPI.setClockDivider(SPI_BAUD_PCLK_DIV_256)
@@ -40,53 +40,73 @@
#include <EEPROM.h>
// Store settings in the last two pages
// Flash pages must be erased before writing, so keep track.
bool firstWrite = false;
#define EEPROM_SIZE (EEPROM_PAGE_SIZE * 2)
#define ACCESS_FINISHED(TF) do{ FLASH_Lock(); eeprom_dirty = false; return TF; }while(0)
static uint8_t ram_eeprom[EEPROM_SIZE] __attribute__((aligned(4))) = {0};
static bool eeprom_dirty = false;
bool PersistentStore::access_start() {
firstWrite = true;
const uint32_t* source = reinterpret_cast<const uint32_t*>(EEPROM_PAGE0_BASE);
uint32_t* destination = reinterpret_cast<uint32_t*>(ram_eeprom);
static_assert(0 == EEPROM_SIZE % 4, "EEPROM_SIZE is corrupted. (Must be a multiple of 4.)"); // Ensure copying as uint32_t is safe
constexpr size_t eeprom_size_u32 = EEPROM_SIZE / 4;
for (size_t i = 0; i < eeprom_size_u32; ++i, ++destination, ++source)
*destination = *source;
eeprom_dirty = false;
return true;
}
bool PersistentStore::access_finish() {
FLASH_Lock();
firstWrite = false;
if (eeprom_dirty) {
FLASH_Status status;
// Instead of erasing all (both) pages, maybe in the loop we check what page we are in, and if the
// data has changed in that page. We then erase the first time we "detect" a change. In theory, if
// nothing changed in a page, we wouldn't need to erase/write it.
// Or, instead of checking at this point, turn eeprom_dirty into an array of bool the size of number
// of pages. Inside write_data, we set the flag to true at that time if something in that
// page changes...either way, something to look at later.
FLASH_Unlock();
status = FLASH_ErasePage(EEPROM_PAGE0_BASE);
if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
status = FLASH_ErasePage(EEPROM_PAGE1_BASE);
if (status != FLASH_COMPLETE) ACCESS_FINISHED(true);
const uint16_t *source = reinterpret_cast<const uint16_t*>(ram_eeprom);
for (size_t i = 0; i < EEPROM_SIZE; i += 2, ++source) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + i, *source) != FLASH_COMPLETE)
ACCESS_FINISHED(false);
}
ACCESS_FINISHED(true);
}
return true;
}
bool PersistentStore::write_data(int &pos, const uint8_t *value, size_t size, uint16_t *crc) {
FLASH_Status status;
if (firstWrite) {
FLASH_Unlock();
status = FLASH_ErasePage(EEPROM_PAGE0_BASE);
if (status != FLASH_COMPLETE) return true;
status = FLASH_ErasePage(EEPROM_PAGE1_BASE);
if (status != FLASH_COMPLETE) return true;
firstWrite = false;
}
for (size_t i = 0; i < size; i++) {
if (FLASH_ProgramHalfWord(EEPROM_PAGE0_BASE + (pos + i) * 2, value[i]) != FLASH_COMPLETE)
return true;
}
for (size_t i = 0; i < size; ++i) ram_eeprom[pos + i] = value[i];
eeprom_dirty = true;
crc16(crc, value, size);
pos += size;
return false;
return false; // return true for any error
}
bool PersistentStore::read_data(int &pos, uint8_t* value, const size_t size, uint16_t *crc, const bool writing/*=true*/) {
for (size_t i = 0; i < size; i++) {
uint8_t v = *(uint16_t *)(EEPROM_PAGE0_BASE + (pos + i) * 2);
if (writing) value[i] = v;
crc16(crc, &v, 1);
}
const uint8_t * const buff = writing ? &value[0] : &ram_eeprom[pos];
if (writing) for (size_t i = 0; i < size; i++) value[i] = ram_eeprom[pos + i];
crc16(crc, buff, size);
pos += size;
return false;
return false; // return true for any error
}
size_t PersistentStore::capacity() { return size_t(E2END + 1); }
size_t PersistentStore::capacity() { return EEPROM_SIZE; }
#endif // EEPROM_SETTINGS && EEPROM FLASH
#endif // __STM32F1__
+4 -4
View File
@@ -26,8 +26,8 @@
#ifdef __STM32F1__
#include "../../inc/MarlinConfig.h"
#include "HAL.h"
#include "timers.h"
// ------------------------
@@ -57,7 +57,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
case 3: irq_num = NVIC_TIMER3; break;
case 4: irq_num = NVIC_TIMER4; break;
case 5: irq_num = NVIC_TIMER5; break;
#if ENABLED(STM32_HIGH_DENSITY)
#ifdef STM32_HIGH_DENSITY
// 6 & 7 are basic timers, avoid them
case 8: irq_num = NVIC_TIMER8_CC; break;
#endif
@@ -82,7 +82,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_prescaler(STEP_TIMER_DEV, (uint16_t)(STEPPER_TIMER_PRESCALE - 1));
timer_set_reload(STEP_TIMER_DEV, 0xFFFF);
timer_oc_set_mode(STEP_TIMER_DEV, STEP_TIMER_CHAN, TIMER_OC_MODE_FROZEN, TIMER_OC_NO_PRELOAD); // no output pin change
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE / frequency)));
timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (STEPPER_TIMER_RATE) / frequency));
timer_no_ARR_preload_ARPE(STEP_TIMER_DEV); // Need to be sure no preload on ARR register
timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler);
nvic_irq_set_priority(irq_num, STEP_TIMER_IRQ_PRIO);
@@ -95,7 +95,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
timer_set_count(TEMP_TIMER_DEV, 0);
timer_set_prescaler(TEMP_TIMER_DEV, (uint16_t)(TEMP_TIMER_PRESCALE - 1));
timer_set_reload(TEMP_TIMER_DEV, 0xFFFF);
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), ((F_CPU / TEMP_TIMER_PRESCALE) / frequency)));
timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, _MIN(hal_timer_t(HAL_TIMER_TYPE_MAX), (F_CPU) / (TEMP_TIMER_PRESCALE) / frequency));
timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler);
nvic_irq_set_priority(irq_num, TEMP_TIMER_IRQ_PRIO);
timer_generate_update(TEMP_TIMER_DEV);
+26 -1
View File
@@ -27,6 +27,7 @@
#include <stdint.h>
#include <libmaple/timer.h>
#include "../../core/boards.h"
// ------------------------
// Defines
@@ -46,6 +47,20 @@ typedef uint16_t hal_timer_t;
#define STEP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
#define TEMP_TIMER_CHAN 1 // Channel of the timer to use for compare and interrupts
/**
* Note: Timers may be used by platforms and libraries
*
* FAN PWMs:
* With FAN_SOFT_PWM disabled the Temperature class uses
* FANx_PIN timers to generate FAN PWM signals.
*
* Speaker:
* When SPEAKER is enabled, one timer is allocated by maple/tone.cpp.
* - If BEEPER_PIN has a timer channel (and USE_PIN_TIMER is
* defined in tone.cpp) it uses the pin's own timer.
* - Otherwise it uses Timer 8 on boards with STM32_HIGH_DENSITY
* or Timer 4 on other boards.
*/
#if defined(MCU_STM32F103CB) || defined(MCU_STM32F103C8)
#define STEP_TIMER_NUM 4 // For C8/CB boards, use timer 4
#else
@@ -54,7 +69,17 @@ typedef uint16_t hal_timer_t;
#define TEMP_TIMER_NUM 2 // index of timer to use for temperature
//#define TEMP_TIMER_NUM 4 // 2->4, Timer 2 for Stepper Current PWM
#define PULSE_TIMER_NUM STEP_TIMER_NUM
#define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH
#if MB(BTT_SKR_MINI_E3_V1_0, BIGTREE_SKR_E3_DIP, BTT_SKR_MINI_E3_V1_2, MKS_ROBIN_LITE)
// SKR Mini E3 boards use PA8 as FAN_PIN, so TIMER 1 is used for Fan PWM.
#ifdef STM32_HIGH_DENSITY
#define SERVO0_TIMER_NUM 8 // tone.cpp uses Timer 4
#else
#define SERVO0_TIMER_NUM 3 // tone.cpp uses Timer 8
#endif
#else
#define SERVO0_TIMER_NUM 1 // SERVO0 or BLTOUCH
#endif
#define STEP_TIMER_IRQ_PRIO 1
#define TEMP_TIMER_IRQ_PRIO 2
+1 -1
View File
@@ -64,7 +64,7 @@ extern "C" {
// return free memory between end of heap (or end bss) and whatever is current
/*
#include "wirish/syscalls.c"
#include <wirish/syscalls.c>
//extern caddr_t _sbrk(int incr);
#ifndef CONFIG_HEAP_END
extern char _lm_heap_end;
+4 -4
View File
@@ -24,16 +24,15 @@
#define CPU_32_BIT
#include "../../inc/MarlinConfigPre.h"
#include "../shared/Marduino.h"
#include "../shared/math_32bit.h"
#include "../shared/HAL_SPI.h"
#include "fastio.h"
#include "watchdog.h"
#include "timers.h"
#include "../../inc/MarlinConfigPre.h"
#include "watchdog.h"
#include <stdint.h>
@@ -208,6 +207,7 @@ void eeprom_update_block (const void *__src, void *__dst, size_t __n);
inline void HAL_adc_init() {}
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_result
#define HAL_ADC_READY() true
+1 -1
View File
@@ -38,7 +38,7 @@
//Error_Handler();
}
else {
#if PIN_EXISTS(LED) && !ENABLED(PINS_DEBUGGING)
#if PIN_EXISTS(LED) && DISABLED(PINS_DEBUGGING)
TOGGLE(LED_PIN); // heartbeat indicator
#endif
}
+1
View File
@@ -109,6 +109,7 @@ extern "C" {
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
+2 -2
View File
@@ -53,7 +53,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM0_SC = 0x00; // Set this to zero before changing the modulus
FTM0_CNT = 0x0000; // Reset the count to zero
FTM0_MOD = 0xFFFF; // max modulus = 65535
FTM0_C0V = FTM0_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value
FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value
FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8
FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
@@ -62,7 +62,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM1_SC = 0x00; // Set this to zero before changing the modulus
FTM1_CNT = 0x0000; // Reset the count to zero
FTM1_MOD = 0xFFFF; // max modulus = 65535
FTM1_C0V = FTM1_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value 65535
FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535
FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4
FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
+1
View File
@@ -115,6 +115,7 @@ extern "C" {
void HAL_adc_init();
#define HAL_START_ADC(pin) HAL_adc_start_conversion(pin)
#define HAL_ADC_RESOLUTION 10
#define HAL_READ_ADC() HAL_adc_get_result()
#define HAL_ADC_READY() true
+2 -2
View File
@@ -54,7 +54,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM0_SC = 0x00; // Set this to zero before changing the modulus
FTM0_CNT = 0x0000; // Reset the count to zero
FTM0_MOD = 0xFFFF; // max modulus = 65535
FTM0_C0V = FTM0_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value
FTM0_C0V = (FTM0_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value
FTM0_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM0_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 8
FTM0_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
@@ -63,7 +63,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) {
FTM1_SC = 0x00; // Set this to zero before changing the modulus
FTM1_CNT = 0x0000; // Reset the count to zero
FTM1_MOD = 0xFFFF; // max modulus = 65535
FTM1_C0V = FTM1_TIMER_RATE / frequency; // Initial FTM Channel 0 compare value 65535
FTM1_C0V = (FTM1_TIMER_RATE) / frequency; // Initial FTM Channel 0 compare value 65535
FTM1_SC = (FTM_SC_CLKS(0b1) & FTM_SC_CLKS_MASK) | (FTM_SC_PS(FTM1_TIMER_PRESCALE_BITS) & FTM_SC_PS_MASK); // Bus clock 60MHz divided by prescaler 4
FTM1_C0SC = FTM_CSC_CHIE | FTM_CSC_MSA | FTM_CSC_ELSA;
break;
+4 -3
View File
@@ -36,14 +36,15 @@
#if __CORTEX_M == 7
// Cortex-M7 can use the cycle counter of the DWT unit
// Cortex-M3 through M7 can use the cycle counter of the DWT unit
// http://www.anthonyvh.com/2017/05/18/cortex_m-cycle_counter/
FORCE_INLINE static void enableCycleCounter() {
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
// Unlock DWT.
DWT->LAR = 0xC5ACCE55;
#if __CORTEX_M == 7
DWT->LAR = 0xC5ACCE55; // Unlock DWT on the M7
#endif
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
@@ -20,10 +20,9 @@
*
*/
#include "backtrace.h"
#if defined(__arm__) || defined(__thumb__)
#include "backtrace.h"
#include "unwinder.h"
#include "unwmemaccess.h"
+93 -82
View File
@@ -110,7 +110,7 @@
#include "feature/I2CPositionEncoder.h"
#endif
#if HAS_TRINAMIC && DISABLED(PS_DEFAULT_OFF)
#if HAS_TRINAMIC && DISABLED(PSU_DEFAULT_OFF)
#include "feature/tmc_util.h"
#endif
@@ -145,6 +145,10 @@
#include "feature/power_loss_recovery.h"
#endif
#if ENABLED(CANCEL_OBJECTS)
#include "feature/cancel_object.h"
#endif
#if HAS_FILAMENT_SENSOR
#include "feature/runout.h"
#endif
@@ -177,6 +181,16 @@
#include "libs/L6470/L6470_Marlin.h"
#endif
const char NUL_STR[] PROGMEM = "",
G28_STR[] PROGMEM = "G28",
M21_STR[] PROGMEM = "M21",
M23_STR[] PROGMEM = "M23 %s",
M24_STR[] PROGMEM = "M24",
SP_X_STR[] PROGMEM = " X",
SP_Y_STR[] PROGMEM = " Y",
SP_Z_STR[] PROGMEM = " Z",
SP_E_STR[] PROGMEM = " E";
bool Running = true;
// For M109 and M190, this flag may be cleared (by M108) to exit the wait loop
@@ -217,10 +231,10 @@ void setup_killpin() {
void setup_powerhold() {
#if HAS_SUICIDE
OUT_WRITE(SUICIDE_PIN, HIGH);
OUT_WRITE(SUICIDE_PIN, !SUICIDE_PIN_INVERTING);
#endif
#if HAS_POWER_SWITCH
#if ENABLED(PS_DEFAULT_OFF)
#if ENABLED(PSU_CONTROL)
#if ENABLED(PSU_DEFAULT_OFF)
powersupply_on = true; PSU_OFF();
#else
powersupply_on = false; PSU_ON();
@@ -276,7 +290,8 @@ void quickstop_stepper() {
}
void enable_e_steppers() {
enable_E0(); enable_E1(); enable_E2(); enable_E3(); enable_E4(); enable_E5();
#define _ENA_E(N) enable_E##N();
REPEAT(E_STEPPERS, _ENA_E)
}
void enable_all_steppers() {
@@ -290,17 +305,14 @@ void enable_all_steppers() {
}
void disable_e_steppers() {
disable_E0(); disable_E1(); disable_E2(); disable_E3(); disable_E4(); disable_E5();
#define _DIS_E(N) disable_E##N();
REPEAT(E_STEPPERS, _DIS_E)
}
void disable_e_stepper(const uint8_t e) {
#define _CASE_DIS_E(N) case N: disable_E##N(); break;
switch (e) {
case 0: disable_E0(); break;
case 1: disable_E1(); break;
case 2: disable_E2(); break;
case 3: disable_E3(); break;
case 4: disable_E4(); break;
case 5: disable_E5(); break;
REPEAT(EXTRUDERS, _CASE_DIS_E)
}
}
@@ -324,7 +336,7 @@ void disable_all_steppers() {
#ifdef ACTION_ON_CANCEL
host_action_cancel();
#endif
kill(PSTR(MSG_ERR_PROBING_FAILED));
kill(GET_TEXT(MSG_LCD_PROBING_FAILED));
#endif
}
@@ -342,20 +354,67 @@ void disable_all_steppers() {
#endif
#if ENABLED(ADVANCED_PAUSE_FEATURE)
#include "feature/pause.h"
#else
constexpr bool did_pause_print = false;
#endif
/**
* Printing is active when the print job timer is running
*/
bool printingIsActive() {
return print_job_timer.isRunning() || IS_SD_PRINTING();
return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING());
}
/**
* Printing is paused according to SD or host indicators
*/
bool printingIsPaused() {
return print_job_timer.isPaused() || IS_SD_PAUSED();
return did_pause_print || print_job_timer.isPaused() || IS_SD_PAUSED();
}
void startOrResumeJob() {
if (!printingIsPaused()) {
#if ENABLED(CANCEL_OBJECTS)
cancelable.reset();
#endif
#if ENABLED(LCD_SHOW_E_TOTAL)
e_move_accumulator = 0;
#endif
#if BOTH(LCD_SET_PROGRESS_MANUALLY, USE_M73_REMAINING_TIME)
ui.reset_remaining_time();
#endif
}
print_job_timer.start();
}
#if ENABLED(SDSUPPORT)
void abortSDPrinting() {
card.stopSDPrint(
#if SD_RESORT
true
#endif
);
queue.clear();
quickstop_stepper();
print_job_timer.stop();
#if DISABLED(SD_ABORT_NO_COOLDOWN)
thermalManager.disable_all_heaters();
#endif
thermalManager.zero_fan_speeds();
wait_for_heatup = false;
#if ENABLED(POWER_LOSS_RECOVERY)
card.removeJobRecoveryFile();
#endif
#ifdef EVENT_GCODE_SD_STOP
queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
#endif
}
#endif
/**
* Manage several activities:
* - Check for Filament Runout
@@ -461,7 +520,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
if (ELAPSED(ms, next_home_key_ms)) {
next_home_key_ms = ms + HOME_DEBOUNCE_DELAY;
LCD_MESSAGEPGM(MSG_AUTO_HOME);
queue.enqueue_now_P(PSTR("G28"));
queue.enqueue_now_P(G28_STR);
}
}
#endif
@@ -493,24 +552,11 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
#else // !SWITCHING_EXTRUDER
bool oldstatus;
switch (active_extruder) {
default: oldstatus = E0_ENABLE_READ(); enable_E0(); break;
#if E_STEPPERS > 1
case 1: oldstatus = E1_ENABLE_READ(); enable_E1(); break;
#if E_STEPPERS > 2
case 2: oldstatus = E2_ENABLE_READ(); enable_E2(); break;
#if E_STEPPERS > 3
case 3: oldstatus = E3_ENABLE_READ(); enable_E3(); break;
#if E_STEPPERS > 4
case 4: oldstatus = E4_ENABLE_READ(); enable_E4(); break;
#if E_STEPPERS > 5
case 5: oldstatus = E5_ENABLE_READ(); enable_E5(); break;
#endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2
#endif // E_STEPPERS > 1
default:
#define _CASE_EN(N) case N: oldstatus = E##N_ENABLE_READ(); enable_E##N(); break;
REPEAT(E_STEPPERS, _CASE_EN);
}
#endif // !SWITCHING_EXTRUDER
#endif
const float olde = current_position.e;
current_position.e += EXTRUDER_RUNOUT_EXTRUDE;
@@ -531,22 +577,8 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
}
#else // !SWITCHING_EXTRUDER
switch (active_extruder) {
case 0: E0_ENABLE_WRITE(oldstatus); break;
#if E_STEPPERS > 1
case 1: E1_ENABLE_WRITE(oldstatus); break;
#if E_STEPPERS > 2
case 2: E2_ENABLE_WRITE(oldstatus); break;
#if E_STEPPERS > 3
case 3: E3_ENABLE_WRITE(oldstatus); break;
#if E_STEPPERS > 4
case 4: E4_ENABLE_WRITE(oldstatus); break;
#if E_STEPPERS > 5
case 5: E5_ENABLE_WRITE(oldstatus); break;
#endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2
#endif // E_STEPPERS > 1
#define _CASE_RESTORE(N) case N: E##N##_ENABLE_WRITE(oldstatus); break;
REPEAT(E_STEPPERS, _CASE_RESTORE);
}
#endif // !SWITCHING_EXTRUDER
@@ -569,7 +601,7 @@ void manage_inactivity(const bool ignore_stepper_queue/*=false*/) {
#endif
#if ENABLED(MONITOR_DRIVER_STATUS)
monitor_tmc_driver();
monitor_tmc_drivers();
#endif
#if ENABLED(MONITOR_L6470_DRIVER_STATUS)
@@ -686,15 +718,16 @@ void idle(
* Kill all activity and lock the machine.
* After this the machine will need to be reset.
*/
void kill(PGM_P const lcd_msg/*=nullptr*/, const bool steppers_off/*=false*/) {
void kill(PGM_P const lcd_error/*=nullptr*/, PGM_P const lcd_component/*=nullptr*/, const bool steppers_off/*=false*/) {
thermalManager.disable_all_heaters();
SERIAL_ERROR_MSG(MSG_ERR_KILLED);
#if HAS_DISPLAY
ui.kill_screen(lcd_msg ?: PSTR(MSG_KILLED));
ui.kill_screen(lcd_error ?: GET_TEXT(MSG_KILLED), lcd_component ?: NUL_STR);
#else
UNUSED(lcd_msg);
UNUSED(lcd_error);
UNUSED(lcd_component);
#endif
#ifdef ACTION_ON_KILL
@@ -720,7 +753,7 @@ void minkill(const bool steppers_off/*=false*/) {
// Power off all steppers (for M112) or just the E steppers
steppers_off ? disable_all_steppers() : disable_e_steppers();
#if HAS_POWER_SWITCH
#if ENABLED(PSU_CONTROL)
PSU_OFF();
#endif
@@ -900,8 +933,6 @@ void setup() {
#endif
ui.init();
ui.reset_status();
#if HAS_SPI_LCD && ENABLED(SHOW_BOOTSCREEN)
ui.show_bootscreen();
#endif
@@ -930,6 +961,8 @@ void setup() {
print_job_timer.init(); // Initial setup of print job timer
ui.reset_status(); // Print startup message after print statistics are loaded
endstops.init(); // Init endstops and pullups
stepper.init(); // Init stepper. This enables interrupts!
@@ -1077,7 +1110,7 @@ void setup() {
host_action_prompt_end();
#endif
#if HAS_TRINAMIC && DISABLED(PS_DEFAULT_OFF)
#if HAS_TRINAMIC && DISABLED(PSU_DEFAULT_OFF)
test_tmc_connection(true, true, true, true);
#endif
@@ -1101,34 +1134,12 @@ void loop() {
idle(); // Do an idle first so boot is slightly faster
#if ENABLED(SDSUPPORT)
card.checkautostart();
if (card.flag.abort_sd_printing) {
card.stopSDPrint(
#if SD_RESORT
true
#endif
);
queue.clear();
quickstop_stepper();
print_job_timer.stop();
#if DISABLED(SD_ABORT_NO_COOLDOWN)
thermalManager.disable_all_heaters();
#endif
thermalManager.zero_fan_speeds();
wait_for_heatup = false;
#if ENABLED(POWER_LOSS_RECOVERY)
card.removeJobRecoveryFile();
#endif
#ifdef EVENT_GCODE_SD_STOP
queue.inject_P(PSTR(EVENT_GCODE_SD_STOP));
#endif
}
#endif // SDSUPPORT
if (card.flag.abort_sd_printing) abortSDPrinting();
#endif
queue.advance();
endstops.event_handler();
}
}
+113 -109
View File
@@ -51,96 +51,96 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
//
#if AXIS_DRIVER_TYPE_X(L6470)
extern L6470 stepperX;
#define X_enable NOOP
#define X_disable stepperX.free()
#define X_enable() NOOP
#define X_disable() stepperX.free()
#elif HAS_X_ENABLE
#define X_enable X_ENABLE_WRITE( X_ENABLE_ON)
#define X_disable X_ENABLE_WRITE(!X_ENABLE_ON)
#define X_enable() X_ENABLE_WRITE( X_ENABLE_ON)
#define X_disable() X_ENABLE_WRITE(!X_ENABLE_ON)
#else
#define X_enable NOOP
#define X_disable NOOP
#define X_enable() NOOP
#define X_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_X2(L6470)
extern L6470 stepperX2;
#define X2_enable NOOP
#define X2_disable stepperX2.free()
#define X2_enable() NOOP
#define X2_disable() stepperX2.free()
#elif HAS_X2_ENABLE
#define X2_enable X2_ENABLE_WRITE( X_ENABLE_ON)
#define X2_disable X2_ENABLE_WRITE(!X_ENABLE_ON)
#define X2_enable() X2_ENABLE_WRITE( X_ENABLE_ON)
#define X2_disable() X2_ENABLE_WRITE(!X_ENABLE_ON)
#else
#define X2_enable NOOP
#define X2_disable NOOP
#define X2_enable() NOOP
#define X2_disable() NOOP
#endif
#define enable_X() do{ X_enable; X2_enable; }while(0)
#define disable_X() do{ X_disable; X2_disable; CBI(axis_known_position, X_AXIS); }while(0)
#define enable_X() do{ X_enable(); X2_enable(); }while(0)
#define disable_X() do{ X_disable(); X2_disable(); CBI(axis_known_position, X_AXIS); }while(0)
#if AXIS_DRIVER_TYPE_Y(L6470)
extern L6470 stepperY;
#define Y_enable NOOP
#define Y_disable stepperY.free()
#define Y_enable() NOOP
#define Y_disable() stepperY.free()
#elif HAS_Y_ENABLE
#define Y_enable Y_ENABLE_WRITE( Y_ENABLE_ON)
#define Y_disable Y_ENABLE_WRITE(!Y_ENABLE_ON)
#define Y_enable() Y_ENABLE_WRITE( Y_ENABLE_ON)
#define Y_disable() Y_ENABLE_WRITE(!Y_ENABLE_ON)
#else
#define Y_enable NOOP
#define Y_disable NOOP
#define Y_enable() NOOP
#define Y_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_Y2(L6470)
extern L6470 stepperY2;
#define Y2_enable NOOP
#define Y2_disable stepperY2.free()
#define Y2_enable() NOOP
#define Y2_disable() stepperY2.free()
#elif HAS_Y2_ENABLE
#define Y2_enable Y2_ENABLE_WRITE( Y_ENABLE_ON)
#define Y2_disable Y2_ENABLE_WRITE(!Y_ENABLE_ON)
#define Y2_enable() Y2_ENABLE_WRITE( Y_ENABLE_ON)
#define Y2_disable() Y2_ENABLE_WRITE(!Y_ENABLE_ON)
#else
#define Y2_enable NOOP
#define Y2_disable NOOP
#define Y2_enable() NOOP
#define Y2_disable() NOOP
#endif
#define enable_Y() do{ Y_enable; Y2_enable; }while(0)
#define disable_Y() do{ Y_disable; Y2_disable; CBI(axis_known_position, Y_AXIS); }while(0)
#define enable_Y() do{ Y_enable(); Y2_enable(); }while(0)
#define disable_Y() do{ Y_disable(); Y2_disable(); CBI(axis_known_position, Y_AXIS); }while(0)
#if AXIS_DRIVER_TYPE_Z(L6470)
extern L6470 stepperZ;
#define Z_enable NOOP
#define Z_disable stepperZ.free()
#define Z_enable() NOOP
#define Z_disable() stepperZ.free()
#elif HAS_Z_ENABLE
#define Z_enable Z_ENABLE_WRITE( Z_ENABLE_ON)
#define Z_disable Z_ENABLE_WRITE(!Z_ENABLE_ON)
#define Z_enable() Z_ENABLE_WRITE( Z_ENABLE_ON)
#define Z_disable() Z_ENABLE_WRITE(!Z_ENABLE_ON)
#else
#define Z_enable NOOP
#define Z_disable NOOP
#define Z_enable() NOOP
#define Z_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_Z2(L6470)
extern L6470 stepperZ2;
#define Z2_enable NOOP
#define Z2_disable stepperZ2.free()
#define Z2_enable() NOOP
#define Z2_disable() stepperZ2.free()
#elif HAS_Z2_ENABLE
#define Z2_enable Z2_ENABLE_WRITE( Z_ENABLE_ON)
#define Z2_disable Z2_ENABLE_WRITE(!Z_ENABLE_ON)
#define Z2_enable() Z2_ENABLE_WRITE( Z_ENABLE_ON)
#define Z2_disable() Z2_ENABLE_WRITE(!Z_ENABLE_ON)
#else
#define Z2_enable NOOP
#define Z2_disable NOOP
#define Z2_enable() NOOP
#define Z2_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_Z3(L6470)
extern L6470 stepperZ3;
#define Z3_enable NOOP
#define Z3_disable stepperZ3.free()
#define Z3_enable() NOOP
#define Z3_disable() stepperZ3.free()
#elif HAS_Z3_ENABLE
#define Z3_enable Z3_ENABLE_WRITE( Z_ENABLE_ON)
#define Z3_disable Z3_ENABLE_WRITE(!Z_ENABLE_ON)
#define Z3_enable() Z3_ENABLE_WRITE( Z_ENABLE_ON)
#define Z3_disable() Z3_ENABLE_WRITE(!Z_ENABLE_ON)
#else
#define Z3_enable NOOP
#define Z3_disable NOOP
#define Z3_enable() NOOP
#define Z3_disable() NOOP
#endif
#define enable_Z() do{ Z_enable; Z2_enable; Z3_enable; }while(0)
#define disable_Z() do{ Z_disable; Z2_disable; Z3_disable; CBI(axis_known_position, Z_AXIS); }while(0)
#define enable_Z() do{ Z_enable(); Z2_enable(); Z3_enable(); }while(0)
#define disable_Z() do{ Z_disable(); Z2_disable(); Z3_disable(); CBI(axis_known_position, Z_AXIS); }while(0)
//
// Extruder Stepper enable / disable
@@ -149,74 +149,74 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
// define the individual enables/disables
#if AXIS_DRIVER_TYPE_E0(L6470)
extern L6470 stepperE0;
#define E0_enable NOOP
#define E0_disable do{ stepperE0.free(); CBI(axis_known_position, E_AXIS); }while(0)
#define E0_enable() NOOP
#define E0_disable() do{ stepperE0.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif HAS_E0_ENABLE
#define E0_enable E0_ENABLE_WRITE( E_ENABLE_ON)
#define E0_disable E0_ENABLE_WRITE(!E_ENABLE_ON)
#define E0_enable() E0_ENABLE_WRITE( E_ENABLE_ON)
#define E0_disable() E0_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define E0_enable NOOP
#define E0_disable NOOP
#define E0_enable() NOOP
#define E0_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E1(L6470)
extern L6470 stepperE1;
#define E1_enable NOOP
#define E1_disable do{ stepperE1.free(); CBI(axis_known_position, E_AXIS); }while(0)
#define E1_enable() NOOP
#define E1_disable() do{ stepperE1.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 1 && HAS_E1_ENABLE
#define E1_enable E1_ENABLE_WRITE( E_ENABLE_ON)
#define E1_disable E1_ENABLE_WRITE(!E_ENABLE_ON)
#define E1_enable() E1_ENABLE_WRITE( E_ENABLE_ON)
#define E1_disable() E1_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define E1_enable NOOP
#define E1_disable NOOP
#define E1_enable() NOOP
#define E1_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E2(L6470)
extern L6470 stepperE2;
#define E2_enable NOOP
#define E2_disable do{ stepperE2.free(); CBI(axis_known_position, E_AXIS); }while(0)
#define E2_enable() NOOP
#define E2_disable() do{ stepperE2.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 2 && HAS_E2_ENABLE
#define E2_enable E2_ENABLE_WRITE( E_ENABLE_ON)
#define E2_disable E2_ENABLE_WRITE(!E_ENABLE_ON)
#define E2_enable() E2_ENABLE_WRITE( E_ENABLE_ON)
#define E2_disable() E2_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define E2_enable NOOP
#define E2_disable NOOP
#define E2_enable() NOOP
#define E2_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E3(L6470)
extern L6470 stepperE3;
#define E3_enable NOOP
#define E3_disable do{ stepperE3.free(); CBI(axis_known_position, E_AXIS); }while(0)
#define E3_enable() NOOP
#define E3_disable() do{ stepperE3.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 3 && HAS_E3_ENABLE
#define E3_enable E3_ENABLE_WRITE( E_ENABLE_ON)
#define E3_disable E3_ENABLE_WRITE(!E_ENABLE_ON)
#define E3_enable() E3_ENABLE_WRITE( E_ENABLE_ON)
#define E3_disable() E3_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define E3_enable NOOP
#define E3_disable NOOP
#define E3_enable() NOOP
#define E3_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E4(L6470)
extern L6470 stepperE4;
#define E4_enable NOOP
#define E4_disable do{ stepperE4.free(); CBI(axis_known_position, E_AXIS); }while(0)
#define E4_enable() NOOP
#define E4_disable() do{ stepperE4.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 4 && HAS_E4_ENABLE
#define E4_enable E4_ENABLE_WRITE( E_ENABLE_ON)
#define E4_disable E4_ENABLE_WRITE(!E_ENABLE_ON)
#define E4_enable() E4_ENABLE_WRITE( E_ENABLE_ON)
#define E4_disable() E4_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define E4_enable NOOP
#define E4_disable NOOP
#define E4_enable() NOOP
#define E4_disable() NOOP
#endif
#if AXIS_DRIVER_TYPE_E5(L6470)
extern L6470 stepperE5;
#define E5_enable NOOP
#define E5_disable do{ stepperE5.free(); CBI(axis_known_position, E_AXIS); }while(0)
#define E5_enable() NOOP
#define E5_disable() do{ stepperE5.free(); CBI(axis_known_position, E_AXIS); }while(0)
#elif E_STEPPERS > 5 && HAS_E5_ENABLE
#define E5_enable E5_ENABLE_WRITE( E_ENABLE_ON)
#define E5_disable E5_ENABLE_WRITE(!E_ENABLE_ON)
#define E5_enable() E5_ENABLE_WRITE( E_ENABLE_ON)
#define E5_disable() E5_ENABLE_WRITE(!E_ENABLE_ON)
#else
#define E5_enable NOOP
#define E5_disable NOOP
#define E5_enable() NOOP
#define E5_disable() NOOP
#endif
#if ENABLED(MIXING_EXTRUDER)
@@ -225,20 +225,20 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
* Mixing steppers synchronize their enable (and direction) together
*/
#if MIXING_STEPPERS > 5
#define enable_E0() { E0_enable; E1_enable; E2_enable; E3_enable; E4_enable; E5_enable; }
#define disable_E0() { E0_disable; E1_disable; E2_disable; E3_disable; E4_disable; E5_disable; }
#define enable_E0() { E0_enable(); E1_enable(); E2_enable(); E3_enable(); E4_enable(); E5_enable(); }
#define disable_E0() { E0_disable(); E1_disable(); E2_disable(); E3_disable(); E4_disable(); E5_disable(); }
#elif MIXING_STEPPERS > 4
#define enable_E0() { E0_enable; E1_enable; E2_enable; E3_enable; E4_enable; }
#define disable_E0() { E0_disable; E1_disable; E2_disable; E3_disable; E4_disable; }
#define enable_E0() { E0_enable(); E1_enable(); E2_enable(); E3_enable(); E4_enable(); }
#define disable_E0() { E0_disable(); E1_disable(); E2_disable(); E3_disable(); E4_disable(); }
#elif MIXING_STEPPERS > 3
#define enable_E0() { E0_enable; E1_enable; E2_enable; E3_enable; }
#define disable_E0() { E0_disable; E1_disable; E2_disable; E3_disable; }
#define enable_E0() { E0_enable(); E1_enable(); E2_enable(); E3_enable(); }
#define disable_E0() { E0_disable(); E1_disable(); E2_disable(); E3_disable(); }
#elif MIXING_STEPPERS > 2
#define enable_E0() { E0_enable; E1_enable; E2_enable; }
#define disable_E0() { E0_disable; E1_disable; E2_disable; }
#define enable_E0() { E0_enable(); E1_enable(); E2_enable(); }
#define disable_E0() { E0_disable(); E1_disable(); E2_disable(); }
#else
#define enable_E0() { E0_enable; E1_enable; }
#define disable_E0() { E0_disable; E1_disable; }
#define enable_E0() { E0_enable(); E1_enable(); }
#define disable_E0() { E0_disable(); E1_disable(); }
#endif
#define enable_E1() NOOP
#define disable_E1() NOOP
@@ -254,48 +254,48 @@ void manage_inactivity(const bool ignore_stepper_queue=false);
#else // !MIXING_EXTRUDER
#if HAS_E0_ENABLE
#define enable_E0() E0_enable
#define disable_E0() E0_disable
#define enable_E0() E0_enable()
#define disable_E0() E0_disable()
#else
#define enable_E0() NOOP
#define disable_E0() NOOP
#endif
#if E_STEPPERS > 1 && HAS_E1_ENABLE
#define enable_E1() E1_enable
#define disable_E1() E1_disable
#define enable_E1() E1_enable()
#define disable_E1() E1_disable()
#else
#define enable_E1() NOOP
#define disable_E1() NOOP
#endif
#if E_STEPPERS > 2 && HAS_E2_ENABLE
#define enable_E2() E2_enable
#define disable_E2() E2_disable
#define enable_E2() E2_enable()
#define disable_E2() E2_disable()
#else
#define enable_E2() NOOP
#define disable_E2() NOOP
#endif
#if E_STEPPERS > 3 && HAS_E3_ENABLE
#define enable_E3() E3_enable
#define disable_E3() E3_disable
#define enable_E3() E3_enable()
#define disable_E3() E3_disable()
#else
#define enable_E3() NOOP
#define disable_E3() NOOP
#endif
#if E_STEPPERS > 4 && HAS_E4_ENABLE
#define enable_E4() E4_enable
#define disable_E4() E4_disable
#define enable_E4() E4_enable()
#define disable_E4() E4_disable()
#else
#define enable_E4() NOOP
#define disable_E4() NOOP
#endif
#if E_STEPPERS > 5 && HAS_E5_ENABLE
#define enable_E5() E5_enable
#define disable_E5() E5_disable
#define enable_E5() E5_enable()
#define disable_E5() E5_disable()
#else
#define enable_E5() NOOP
#define disable_E5() NOOP
@@ -322,7 +322,7 @@ void disable_e_stepper(const uint8_t e);
void disable_e_steppers();
void disable_all_steppers();
void kill(PGM_P const lcd_msg=nullptr, const bool steppers_off=false);
void kill(PGM_P const lcd_error=nullptr, PGM_P const lcd_component=nullptr, const bool steppers_off=false);
void minkill(const bool steppers_off=false);
void quickstop_stepper();
@@ -333,6 +333,7 @@ inline bool IsStopped() { return !Running; }
bool printingIsActive();
bool printingIsPaused();
void startOrResumeJob();
extern bool wait_for_heatup;
@@ -351,7 +352,7 @@ extern millis_t max_inactive_time, stepper_inactive_time;
extern uint8_t controllerfan_speed;
#endif
#if HAS_POWER_SWITCH
#if ENABLED(PSU_CONTROL)
extern bool powersupply_on;
#define PSU_PIN_ON() do{ OUT_WRITE(PS_ON_PIN, PSU_ACTIVE_HIGH); powersupply_on = true; }while(0)
#define PSU_PIN_OFF() do{ OUT_WRITE(PS_ON_PIN, !PSU_ACTIVE_HIGH); powersupply_on = false; }while(0)
@@ -368,10 +369,13 @@ bool pin_is_protected(const pin_t pin);
void protected_pin_err();
#if HAS_SUICIDE
inline void suicide() { OUT_WRITE(SUICIDE_PIN, LOW); }
inline void suicide() { OUT_WRITE(SUICIDE_PIN, SUICIDE_PIN_INVERTING); }
#endif
#if ENABLED(G29_RETRY_AND_RECOVER)
void event_probe_recover();
void event_probe_failure();
#endif
extern const char NUL_STR[], G28_STR[], M21_STR[], M23_STR[], M24_STR[],
SP_X_STR[], SP_Y_STR[], SP_Z_STR[], SP_E_STR[];
+18 -6
View File
@@ -21,6 +21,8 @@
*/
#pragma once
#include "macros.h"
#define BOARD_UNKNOWN -1
//
@@ -97,6 +99,8 @@
#define BOARD_OVERLORD 1143 // Overlord/Overlord Pro
#define BOARD_HJC2560C_REV1 1144 // ADIMLab Gantry v1
#define BOARD_HJC2560C_REV2 1145 // ADIMLab Gantry v2
#define BOARD_TANGO 1146 // BIQU Tango V1
#define BOARD_MKS_GEN_L_V2 1147 // MKS GEN L V2
//
// RAMBo and derivatives
@@ -266,14 +270,17 @@
#define BOARD_MKS_ROBIN_NANO 4008 // MKS Robin Nano (STM32F103VET6)
#define BOARD_MKS_ROBIN_LITE 4009 // MKS Robin Lite/Lite2 (STM32F103RCT6)
#define BOARD_BIGTREE_SKR_MINI_V1_1 4010 // BigTreeTech SKR Mini v1.1 (STM32F103RC)
#define BOARD_BIGTREE_SKR_MINI_E3 4011 // BigTreeTech SKR Mini E3 (STM32F103RC)
#define BOARD_BIGTREE_SKR_E3_DIP 4012 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V1_2 4013 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V1_0 4011 // BigTreeTech SKR Mini E3 (STM32F103RC)
#define BOARD_BTT_SKR_MINI_E3_V1_2 4012 // BigTreeTech SKR Mini E3 V1.2 (STM32F103RC)
#define BOARD_BIGTREE_SKR_E3_DIP 4013 // BigTreeTech SKR E3 DIP V1.0 (STM32F103RC / STM32F103RE)
#define BOARD_JGAURORA_A5S_A1 4014 // JGAurora A5S A1 (STM32F103ZET6)
#define BOARD_FYSETC_AIO_II 4015 // FYSETC AIO_II
#define BOARD_FYSETC_CHEETAH 4016 // FYSETC Cheetah
#define BOARD_FYSETC_CHEETAH_V12 4017 // FYSETC Cheetah V1.2
#define BOARD_LONGER3D_LK 4018 // Alfawise U20/U20+/U30 (Longer3D LK1/2) / STM32F103VET6
#define BOARD_GTM32_MINI 4019 // STM32F103VET6 controller
#define BOARD_GTM32_MINI_A30 4020 // STM32F103VET6 controller
#define BOARD_GTM32_REV_B 4021 // STM32F103VET6 controller
//
// ARM Cortex-M4F
@@ -287,7 +294,7 @@
//
#define BOARD_BEAST 4200 // STM32F4xxVxT6 Libmaple-based STM32F4 controller
#define BOARD_STM32F4 4201 // STM32 STM32GENERIC-based STM32F4 controller
#define BOARD_GENERIC_STM32F4 4201 // STM32 STM32GENERIC-based STM32F4 controller
#define BOARD_ARMED 4202 // Arm'ed STM32F4-based controller
#define BOARD_RUMBA32 4203 // RUMBA32 STM32F4-based controller
#define BOARD_BLACK_STM32F407VE 4204 // BLACK_STM32F407VE
@@ -297,6 +304,8 @@
#define BOARD_BIGTREE_BTT002_V1_0 4208 // BigTreeTech BTT002 v1.0 (STM32F407VE)
#define BOARD_LERDGE_K 4209 // Lerdge K (STM32F407ZG)
#define BOARD_LERDGE_X 4210 // Lerdge X (STM32F407VE)
#define BOARD_VAKE403D 4211 // VAkE 403D (STM32F446VET6)
#define BOARD_FYSETC_S6 4212 // FYSETC S6 board
//
// ARM Cortex M7
@@ -308,7 +317,7 @@
//
// Espressif ESP32 WiFi
//
#define BOARD_ESP32 6000
#define BOARD_ESPRESSIF_ESP32 6000
//
// Simulations
@@ -316,4 +325,7 @@
#define BOARD_LINUX_RAMPS 9999
#define MB(board) (defined(BOARD_##board) && MOTHERBOARD==BOARD_##board)
#define _MB_1(B) (defined(BOARD_##B) && MOTHERBOARD==BOARD_##B)
#define MB(V...) DO(MB,||,V)
#define IS_MELZI MB(MELZI, MELZI_CREALITY, MELZI_MAKR3D, MELZI_MALYAN, MELZI_TRONXY)
+31 -20
View File
@@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
//
// Serial aliases for debugging.
@@ -37,9 +36,13 @@
#undef DEBUG_ECHOPGM
#undef DEBUG_ECHOLNPGM
#undef DEBUG_ECHOPAIR
#undef DEBUG_ECHOPAIR_P
#undef DEBUG_ECHOPAIR_F
#undef DEBUG_ECHOPAIR_F_P
#undef DEBUG_ECHOLNPAIR
#undef DEBUG_ECHOLNPAIR_P
#undef DEBUG_ECHOLNPAIR_F
#undef DEBUG_ECHOLNPAIR_F_P
#undef DEBUG_ECHO_MSG
#undef DEBUG_ERROR_MSG
#undef DEBUG_EOL
@@ -58,9 +61,13 @@
#define DEBUG_ECHOPGM SERIAL_ECHOPGM
#define DEBUG_ECHOLNPGM SERIAL_ECHOLNPGM
#define DEBUG_ECHOPAIR SERIAL_ECHOPAIR
#define DEBUG_ECHOPAIR_P SERIAL_ECHOPAIR_P
#define DEBUG_ECHOPAIR_F SERIAL_ECHOPAIR_F
#define DEBUG_ECHOPAIR_F_P SERIAL_ECHOPAIR_F_P
#define DEBUG_ECHOLNPAIR SERIAL_ECHOLNPAIR
#define DEBUG_ECHOLNPAIR_P SERIAL_ECHOLNPAIR_P
#define DEBUG_ECHOLNPAIR_F SERIAL_ECHOLNPAIR_F
#define DEBUG_ECHOLNPAIR_F_P SERIAL_ECHOLNPAIR_F_P
#define DEBUG_ECHO_MSG SERIAL_ECHO_MSG
#define DEBUG_ERROR_MSG SERIAL_ERROR_MSG
#define DEBUG_EOL SERIAL_EOL
@@ -68,25 +75,29 @@
#define DEBUG_XYZ SERIAL_XYZ
#define DEBUG_DELAY(ms) serial_delay(ms)
#else
#define DEBUG_PRINT_P(P) NOOP
#define DEBUG_ECHO_START() NOOP
#define DEBUG_ERROR_START() NOOP
#define DEBUG_CHAR(...) NOOP
#define DEBUG_ECHO(...) NOOP
#define DEBUG_ECHO_F(...) NOOP
#define DEBUG_ECHOLN(...) NOOP
#define DEBUG_ECHOPGM(...) NOOP
#define DEBUG_ECHOLNPGM(...) NOOP
#define DEBUG_ECHOPAIR(...) NOOP
#define DEBUG_ECHOPAIR_F(...) NOOP
#define DEBUG_ECHOLNPAIR(...) NOOP
#define DEBUG_ECHOLNPAIR_F(...) NOOP
#define DEBUG_ECHO_MSG(...) NOOP
#define DEBUG_ERROR_MSG(...) NOOP
#define DEBUG_EOL() NOOP
#define DEBUG_POS(...) NOOP
#define DEBUG_XYZ(...) NOOP
#define DEBUG_DELAY(...) NOOP
#define DEBUG_PRINT_P(P) NOOP
#define DEBUG_ECHO_START() NOOP
#define DEBUG_ERROR_START() NOOP
#define DEBUG_CHAR(...) NOOP
#define DEBUG_ECHO(...) NOOP
#define DEBUG_ECHO_F(...) NOOP
#define DEBUG_ECHOLN(...) NOOP
#define DEBUG_ECHOPGM(...) NOOP
#define DEBUG_ECHOLNPGM(...) NOOP
#define DEBUG_ECHOPAIR(...) NOOP
#define DEBUG_ECHOPAIR_P(...) NOOP
#define DEBUG_ECHOPAIR_F(...) NOOP
#define DEBUG_ECHOPAIR_F_P(...) NOOP
#define DEBUG_ECHOLNPAIR(...) NOOP
#define DEBUG_ECHOLNPAIR_P(...) NOOP
#define DEBUG_ECHOLNPAIR_F(...) NOOP
#define DEBUG_ECHOLNPAIR_F_P(...) NOOP
#define DEBUG_ECHO_MSG(...) NOOP
#define DEBUG_ERROR_MSG(...) NOOP
#define DEBUG_EOL() NOOP
#define DEBUG_POS(...) NOOP
#define DEBUG_XYZ(...) NOOP
#define DEBUG_DELAY(...) NOOP
#endif
#undef DEBUG_OUT
+13
View File
@@ -121,6 +121,19 @@
|| AXIS_DRIVER_TYPE(A,TMC5130) \
|| AXIS_DRIVER_TYPE(A,TMC5160) )
#define HAS_TMC_E_DRIVER ( HAS_E_DRIVER(TMC2130) \
|| HAS_E_DRIVER(TMC2160) \
|| HAS_E_DRIVER(TMC2660) \
|| HAS_E_DRIVER(TMC2209) \
|| HAS_E_DRIVER(TMC5130) \
|| HAS_E_DRIVER(TMC5160) )
#define HAS_TMC_STANDALONE_E_DRIVER ( HAS_E_DRIVER(TMC2130_STANDALONE) \
|| HAS_E_DRIVER(TMC2160_STANDALONE) \
|| HAS_E_DRIVER(TMC2660_STANDALONE) \
|| HAS_E_DRIVER(TMC2209_STANDALONE) \
|| HAS_E_DRIVER(TMC5130_STANDALONE) \
|| HAS_E_DRIVER(TMC5160_STANDALONE) )
//
// Stretching 'drivers.h' to include LPC/SAMD51 SD options
//
+40 -32
View File
@@ -49,7 +49,7 @@
// da Danish
// de German
// el Greek
// el-gr Greek (Greece)
// el_gr Greek (Greece)
// en English
// es Spanish
// eu Basque-Euskera
@@ -58,12 +58,12 @@
// gl Galician
// hr Croatian
// it Italian
// jp-kana Japanese
// jp_kana Japanese
// ko_KR Korean (South Korea)
// nl Dutch
// pl Polish
// pt Portuguese
// pt-br Portuguese (Brazilian)
// pt_br Portuguese (Brazilian)
// ru Russian
// sk Slovak
// tr Turkish
@@ -97,7 +97,20 @@
// #define STRING_SPLASH_LINE3 WEBSITE_URL
//#endif
#if HAS_GRAPHICAL_LCD
#if HAS_CHARACTER_LCD
// Custom characters defined in the first 8 characters of the LCD
#define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string!
#define LCD_STR_DEGREE "\x01"
#define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation
#define LCD_STR_UPLEVEL "\x03"
#define LCD_STR_REFRESH "\x04"
#define LCD_STR_FOLDER "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_CLOCK "\x07"
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
#else
//
// Custom characters from Marlin_symbols.fon which was merged into ISO10646-0-3.bdf
// \x00 intentionally skipped to avoid problems in strings
@@ -120,19 +133,6 @@
#define LCD_STR_FILAM_DIA "\xF8"
#define LCD_STR_FILAM_MUL "\xA4"
#elif HAS_CHARACTER_LCD
// Custom characters defined in the first 8 characters of the LCD
#define LCD_STR_BEDTEMP "\x00" // Print only as a char. This will have 'unexpected' results when used in a string!
#define LCD_STR_DEGREE "\x01"
#define LCD_STR_THERMOMETER "\x02" // Still used with string concatenation
#define LCD_STR_UPLEVEL "\x03"
#define LCD_STR_REFRESH "\x04"
#define LCD_STR_FOLDER "\x05"
#define LCD_STR_FEEDRATE "\x06"
#define LCD_STR_CLOCK "\x07"
#define LCD_STR_ARROW_RIGHT ">" /* from the default character set */
#endif
// Common LCD messages
@@ -168,7 +168,6 @@
#define MSG_INVALID_E_STEPPER "Invalid E stepper"
#define MSG_E_STEPPER_NOT_SPECIFIED "E stepper not specified"
#define MSG_INVALID_SOLENOID "Invalid solenoid"
#define MSG_ERR_NO_THERMISTORS "No thermistors - no temperature"
#define MSG_M115_REPORT "FIRMWARE_NAME:Marlin " DETAILED_BUILD_VERSION " SOURCE_CODE_URL:" SOURCE_CODE_URL " PROTOCOL_VERSION:" PROTOCOL_VERSION " MACHINE_TYPE:" MACHINE_NAME " EXTRUDER_COUNT:" STRINGIFY(EXTRUDERS) " UUID:" MACHINE_UUID
#define MSG_COUNT_X " Count X:"
#define MSG_COUNT_A " Count A:"
@@ -243,10 +242,9 @@
#define MSG_ERR_COLD_EXTRUDE_STOP " cold extrusion prevented"
#define MSG_ERR_LONG_EXTRUDE_STOP " too long extrusion prevented"
#define MSG_ERR_HOTEND_TOO_COLD "Hotend too cold"
#define MSG_ERR_Z_HOMING_SER "Home XY first"
#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!"
#define MSG_FILAMENT_CHANGE_HEAT "Press button (or M108) to heat nozzle"
#define MSG_FILAMENT_CHANGE_INSERT "Insert filament and press button (or M108)"
#define MSG_FILAMENT_CHANGE_WAIT "Press button (or M108) to resume"
#define MSG_FILAMENT_CHANGE_HEAT_LCD "Press button to heat nozzle"
#define MSG_FILAMENT_CHANGE_INSERT_LCD "Insert filament and press button"
#define MSG_FILAMENT_CHANGE_WAIT_LCD "Press button to resume"
@@ -254,17 +252,15 @@
#define MSG_FILAMENT_CHANGE_INSERT_M108 "Insert filament and send M108"
#define MSG_FILAMENT_CHANGE_WAIT_M108 "Send M108 to resume"
#define MSG_ERR_EEPROM_WRITE "Error writing to EEPROM!"
#define MSG_STOP_BLTOUCH "STOP called because of BLTouch error - restart with M999"
#define MSG_STOP_UNHOMED "STOP called because of unhomed error - restart with M999"
#define MSG_KILL_INACTIVE_TIME "KILL caused by too much inactive time - current command: "
#define MSG_KILL_BUTTON "KILL caused by KILL button/pin"
// temperature.cpp strings
#define MSG_PID_AUTOTUNE "PID Autotune"
#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE " start"
#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE " failed!"
#define MSG_PID_AUTOTUNE_PREFIX "PID Autotune"
#define MSG_PID_AUTOTUNE_START MSG_PID_AUTOTUNE_PREFIX " start"
#define MSG_PID_AUTOTUNE_FAILED MSG_PID_AUTOTUNE_PREFIX " failed!"
#define MSG_PID_BAD_EXTRUDER_NUM MSG_PID_AUTOTUNE_FAILED " Bad extruder number"
#define MSG_PID_TEMP_TOO_HIGH MSG_PID_AUTOTUNE_FAILED " Temperature too high"
#define MSG_PID_TIMEOUT MSG_PID_AUTOTUNE_FAILED " timeout"
@@ -279,7 +275,7 @@
#define MSG_KI " Ki: "
#define MSG_KD " Kd: "
#define MSG_AT " @:"
#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
#define MSG_PID_AUTOTUNE_FINISHED MSG_PID_AUTOTUNE_PREFIX " finished! Put the last Kp, Ki and Kd constants from below into Configuration.h"
#define MSG_PID_DEBUG " PID_DEBUG "
#define MSG_PID_DEBUG_INPUT ": Input "
#define MSG_PID_DEBUG_OUTPUT " Output "
@@ -298,6 +294,8 @@
#define MSG_T_THERMAL_RUNAWAY "Thermal Runaway"
#define MSG_T_MAXTEMP "MAXTEMP triggered"
#define MSG_T_MINTEMP "MINTEMP triggered"
#define MSG_ERR_PROBING_FAILED "Probing Failed"
#define MSG_ZPROBE_OUT_SER "Z Probe Past Bed"
// Debug
#define MSG_DEBUG_PREFIX "DEBUG:"
@@ -313,11 +311,9 @@
#define LANGUAGE_DATA_INCL_(M) STRINGIFY_(fontdata/langdata_##M.h)
#define LANGUAGE_DATA_INCL(M) LANGUAGE_DATA_INCL_(M)
#define INCLUDE_LANGUAGE_DATA LANGUAGE_DATA_INCL(LCD_LANGUAGE)
#define LANGUAGE_INCL_(M) STRINGIFY_(../lcd/language/language_##M.h)
#define LANGUAGE_INCL(M) LANGUAGE_INCL_(M)
#define INCLUDE_LANGUAGE LANGUAGE_INCL(LCD_LANGUAGE)
// Never translate these strings
#define MSG_X "X"
@@ -338,6 +334,11 @@
#define MSG_Z2 "Z2"
#define MSG_Z3 "Z3"
#define LCD_STR_A MSG_A
#define LCD_STR_B MSG_B
#define LCD_STR_C MSG_C
#define LCD_STR_E MSG_E
/**
* Tool indexes for LCD display only
*
@@ -348,6 +349,7 @@
*
*/
#if ENABLED(NUMBER_TOOLS_FROM_0)
#define LCD_FIRST_TOOL '0'
#define LCD_STR_N0 "0"
#define LCD_STR_N1 "1"
#define LCD_STR_N2 "2"
@@ -355,6 +357,7 @@
#define LCD_STR_N4 "4"
#define LCD_STR_N5 "5"
#else
#define LCD_FIRST_TOOL '1'
#define LCD_STR_N0 "1"
#define LCD_STR_N1 "2"
#define LCD_STR_N2 "3"
@@ -370,7 +373,14 @@
#define LCD_STR_E4 "E" LCD_STR_N4
#define LCD_STR_E5 "E" LCD_STR_N5
#include INCLUDE_LANGUAGE
#include "multi_language.h" // Allow multiple languages
#include "../lcd/language/language_en.h"
#include LANGUAGE_INCL(LCD_LANGUAGE)
#include LANGUAGE_INCL(LCD_LANGUAGE_2)
#include LANGUAGE_INCL(LCD_LANGUAGE_3)
#include LANGUAGE_INCL(LCD_LANGUAGE_4)
#include LANGUAGE_INCL(LCD_LANGUAGE_5)
#if NONE(DISPLAY_CHARSET_ISO10646_1, \
DISPLAY_CHARSET_ISO10646_5, \
@@ -383,5 +393,3 @@
DISPLAY_CHARSET_ISO10646_SK)
#define DISPLAY_CHARSET_ISO10646_1 // use the better font on full graphic displays.
#endif
#include "../lcd/language/language_en.h"
+127 -27
View File
@@ -165,6 +165,7 @@
// Macros to support option testing
#define _CAT(a,V...) a##V
#define CAT(a,V...) _CAT(a,V)
#define SWITCH_ENABLED_false 0
#define SWITCH_ENABLED_true 1
#define SWITCH_ENABLED_0 0
@@ -229,32 +230,6 @@
#define _JOIN_1(O) (O)
#define JOIN_N(N,C,V...) (DO(JOIN,C,LIST_N(N,V)))
// Macros for adding
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INCREMENT_(n) INC_##n
#define INCREMENT(n) INCREMENT_(n)
// Macros for subtracting
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DECREMENT_(n) DEC_##n
#define DECREMENT(n) DECREMENT_(n)
#define NOOP (void(0))
#define CEILING(x,y) (((x) + (y) - 1) / (y))
@@ -276,10 +251,11 @@
//
// Maths macros that can be overridden by HAL
//
#define ACOS(x) acosf(x)
#define ATAN2(y, x) atan2f(y, x)
#define POW(x, y) powf(x, y)
#define SQRT(x) sqrtf(x)
#define RSQRT(x) (1 / sqrtf(x))
#define RSQRT(x) (1.0f / sqrtf(x))
#define CEIL(x) ceilf(x)
#define FLOOR(x) floorf(x)
#define LROUND(x) lroundf(x)
@@ -346,3 +322,127 @@
#define _MAX(V...) _MAX_N(NUM_ARGS(V), V)
#endif
// Macros for adding
#define INC_0 1
#define INC_1 2
#define INC_2 3
#define INC_3 4
#define INC_4 5
#define INC_5 6
#define INC_6 7
#define INC_7 8
#define INC_8 9
#define INCREMENT_(n) INC_##n
#define INCREMENT(n) INCREMENT_(n)
#define ADD0(N) N
#define ADD1(N) INCREMENT_(N)
#define ADD2(N) ADD1(ADD1(N))
#define ADD3(N) ADD1(ADD2(N))
#define ADD4(N) ADD2(ADD2(N))
#define ADD5(N) ADD2(ADD3(N))
#define ADD6(N) ADD3(ADD3(N))
#define ADD7(N) ADD3(ADD4(N))
#define ADD8(N) ADD4(ADD4(N))
#define ADD9(N) ADD4(ADD5(N))
#define ADD10(N) ADD5(ADD5(N))
// Macros for subtracting
#define DEC_0 0
#define DEC_1 0
#define DEC_2 1
#define DEC_3 2
#define DEC_4 3
#define DEC_5 4
#define DEC_6 5
#define DEC_7 6
#define DEC_8 7
#define DEC_9 8
#define DECREMENT_(n) DEC_##n
#define DECREMENT(n) DECREMENT_(n)
#define SUB0(N) N
#define SUB1(N) DECREMENT_(N)
#define SUB2(N) SUB1(SUB1(N))
#define SUB3(N) SUB1(SUB2(N))
#define SUB4(N) SUB2(SUB2(N))
#define SUB5(N) SUB2(SUB3(N))
#define SUB6(N) SUB3(SUB3(N))
#define SUB7(N) SUB3(SUB4(N))
#define SUB8(N) SUB4(SUB4(N))
#define SUB9(N) SUB4(SUB5(N))
#define SUB10(N) SUB5(SUB5(N))
//
// Primitives supporting precompiler REPEAT
//
#define FIRST(a,...) a
#define SECOND(a,b,...) b
// Defer expansion
#define EMPTY()
#define DEFER(M) M EMPTY()
#define DEFER2(M) M EMPTY EMPTY()()
#define DEFER3(M) M EMPTY EMPTY EMPTY()()()
#define DEFER4(M) M EMPTY EMPTY EMPTY EMPTY()()()()
// Force define expansion
#define EVAL(V...) EVAL16(V)
#define EVAL1024(V...) EVAL512(EVAL512(V))
#define EVAL512(V...) EVAL256(EVAL256(V))
#define EVAL256(V...) EVAL128(EVAL128(V))
#define EVAL128(V...) EVAL64(EVAL64(V))
#define EVAL64(V...) EVAL32(EVAL32(V))
#define EVAL32(V...) EVAL16(EVAL16(V))
#define EVAL16(V...) EVAL8(EVAL8(V))
#define EVAL8(V...) EVAL4(EVAL4(V))
#define EVAL4(V...) EVAL2(EVAL2(V))
#define EVAL2(V...) EVAL1(EVAL1(V))
#define EVAL1(V...) V
#define IS_PROBE(V...) SECOND(V, 0) // Get the second item passed, or 0
#define PROBE() ~, 1 // Second item will be 1 if this is passed
#define _NOT_0 PROBE()
#define NOT(x) IS_PROBE(_CAT(_NOT_, x)) // NOT('0') gets '1'. Anything else gets '0'.
#define _BOOL(x) NOT(NOT(x)) // NOT('0') gets '0'. Anything else gets '1'.
#define IF_ELSE(TF) _IF_ELSE(_BOOL(TF))
#define _IF_ELSE(TF) _CAT(_IF_, TF)
#define _IF_1(V...) V _IF_1_ELSE
#define _IF_0(...) _IF_0_ELSE
#define _IF_1_ELSE(...)
#define _IF_0_ELSE(V...) V
#define HAS_ARGS(V...) _BOOL(FIRST(_END_OF_ARGUMENTS_ V)())
#define _END_OF_ARGUMENTS_() 0
//
// REPEAT core macros. Recurse N times with ascending I.
//
// Call OP(I) N times with ascending counter.
#define _REPEAT(_RPT_I,_RPT_N,_RPT_OP) \
_RPT_OP(_RPT_I) \
IF_ELSE(SUB1(_RPT_N)) \
( DEFER2(__REPEAT)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP) ) \
( /* Do nothing */ )
#define __REPEAT() _REPEAT
// Call OP(I, ...) N times with ascending counter.
#define _REPEAT2(_RPT_I,_RPT_N,_RPT_OP,V...) \
_RPT_OP(_RPT_I,V) \
IF_ELSE(SUB1(_RPT_N)) \
( DEFER2(__REPEAT2)()(ADD1(_RPT_I),SUB1(_RPT_N),_RPT_OP,V) ) \
( /* Do nothing */ )
#define __REPEAT2() _REPEAT2
// Repeat a macro passing S...N-1.
#define REPEAT_S(S,N,OP) EVAL(_REPEAT(S,SUB##S(N),OP))
#define REPEAT(N,OP) REPEAT_S(0,N,OP)
// Repeat a macro passing 0...N-1 plus additional arguments.
#define REPEAT2_S(S,N,OP,V...) EVAL(_REPEAT2(S,SUB##S(N),OP,V))
#define REPEAT2(N,OP,V...) REPEAT2_S(0,N,OP,V)
View File
@@ -1,6 +1,6 @@
/**************
* language.h *
**************/
/********************
* multi_language.h *
********************/
/****************************************************************************
* Written By Marcio Teixeira 2019 - Aleph Objects, Inc. *
@@ -22,8 +22,6 @@
typedef const char Language_Str[];
// Count how many languages are defined.
#if defined(LCD_LANGUAGE_5)
#define NUM_LANGUAGES 5
#elif defined(LCD_LANGUAGE_4)
@@ -36,15 +34,11 @@ typedef const char Language_Str[];
#define NUM_LANGUAGES 1
#endif
// Set undefined languages equal to the last and
// let the compiler optimize out the duplicates
#ifndef LCD_LANGUAGE_1
#define LCD_LANGUAGE_1 LCD_LANGUAGE
#endif
// Setting the unused languages equal to each other allows
// the compiler to optimize away the conditionals
#ifndef LCD_LANGUAGE_2
#define LCD_LANGUAGE_2 LCD_LANGUAGE_1
#define LCD_LANGUAGE_2 LCD_LANGUAGE
#endif
#ifndef LCD_LANGUAGE_3
@@ -59,31 +53,27 @@ typedef const char Language_Str[];
#define LCD_LANGUAGE_5 LCD_LANGUAGE_4
#endif
// Indirection required to paste together the namespace name
#define _GET_LANG(LANG) Language_##LANG
#define GET_LANG(LANG) _GET_LANG(LANG)
#if NUM_LANGUAGES > 1
extern uint8_t lang;
// The compiler does a good job of "flattening" out this
// if statement when there are fewer than five languages.
#define GET_TEXT(MSG) ( \
lang == 0 ? GET_LANG(LCD_LANGUAGE_1)::MSG : \
lang == 0 ? GET_LANG(LCD_LANGUAGE)::MSG : \
lang == 1 ? GET_LANG(LCD_LANGUAGE_2)::MSG : \
lang == 2 ? GET_LANG(LCD_LANGUAGE_3)::MSG : \
lang == 3 ? GET_LANG(LCD_LANGUAGE_4)::MSG : \
GET_LANG(LCD_LANGUAGE_5)::MSG \
)
#define MAX_LANG_CHARSIZE _MAX(GET_LANG(LCD_LANGUAGE)::CHARSIZE, \
GET_LANG(LCD_LANGUAGE_2)::CHARSIZE, \
GET_LANG(LCD_LANGUAGE_3)::CHARSIZE, \
GET_LANG(LCD_LANGUAGE_4)::CHARSIZE, \
GET_LANG(LCD_LANGUAGE_5)::CHARSIZE)
#else
#define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE_1)::MSG
#define GET_TEXT(MSG) GET_LANG(LCD_LANGUAGE)::MSG
#define MAX_LANG_CHARSIZE GET_LANG(LCD_LANGUAGE)::CHARSIZE
#endif
#define GET_TEXT_F(MSG) reinterpret_cast<const __FlashStringHelper *>(GET_TEXT(MSG))
#define GET_TEXT_F(MSG) (const __FlashStringHelper*)GET_TEXT(MSG)
#define GET_LANGUAGE_NAME(N) GET_LANG(LCD_LANGUAGE_##N)::LANGUAGE
// All the language tables go here
#include "language_en.h"
#include "language_de.h"
#include "language_fr.h"
#define MSG_CONCAT(A,B) pgm_p_pair_t(GET_TEXT(A),GET_TEXT(B))
+3 -1
View File
@@ -67,8 +67,10 @@ void print_bin(const uint16_t val) {
}
}
extern const char SP_X_STR[], SP_Y_STR[], SP_Z_STR[];
void print_xyz(const float &x, const float &y, const float &z, PGM_P const prefix/*=nullptr*/, PGM_P const suffix/*=nullptr*/) {
serialprintPGM(prefix);
SERIAL_ECHOPAIR(" " MSG_X, x, " " MSG_Y, y, " " MSG_Z, z);
SERIAL_ECHOPAIR_P(SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z);
if (suffix) serialprintPGM(suffix); else SERIAL_EOL();
}
+71 -6
View File
@@ -83,7 +83,7 @@ extern uint8_t marlin_debug_flags;
#define SERIAL_FLUSHTX()
#endif
// Print up to 12 pairs of values
// Print up to 12 pairs of values. Odd elements auto-wrapped in PSTR().
#define __SEP_N(N,V...) _SEP_##N(V)
#define _SEP_N(N,V...) __SEP_N(N,V)
#define _SEP_1(PRE) SERIAL_ECHOPGM(PRE)
@@ -113,6 +113,36 @@ extern uint8_t marlin_debug_flags;
#define SERIAL_ECHOPAIR(V...) _SEP_N(NUM_ARGS(V),V)
// Print up to 12 pairs of values. Odd elements must be PSTR pointers.
#define __SEP_N_P(N,V...) _SEP_##N##_P(V)
#define _SEP_N_P(N,V...) __SEP_N_P(N,V)
#define _SEP_1_P(PRE) serialprintPGM(PRE)
#define _SEP_2_P(PRE,V) serial_echopair_PGM(PRE,V)
#define _SEP_3_P(a,b,c) do{ _SEP_2_P(a,b); serialprintPGM(c); }while(0)
#define _SEP_4_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_2_P(V); }while(0)
#define _SEP_5_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_3_P(V); }while(0)
#define _SEP_6_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_4_P(V); }while(0)
#define _SEP_7_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_5_P(V); }while(0)
#define _SEP_8_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_6_P(V); }while(0)
#define _SEP_9_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_7_P(V); }while(0)
#define _SEP_10_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_8_P(V); }while(0)
#define _SEP_11_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_9_P(V); }while(0)
#define _SEP_12_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_10_P(V); }while(0)
#define _SEP_13_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_11_P(V); }while(0)
#define _SEP_14_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_12_P(V); }while(0)
#define _SEP_15_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_13_P(V); }while(0)
#define _SEP_16_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_14_P(V); }while(0)
#define _SEP_17_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_15_P(V); }while(0)
#define _SEP_18_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_16_P(V); }while(0)
#define _SEP_19_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_17_P(V); }while(0)
#define _SEP_20_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_18_P(V); }while(0)
#define _SEP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_19_P(V); }while(0)
#define _SEP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_20_P(V); }while(0)
#define _SEP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_21_P(V); }while(0)
#define _SEP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SEP_22_P(V); }while(0)
#define SERIAL_ECHOPAIR_P(V...) _SEP_N_P(NUM_ARGS(V),V)
// Print up to 12 pairs of values followed by newline
#define __SELP_N(N,V...) _SELP_##N(V)
#define _SELP_N(N,V...) __SELP_N(N,V)
@@ -139,10 +169,40 @@ extern uint8_t marlin_debug_flags;
#define _SELP_21(a,b,V...) do{ _SEP_2(a,b); _SELP_19(V); }while(0)
#define _SELP_22(a,b,V...) do{ _SEP_2(a,b); _SELP_20(V); }while(0)
#define _SELP_23(a,b,V...) do{ _SEP_2(a,b); _SELP_21(V); }while(0)
#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) // Use up two, pass the rest up
#define _SELP_24(a,b,V...) do{ _SEP_2(a,b); _SELP_22(V); }while(0) // Eat two args, pass the rest up
#define SERIAL_ECHOLNPAIR(V...) _SELP_N(NUM_ARGS(V),V)
// Print up to 12 pairs of values followed by newline
#define __SELP_N_P(N,V...) _SELP_##N##_P(V)
#define _SELP_N_P(N,V...) __SELP_N_P(N,V)
#define _SELP_1_P(PRE) serialprintPGM(PRE)
#define _SELP_2_P(PRE,V) do{ serial_echopair_PGM(PRE,V); SERIAL_EOL(); }while(0)
#define _SELP_3_P(a,b,c) do{ _SEP_2_P(a,b); serialprintPGM(c); }while(0)
#define _SELP_4_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_2_P(V); }while(0)
#define _SELP_5_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_3_P(V); }while(0)
#define _SELP_6_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_4_P(V); }while(0)
#define _SELP_7_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_5_P(V); }while(0)
#define _SELP_8_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_6_P(V); }while(0)
#define _SELP_9_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_7_P(V); }while(0)
#define _SELP_10_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_8_P(V); }while(0)
#define _SELP_11_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_9_P(V); }while(0)
#define _SELP_12_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_10_P(V); }while(0)
#define _SELP_13_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_11_P(V); }while(0)
#define _SELP_14_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_12_P(V); }while(0)
#define _SELP_15_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_13_P(V); }while(0)
#define _SELP_16_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_14_P(V); }while(0)
#define _SELP_17_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_15_P(V); }while(0)
#define _SELP_18_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_16_P(V); }while(0)
#define _SELP_19_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_17_P(V); }while(0)
#define _SELP_20_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_18_P(V); }while(0)
#define _SELP_21_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_19_P(V); }while(0)
#define _SELP_22_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_20_P(V); }while(0)
#define _SELP_23_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_21_P(V); }while(0)
#define _SELP_24_P(a,b,V...) do{ _SEP_2_P(a,b); _SELP_22_P(V); }while(0) // Eat two args, pass the rest up
#define SERIAL_ECHOLNPAIR_P(V...) _SELP_N_P(NUM_ARGS(V),V)
// Print up to 20 comma-separated pairs of values
#define __SLST_N(N,V...) _SLST_##N(V)
#define _SLST_N(N,V...) __SLST_N(N,V)
@@ -165,15 +225,20 @@ extern uint8_t marlin_debug_flags;
#define _SLST_17(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_15(V); }while(0)
#define _SLST_18(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_16(V); }while(0)
#define _SLST_19(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_17(V); }while(0)
#define _SLST_20(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_18(V); }while(0) // Use up two, pass the rest up
#define _SLST_20(a,b,V...) do{ SERIAL_ECHO(a); _SEP_2(", ",b); _SLST_18(V); }while(0) // Eat two args, pass the rest up
#define SERIAL_ECHOLIST(pre,V...) do{ SERIAL_ECHOPGM(pre); _SLST_N(NUM_ARGS(V),V); }while(0)
#define SERIAL_ECHOLIST_N(N,V...) _SLST_N(N,LIST_N(N,V))
#define SERIAL_ECHOPGM(S) (serialprintPGM(PSTR(S)))
#define SERIAL_ECHOLNPGM(S) (serialprintPGM(PSTR(S "\n")))
#define SERIAL_ECHO_P(P) (serialprintPGM(P))
#define SERIAL_ECHOPAIR_F(S,V...) do{ SERIAL_ECHOPGM(S); SERIAL_ECHO_F(V); }while(0)
#define SERIAL_ECHOPGM(S) (SERIAL_ECHO_P(PSTR(S)))
#define SERIAL_ECHOLNPGM(S) (SERIAL_ECHO_P(PSTR(S "\n")))
#define SERIAL_ECHOPAIR_F_P(P,V...) do{ serialprintPGM(P); SERIAL_ECHO_F(V); }while(0)
#define SERIAL_ECHOLNPAIR_F_P(V...) do{ SERIAL_ECHOPAIR_F_P(V); SERIAL_EOL(); }while(0)
#define SERIAL_ECHOPAIR_F(S,V...) SERIAL_ECHOPAIR_F_P(PSTR(S),V)
#define SERIAL_ECHOLNPAIR_F(V...) do{ SERIAL_ECHOPAIR_F(V); SERIAL_EOL(); }while(0)
#define SERIAL_ECHO_START() serial_echo_start()
+3
View File
@@ -26,6 +26,9 @@
#include "millis_t.h"
class __FlashStringHelper;
typedef const __FlashStringHelper *progmem_str;
//
// Enumerated axis indices
//
+1 -1
View File
@@ -79,7 +79,7 @@ void safe_delay(millis_t ms) {
);
#if HAS_BED_PROBE
SERIAL_ECHOPAIR("Probe Offset X", probe_offset.x, " Y", probe_offset.y, " Z", probe_offset.z);
SERIAL_ECHOPAIR_P(PSTR("Probe Offset X"), probe_offset.x, SP_Y_STR, probe_offset.y, SP_Z_STR, probe_offset.z);
if (probe_offset.x > 0)
SERIAL_ECHOPGM(" (Right");
else if (probe_offset.x < 0)
+3 -3
View File
@@ -47,9 +47,9 @@ inline void serial_delay(const millis_t ms) {
void unmark(const uint8_t x, const uint8_t y) { CBI(bits[y], x); }
void mark(const uint8_t x, const uint8_t y) { SBI(bits[y], x); }
bool marked(const uint8_t x, const uint8_t y) { return TEST(bits[y], x); }
inline void unmark(const xy_int8_t &xy) { unmark(xy.y, xy.x); }
inline void mark(const xy_int8_t &xy) { mark(xy.y, xy.x); }
inline bool marked(const xy_int8_t &xy) { return marked(xy.y, xy.x); }
inline void unmark(const xy_int8_t &xy) { unmark(xy.x, xy.y); }
inline void mark(const xy_int8_t &xy) { mark(xy.x, xy.y); }
inline bool marked(const xy_int8_t &xy) { return marked(xy.x, xy.y); }
};
typedef FlagBits<GRID_MAX_POINTS_X, GRID_MAX_POINTS_Y> MeshFlags;
+1 -1
View File
@@ -123,7 +123,7 @@ void Backlash::add_correction_steps(const int32_t &da, const int32_t &db, const
}
#if ENABLED(MEASURE_BACKLASH_WHEN_PROBING)
#if USES_Z_MIN_PROBE_ENDSTOP
#if HAS_CUSTOM_PROBE_PIN
#define TEST_PROBE_PIN (READ(Z_MIN_PROBE_PIN) != Z_MIN_PROBE_ENDSTOP_INVERTING)
#else
#define TEST_PROBE_PIN (READ(Z_MIN_PIN) != Z_MIN_ENDSTOP_INVERTING)
+2 -2
View File
@@ -35,7 +35,7 @@
#include "../../../lcd/extensible_ui/ui_api.h"
#endif
xy_int_t bilinear_grid_spacing, bilinear_start;
xy_pos_t bilinear_grid_spacing, bilinear_start;
xy_float_t bilinear_grid_factor;
bed_mesh_t z_values;
@@ -153,7 +153,7 @@ void print_bilinear_leveling_grid() {
#define ABL_TEMP_POINTS_X (GRID_MAX_POINTS_X + 2)
#define ABL_TEMP_POINTS_Y (GRID_MAX_POINTS_Y + 2)
float z_values_virt[ABL_GRID_POINTS_VIRT_X][ABL_GRID_POINTS_VIRT_Y];
xy_int_t bilinear_grid_spacing_virt;
xy_pos_t bilinear_grid_spacing_virt;
xy_float_t bilinear_grid_factor_virt;
void print_bilinear_leveling_grid_virt() {
+1 -1
View File
@@ -23,7 +23,7 @@
#include "../../../inc/MarlinConfigPre.h"
extern xy_int_t bilinear_grid_spacing, bilinear_start;
extern xy_pos_t bilinear_grid_spacing, bilinear_start;
extern xy_float_t bilinear_grid_factor;
extern bed_mesh_t z_values;
float bilinear_z_offset(const xy_pos_t &raw);
+1 -1
View File
@@ -51,7 +51,7 @@
if (!isnan(z_values[x][y])) {
SERIAL_ECHO_START();
SERIAL_ECHOPAIR(" M421 I", int(x), " J", int(y));
SERIAL_ECHOLNPAIR_F(" Z", z_values[x][y], 4);
SERIAL_ECHOLNPAIR_F_P(SP_Z_STR, z_values[x][y], 4);
serial_delay(75); // Prevent Printrun from exploding
}
}
+52 -47
View File
@@ -338,7 +338,7 @@
}
z_values[cpos.x][cpos.y] = NAN;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onMeshUpdate(closest, 0);
ExtUI::onMeshUpdate(cpos, 0.0f);
#endif
cnt++;
}
@@ -541,7 +541,7 @@
else {
z_values[cpos.x][cpos.y] = g29_constant;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onMeshUpdate(closest, g29_constant);
ExtUI::onMeshUpdate(cpos, g29_constant);
#endif
}
}
@@ -741,13 +741,13 @@
* This attempts to fill in locations closest to the nozzle's start location first.
*/
void unified_bed_leveling::probe_entire_mesh(const xy_pos_t &near, const bool do_ubl_mesh_map, const bool stow_probe, const bool do_furthest) {
DEPLOY_PROBE(); // Deploy before ui.capture() to allow for PAUSE_BEFORE_DEPLOY_STOW
#if HAS_LCD_MENU
ui.capture();
#endif
save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained
DEPLOY_PROBE();
uint8_t count = GRID_MAX_POINTS;
mesh_index_pair best;
@@ -757,17 +757,17 @@
const int point_num = (GRID_MAX_POINTS) - count + 1;
SERIAL_ECHOLNPAIR("\nProbing mesh point ", point_num, "/", int(GRID_MAX_POINTS), ".\n");
#if HAS_DISPLAY
ui.status_printf_P(0, PSTR(MSG_PROBING_MESH " %i/%i"), point_num, int(GRID_MAX_POINTS));
ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_PROBING_MESH), point_num, int(GRID_MAX_POINTS));
#endif
#if HAS_LCD_MENU
if (ui.button_pressed()) {
ui.quick_feedback(false); // Preserve button state for click-and-hold
SERIAL_ECHOLNPGM("\nMesh only partially populated.\n");
STOW_PROBE();
ui.wait_for_release();
ui.quick_feedback();
ui.release();
STOW_PROBE(); // Release UI before stow to allow for PAUSE_BEFORE_DEPLOY_STOW
return restore_ubl_active_state_and_leave();
}
#endif
@@ -783,14 +783,20 @@
);
z_values[best.pos.x][best.pos.y] = measured_z;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onMeshUpdate(best, measured_z);
ExtUI::onMeshUpdate(best.pos, measured_z);
#endif
}
SERIAL_FLUSH(); // Prevent host M105 buffer overrun.
} while (best.pos.x >= 0 && --count);
STOW_PROBE();
#if HAS_LCD_MENU
ui.release();
#endif
STOW_PROBE(); // Release UI during stow to allow for PAUSE_BEFORE_DEPLOY_STOW
#if HAS_LCD_MENU
ui.capture();
#endif
#ifdef Z_AFTER_PROBING
move_z_after_probing();
@@ -849,7 +855,9 @@
static void echo_and_take_a_measurement() { SERIAL_ECHOLNPGM(" and take a measurement."); }
float unified_bed_leveling::measure_business_card_thickness(float in_height) {
ui.capture();
#if HAS_LCD_MENU
ui.capture();
#endif
save_ubl_active_state_and_disable(); // Disable bed level correction for probing
do_blocking_move_to(0.5f * (MESH_MAX_X - (MESH_MIN_X)), 0.5f * (MESH_MAX_Y - (MESH_MIN_Y)), in_height);
@@ -888,8 +896,9 @@
}
void unified_bed_leveling::manually_probe_remaining_mesh(const xy_pos_t &pos, const float &z_clearance, const float &thick, const bool do_ubl_mesh_map) {
ui.capture();
#if HAS_LCD_MENU
ui.capture();
#endif
save_ubl_active_state_and_disable(); // No bed level correction so only raw data is obtained
do_blocking_move_to_xy_z(current_position, z_clearance);
@@ -917,11 +926,13 @@
do_blocking_move_to_z(z_clearance);
KEEPALIVE_STATE(PAUSED_FOR_USER);
ui.capture();
#if HAS_LCD_MENU
ui.capture();
#endif
if (do_ubl_mesh_map) display_map(g29_map_type); // show user where we're probing
serialprintPGM(parser.seen('B') ? PSTR(MSG_UBL_BC_INSERT) : PSTR(MSG_UBL_BC_INSERT2));
serialprintPGM(parser.seen('B') ? GET_TEXT(MSG_UBL_BC_INSERT) : GET_TEXT(MSG_UBL_BC_INSERT2));
const float z_step = 0.01f; // existing behavior: 0.01mm per click, occasionally step
//const float z_step = planner.steps_to_mm[Z_AXIS]; // approx one step each click
@@ -959,7 +970,7 @@
void abort_fine_tune() {
ui.return_to_status();
do_blocking_move_to_z(Z_CLEARANCE_BETWEEN_PROBES);
set_message_with_feedback(PSTR(MSG_EDITING_STOPPED));
set_message_with_feedback(GET_TEXT(MSG_EDITING_STOPPED));
}
void unified_bed_leveling::fine_tune_mesh(const xy_pos_t &pos, const bool do_ubl_mesh_map) {
@@ -984,8 +995,9 @@
save_ubl_active_state_and_disable();
LCD_MESSAGEPGM(MSG_UBL_FINE_TUNE_MESH);
ui.capture(); // Take over control of the LCD encoder
#if HAS_LCD_MENU
ui.capture(); // Take over control of the LCD encoder
#endif
do_blocking_move_to_xy_z(pos, Z_CLEARANCE_BETWEEN_PROBES); // Move to the given XY with probe clearance
#if ENABLED(UBL_MESH_EDIT_MOVES_Z)
@@ -1072,7 +1084,7 @@
bool err_flag = false;
#if HAS_LCD_MENU
set_message_with_feedback(PSTR(MSG_UBL_DOING_G29));
set_message_with_feedback(GET_TEXT(MSG_UBL_DOING_G29));
#endif
g29_constant = 0;
@@ -1196,7 +1208,7 @@
if (ubl_state_recursion_chk != 1) {
SERIAL_ECHOLNPGM("save_ubl_active_state_and_disabled() called multiple times in a row.");
#if HAS_LCD_MENU
set_message_with_feedback(PSTR(MSG_UBL_SAVE_ERROR));
set_message_with_feedback(GET_TEXT(MSG_UBL_SAVE_ERROR));
#endif
return;
}
@@ -1210,7 +1222,7 @@
if (--ubl_state_recursion_chk) {
SERIAL_ECHOLNPGM("restore_ubl_active_state_and_leave() called too many times.");
#if HAS_LCD_MENU
set_message_with_feedback(PSTR(MSG_UBL_RESTORE_ERROR));
set_message_with_feedback(GET_TEXT(MSG_UBL_RESTORE_ERROR));
#endif
return;
}
@@ -1335,7 +1347,7 @@
if (!isnan(v2)) {
z_values[x][y] = v1 < v2 ? v1 : v1 + v1 - v2;
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onMeshUpdate(x, y, z_values[pos.x][pos.y]);
ExtUI::onMeshUpdate(x, y, z_values[x][y]);
#endif
return true;
}
@@ -1385,17 +1397,8 @@
dx = (x_max - x_min) / (g29_grid_size - 1),
dy = (y_max - y_min) / (g29_grid_size - 1);
const vector_3 points[3] = {
#if ENABLED(HAS_FIXED_3POINT)
{ PROBE_PT_1_X, PROBE_PT_1_Y, 0 },
{ PROBE_PT_2_X, PROBE_PT_2_Y, 0 },
{ PROBE_PT_3_X, PROBE_PT_3_Y, 0 }
#else
{ x_min, y_min, 0 },
{ x_max, y_min, 0 },
{ (x_max - x_min) / 2, y_max, 0 }
#endif
};
xy_float_t points[3];
get_three_probe_points(points);
float measured_z;
bool abort_flag = false;
@@ -1410,7 +1413,7 @@
if (do_3_pt_leveling) {
SERIAL_ECHOLNPGM("Tilting mesh (1/3)");
#if HAS_DISPLAY
ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 1/3"));
ui.status_printf_P(0, PSTR(S_FMT " 1/3"), GET_TEXT(MSG_LCD_TILTING_MESH));
#endif
measured_z = probe_at_point(points[0], PROBE_PT_RAISE, g29_verbose_level);
@@ -1431,7 +1434,7 @@
if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (2/3)");
#if HAS_DISPLAY
ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 2/3"));
ui.status_printf_P(0, PSTR(S_FMT " 2/3"), GET_TEXT(MSG_LCD_TILTING_MESH));
#endif
measured_z = probe_at_point(points[1], PROBE_PT_RAISE, g29_verbose_level);
@@ -1453,7 +1456,7 @@
if (!abort_flag) {
SERIAL_ECHOLNPGM("Tilting mesh (3/3)");
#if HAS_DISPLAY
ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " 3/3"));
ui.status_printf_P(0, PSTR(S_FMT " 3/3"), GET_TEXT(MSG_LCD_TILTING_MESH));
#endif
measured_z = probe_at_point(points[2], PROBE_PT_STOW, g29_verbose_level);
@@ -1497,25 +1500,27 @@
if (!abort_flag) {
SERIAL_ECHOLNPAIR("Tilting mesh point ", point_num, "/", total_points, "\n");
#if HAS_DISPLAY
ui.status_printf_P(0, PSTR(MSG_LCD_TILTING_MESH " %i/%i"), point_num, total_points);
ui.status_printf_P(0, PSTR(S_FMT " %i/%i"), GET_TEXT(MSG_LCD_TILTING_MESH), point_num, total_points);
#endif
measured_z = probe_at_point(rpos, parser.seen('E') ? PROBE_PT_STOW : PROBE_PT_RAISE, g29_verbose_level); // TODO: Needs error handling
abort_flag = isnan(measured_z);
if (DEBUGGING(LEVELING)) {
const xy_pos_t lpos = rpos.asLogical();
DEBUG_CHAR('(');
DEBUG_ECHO_F(rpos.x, 7);
DEBUG_CHAR(',');
DEBUG_ECHO_F(rpos.y, 7);
DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7);
DEBUG_CHAR(',');
DEBUG_ECHO_F(lpos.y, 7);
DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7);
DEBUG_ECHOPAIR_F(" correction: ", get_z_correction(rpos), 7);
}
#if ENABLED(DEBUG_LEVELING_FEATURE)
if (DEBUGGING(LEVELING)) {
const xy_pos_t lpos = rpos.asLogical();
DEBUG_CHAR('(');
DEBUG_ECHO_F(rpos.x, 7);
DEBUG_CHAR(',');
DEBUG_ECHO_F(rpos.y, 7);
DEBUG_ECHOPAIR_F(") logical: (", lpos.x, 7);
DEBUG_CHAR(',');
DEBUG_ECHO_F(lpos.y, 7);
DEBUG_ECHOPAIR_F(") measured: ", measured_z, 7);
DEBUG_ECHOPAIR_F(" correction: ", get_z_correction(rpos), 7);
}
#endif
measured_z -= get_z_correction(rpos) /* + probe_offset.z */ ;
+83
View File
@@ -0,0 +1,83 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include "../inc/MarlinConfig.h"
#if ENABLED(CANCEL_OBJECTS)
#include "cancel_object.h"
#include "../gcode/gcode.h"
#include "../lcd/ultralcd.h"
CancelObject cancelable;
int8_t CancelObject::object_count, // = 0
CancelObject::active_object = -1;
uint32_t CancelObject::canceled; // = 0x0000
bool CancelObject::skipping; // = false
void CancelObject::set_active_object(const int8_t obj) {
active_object = obj;
if (WITHIN(obj, 0, 31)) {
if (obj >= object_count) object_count = obj + 1;
skipping = TEST(canceled, obj);
}
else
skipping = false;
#if HAS_DISPLAY
if (active_object >= 0)
ui.status_printf_P(0, PSTR(S_FMT " %i"), GET_TEXT(MSG_PRINTING_OBJECT), int(active_object + 1));
else
ui.reset_status();
#endif
}
void CancelObject::cancel_object(const int8_t obj) {
if (WITHIN(obj, 0, 31)) {
SBI(canceled, obj);
if (obj == active_object) skipping = true;
}
}
void CancelObject::uncancel_object(const int8_t obj) {
if (WITHIN(obj, 0, 31)) {
CBI(canceled, obj);
if (obj == active_object) skipping = false;
}
}
void CancelObject::report() {
if (active_object >= 0) {
SERIAL_ECHO_START();
SERIAL_ECHOLNPAIR("Active Object: ", int(active_object));
}
if (canceled) {
SERIAL_ECHO_START();
SERIAL_ECHOPGM("Canceled:");
for (int i = 0; i < object_count; i++)
if (TEST(canceled, i)) { SERIAL_CHAR(' '); SERIAL_ECHO(i); }
SERIAL_EOL();
}
}
#endif // CANCEL_OBJECTS
+41
View File
@@ -0,0 +1,41 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
class CancelObject {
public:
static bool skipping;
static int8_t object_count, active_object;
static uint32_t canceled;
static void set_active_object(const int8_t obj);
static void cancel_object(const int8_t obj);
static void uncancel_object(const int8_t obj);
static void report();
static inline bool is_canceled(const int8_t obj) { return TEST(canceled, obj); }
static inline void clear_active_object() { set_active_object(-1); }
static inline void cancel_active_object() { cancel_object(active_object); }
static inline void reset() { canceled = 0x0000; object_count = 0; clear_active_object(); }
};
extern CancelObject cancelable;
+3 -17
View File
@@ -56,23 +56,9 @@ void controllerfan_update() {
|| Z3_ENABLE_READ() == Z_ENABLE_ON
#endif
#if E_STEPPERS
|| E0_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 1
|| E1_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 2
|| E2_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 3
|| E3_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 4
|| E4_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 5
|| E5_ENABLE_READ() == E_ENABLE_ON
#endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2
#endif // E_STEPPERS > 1
#endif // E_STEPPERS
#define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == E_ENABLE_ON
REPEAT(E_STEPPERS, _OR_ENABLED_E)
#endif
) {
lastMotorOn = ms; //... set time to NOW so the fan will turn on
}
@@ -35,7 +35,7 @@
#if MB(5DPRINT)
#define DIGIPOT_I2C_FACTOR 117.96
#define DIGIPOT_I2C_MAX_CURRENT 1.736
#elif MB(AZTEEG_X5_MINI) || MB(AZTEEG_X5_MINI_WIFI)
#elif MB(AZTEEG_X5_MINI, AZTEEG_X5_MINI_WIFI)
#define DIGIPOT_I2C_FACTOR 113.5
#define DIGIPOT_I2C_MAX_CURRENT 2.0
#else
+2 -1
View File
@@ -23,6 +23,7 @@
#include "../inc/MarlinConfig.h"
#include "../module/planner.h"
#include "../module/thermistor/thermistors.h"
class FilamentWidthSensor {
public:
@@ -66,7 +67,7 @@ public:
}
// Convert raw measurement to mm
static inline float raw_to_mm(const uint16_t v) { return v * 5.0f * RECIPROCAL(16383.0f); }
static inline float raw_to_mm(const uint16_t v) { return v * 5.0f * RECIPROCAL(float(MAX_RAW_THERMISTOR_VALUE)); }
static inline float raw_to_mm() { return raw_to_mm(raw); }
// A scaled reading is ready
+13 -4
View File
@@ -64,12 +64,20 @@ void host_action(const char * const pstr, const bool eol) {
#if ENABLED(HOST_PROMPT_SUPPORT)
const char CONTINUE_STR[] PROGMEM = "Continue";
#if HAS_RESUME_CONTINUE
extern bool wait_for_user;
#endif
PromptReason host_prompt_reason = PROMPT_NOT_DEFINED;
void host_action_notify(const char * const message) {
host_action(PSTR("notification "), false);
serialprintPGM(message);
SERIAL_EOL();
}
void host_action_prompt(const char * const ptype, const bool eol=true) {
host_action(PSTR("prompt_"), false);
serialprintPGM(ptype);
@@ -102,8 +110,8 @@ void host_action(const char * const pstr, const bool eol) {
void host_response_handler(const uint8_t response) {
#ifdef DEBUG_HOST_ACTIONS
SERIAL_ECHOLNPAIR("M86 Handle Reason: ", host_prompt_reason);
SERIAL_ECHOLNPAIR("M86 Handle Response: ", response);
SERIAL_ECHOLNPAIR("M876 Handle Reason: ", host_prompt_reason);
SERIAL_ECHOLNPAIR("M876 Handle Response: ", response);
#endif
const char *msg = PSTR("UNKNOWN STATE");
const PromptReason hpr = host_prompt_reason;
@@ -126,7 +134,7 @@ void host_action(const char * const pstr, const bool eol) {
host_action_prompt_button(PSTR("DisableRunout"));
else {
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
host_action_prompt_button(PSTR("Continue"));
host_action_prompt_button(CONTINUE_STR);
}
host_action_prompt_show();
}
@@ -151,7 +159,8 @@ void host_action(const char * const pstr, const bool eol) {
case PROMPT_PAUSE_RESUME:
msg = PSTR("LCD_PAUSE_RESUME");
#if ENABLED(ADVANCED_PAUSE_FEATURE)
queue.inject_P(PSTR("M24"));
extern const char M24_STR[];
queue.inject_P(M24_STR);
#endif
break;
case PROMPT_INFO:
+3
View File
@@ -46,6 +46,8 @@ void host_action(const char * const pstr, const bool eol=true);
#if ENABLED(HOST_PROMPT_SUPPORT)
extern const char CONTINUE_STR[];
enum PromptReason : uint8_t {
PROMPT_NOT_DEFINED,
PROMPT_FILAMENT_RUNOUT,
@@ -58,6 +60,7 @@ void host_action(const char * const pstr, const bool eol=true);
extern PromptReason host_prompt_reason;
void host_response_handler(const uint8_t response);
void host_action_notify(const char * const message);
void host_action_prompt_begin(const char * const pstr, const bool eol=true);
void host_action_prompt_button(const char * const pstr);
void host_action_prompt_end();
+4 -4
View File
@@ -54,13 +54,13 @@ Joystick joystick;
void Joystick::report() {
SERIAL_ECHOPGM("Joystick");
#if HAS_JOY_ADC_X
SERIAL_ECHOPAIR(" X", x.raw);
SERIAL_ECHOPAIR_P(SP_X_STR, x.raw);
#endif
#if HAS_JOY_ADC_Y
SERIAL_ECHOPAIR(" Y", y.raw);
SERIAL_ECHOPAIR_P(SP_Y_STR, y.raw);
#endif
#if HAS_JOY_ADC_Z
SERIAL_ECHOPAIR(" Z", z.raw);
SERIAL_ECHOPAIR_P(SP_Z_STR, z.raw);
#endif
#if HAS_JOY_ADC_EN
SERIAL_ECHO_TERNARY(READ(JOY_EN_PIN), " EN=", "HIGH (dis", "LOW (en", "abled)");
@@ -148,7 +148,7 @@ Joystick joystick;
float hypot2 = 0;
LOOP_XYZ(i) if (norm_jog[i]) {
move_dist[i] = seg_time * norm_jog[i] *
#if EITHER(ULTIPANEL, EXTENSIBLE_UI)
#if ENABLED(EXTENSIBLE_UI)
MMM_TO_MMS(manual_feedrate_mm_m[i]);
#else
planner.settings.max_feedrate_mm_s[i];
+20 -21
View File
@@ -53,6 +53,7 @@
#include "../lcd/extensible_ui/ui_api.h"
#endif
#include "../core/language.h"
#include "../lcd/ultralcd.h"
#if HAS_BUZZER
@@ -76,6 +77,12 @@ fil_change_settings_t fc_settings[EXTRUDERS];
#include "../sd/cardreader.h"
#endif
#if ENABLED(EMERGENCY_PARSER)
#define _PMSG(L) L##_M108
#else
#define _PMSG(L) L##_LCD
#endif
#if HAS_BUZZER
static void filament_change_beep(const int8_t max_beep_count, const bool init=false) {
if (pause_mode == PAUSE_MODE_PAUSE_PRINT) return;
@@ -163,7 +170,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
#if HAS_LCD_MENU
if (show_lcd) lcd_pause_show_message(PAUSE_MESSAGE_INSERT, mode);
#endif
SERIAL_ECHO_MSG(MSG_FILAMENT_CHANGE_INSERT);
SERIAL_ECHO_MSG(_PMSG(MSG_FILAMENT_CHANGE_INSERT));
#if HAS_BUZZER
filament_change_beep(max_beep_count, true);
@@ -184,11 +191,11 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
host_action_prompt_begin(PSTR("Load Filament T"), false);
SERIAL_CHAR(tool);
SERIAL_EOL();
host_action_prompt_button(PSTR("Continue"));
host_action_prompt_button(CONTINUE_STR);
host_action_prompt_show();
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onUserConfirmRequired(PSTR("Load Filament"));
ExtUI::onUserConfirmRequired_P(PSTR("Load Filament"));
#endif
while (wait_for_user) {
#if HAS_BUZZER
@@ -240,10 +247,10 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purge Running..."), PSTR("Continue"));
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Filament Purge Running..."), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onUserConfirmRequired(PSTR("Filament Purge Running..."));
ExtUI::onUserConfirmRequired_P(PSTR("Filament Purge Running..."));
#endif
for (float purge_count = purge_length; purge_count > 0 && wait_for_user; --purge_count)
do_pause_e_move(1, ADVANCED_PAUSE_PURGE_FEEDRATE);
@@ -276,7 +283,7 @@ bool load_filament(const float &slow_load_length/*=0*/, const float &fast_load_l
host_action_prompt_button(PSTR("DisableRunout"));
else {
host_prompt_reason = PROMPT_FILAMENT_RUNOUT;
host_action_prompt_button(PSTR("Continue"));
host_action_prompt_button(CONTINUE_STR);
}
host_action_prompt_show();
#endif
@@ -457,7 +464,7 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
#endif
if (unload_length) // Unload the filament
unload_filament(unload_length, show_lcd);
unload_filament(unload_length, show_lcd, PAUSE_MODE_CHANGE_FILAMENT);
#if ENABLED(DUAL_X_CARRIAGE)
active_extruder = saved_ext;
@@ -481,14 +488,6 @@ bool pause_print(const float &retract, const xyz_pos_t &park_point, const float
* Used by M125 and M600
*/
#if (HAS_LCD_MENU || ENABLED(EXTENSIBLE_UI)) && ENABLED(EMERGENCY_PARSER)
#define _PMSG(L) L
#elif ENABLED(EMERGENCY_PARSER)
#define _PMSG(L) L##_M108
#else
#define _PMSG(L) L##_LCD
#endif
void show_continue_prompt(const bool is_reload) {
#if HAS_LCD_MENU
lcd_pause_show_message(is_reload ? PAUSE_MESSAGE_INSERT : PAUSE_MESSAGE_WAITING);
@@ -524,10 +523,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
KEEPALIVE_STATE(PAUSED_FOR_USER);
wait_for_user = true; // LCD click or M108 will clear this
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), PSTR("Continue"));
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Nozzle Parked"), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onUserConfirmRequired(PSTR("Nozzle Parked"));
ExtUI::onUserConfirmRequired_P(PSTR("Nozzle Parked"));
#endif
while (wait_for_user) {
#if HAS_BUZZER
@@ -551,7 +550,7 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onUserConfirmRequired(PSTR("HeaterTimeout"));
ExtUI::onUserConfirmRequired_P(PSTR("HeaterTimeout"));
#endif
// Wait for LCD click or M108
@@ -578,10 +577,10 @@ void wait_for_confirmation(const bool is_reload/*=false*/, const int8_t max_beep
HOTEND_LOOP() thermalManager.hotend_idle[e].start(nozzle_timeout);
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), PSTR("Continue"));
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("Reheat Done"), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onUserConfirmRequired("Reheat finished.");
ExtUI::onUserConfirmRequired_P(PSTR("Reheat finished."));
#endif
wait_for_user = true;
nozzle_timed_out = false;
@@ -638,7 +637,7 @@ void resume_print(const float &slow_load_length/*=0*/, const float &fast_load_le
}
if (nozzle_timed_out || thermalManager.hotEnoughToExtrude(active_extruder)) // Load the new filament
load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_PAUSE_PRINT DXC_PASS);
load_filament(slow_load_length, fast_load_length, purge_length, max_beep_count, true, nozzle_timed_out, PAUSE_MODE_SAME DXC_PASS);
#if HAS_LCD_MENU
lcd_pause_show_message(PAUSE_MESSAGE_RESUME);
+14 -28
View File
@@ -59,33 +59,19 @@ bool Power::is_power_needed() {
#if HAS_HEATED_BED
|| thermalManager.temp_bed.soft_pwm_amount > 0
#endif
#if HAS_X2_ENABLE
|| X2_ENABLE_READ() == X_ENABLE_ON
#endif
#if HAS_Y2_ENABLE
|| Y2_ENABLE_READ() == Y_ENABLE_ON
#endif
#if HAS_Z2_ENABLE
|| Z2_ENABLE_READ() == Z_ENABLE_ON
#endif
#if E_STEPPERS
|| E0_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 1
|| E1_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 2
|| E2_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 3
|| E3_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 4
|| E4_ENABLE_READ() == E_ENABLE_ON
#if E_STEPPERS > 5
|| E5_ENABLE_READ() == E_ENABLE_ON
#endif // E_STEPPERS > 5
#endif // E_STEPPERS > 4
#endif // E_STEPPERS > 3
#endif // E_STEPPERS > 2
#endif // E_STEPPERS > 1
#endif // E_STEPPERS
#if HAS_X2_ENABLE
|| X2_ENABLE_READ() == X_ENABLE_ON
#endif
#if HAS_Y2_ENABLE
|| Y2_ENABLE_READ() == Y_ENABLE_ON
#endif
#if HAS_Z2_ENABLE
|| Z2_ENABLE_READ() == Z_ENABLE_ON
#endif
#if E_STEPPERS
#define _OR_ENABLED_E(N) || E##N##_ENABLE_READ() == E_ENABLE_ON
REPEAT(E_STEPPERS, _OR_ENABLED_E)
#endif
) return true;
HOTEND_LOOP() if (thermalManager.degTargetHotend(e) > 0) return true;
@@ -123,7 +109,7 @@ void Power::power_on() {
PSU_PIN_ON();
#if HAS_TRINAMIC
delay(100); // Wait for power to settle
delay(PSU_POWERUP_DELAY); // Wait for power to settle
restore_stepper_drivers();
#endif
}
+79 -10
View File
@@ -65,6 +65,9 @@ PrintJobRecovery recovery;
#ifndef POWER_LOSS_RETRACT_LEN
#define POWER_LOSS_RETRACT_LEN 0
#endif
#ifndef POWER_LOSS_ZRAISE
#define POWER_LOSS_ZRAISE 2
#endif
/**
* Clear the recovery info
@@ -183,6 +186,15 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
info.active_extruder = active_extruder;
#endif
#if DISABLED(NO_VOLUMETRICS)
info.volumetric_enabled = parser.volumetric_enabled;
#if EXTRUDERS > 1
for (int8_t e = 0; e < EXTRUDERS; e++) info.filament_size[e] = planner.filament_size[e];
#else
if (parser.volumetric_enabled) info.filament_size = planner.filament_size[active_extruder];
#endif
#endif
#if EXTRUDERS
HOTEND_LOOP() info.target_temperature[e] = thermalManager.temp_hotend[e].target;
#endif
@@ -226,10 +238,34 @@ void PrintJobRecovery::save(const bool force/*=false*/, const bool save_queue/*=
}
#if PIN_EXISTS(POWER_LOSS)
void PrintJobRecovery::_outage() {
save(true);
kill(PSTR(MSG_OUTAGE_RECOVERY));
#if ENABLED(BACKUP_POWER_SUPPLY)
static bool lock = false;
if (lock) return; // No re-entrance from idle() during raise_z()
lock = true;
#endif
if (IS_SD_PRINTING()) save(true);
#if ENABLED(BACKUP_POWER_SUPPLY)
raise_z();
#endif
kill(GET_TEXT(MSG_OUTAGE_RECOVERY));
}
#if ENABLED(BACKUP_POWER_SUPPLY)
void PrintJobRecovery::raise_z() {
// Disable all heaters to reduce power loss
thermalManager.disable_all_heaters();
quickstop_stepper();
// Raise Z axis
gcode.process_subcommands_now_P(PSTR("G91\nG0 Z" STRINGIFY(POWER_LOSS_ZRAISE)));
planner.synchronize();
}
#endif
#endif
/**
@@ -251,8 +287,6 @@ void PrintJobRecovery::write() {
*/
void PrintJobRecovery::resume() {
#define RECOVERY_ZRAISE 2
const uint32_t resume_sdpos = info.sdpos; // Get here before the stepper ISR overwrites it
#if HAS_LEVELING
@@ -263,15 +297,27 @@ void PrintJobRecovery::resume() {
// Reset E, raise Z, home XY...
gcode.process_subcommands_now_P(PSTR("G92.9 E0"
#if Z_HOME_DIR > 0
// If Z homing goes to max, reset E and home all
"\nG28R0"
// If Z homing goes to max, just reset E and home all
"\n"
"G28R0"
#if ENABLED(MARLIN_DEV_MODE)
"S"
#endif
#else
#else // "G92.9 E0 ..."
// Set Z to 0, raise Z by RECOVERY_ZRAISE, and Home (XY only for Cartesian)
// with no raise. (Only do simulated homing in Marlin Dev Mode.)
"Z0\nG1Z" STRINGIFY(RECOVERY_ZRAISE) "\nG28R0"
#if ENABLED(BACKUP_POWER_SUPPLY)
"Z" STRINGIFY(POWER_LOSS_ZRAISE) // Z-axis was already raised at outage
#else
"Z0\n" // Set Z=0
"G1Z" STRINGIFY(POWER_LOSS_ZRAISE) // Raise Z
#endif
"\n"
"G28R0"
#if ENABLED(MARLIN_DEV_MODE)
"S"
#elif !IS_KINEMATIC
@@ -291,6 +337,27 @@ void PrintJobRecovery::resume() {
gcode.process_subcommands_now(cmd);
#endif
// Recover volumetric extrusion state
#if DISABLED(NO_VOLUMETRICS)
#if EXTRUDERS > 1
for (int8_t e = 0; e < EXTRUDERS; e++) {
dtostrf(info.filament_size[e], 1, 3, str_1);
sprintf_P(cmd, PSTR("M200 T%i D%s"), e, str_1);
gcode.process_subcommands_now(cmd);
}
if (!info.volumetric_enabled) {
sprintf_P(cmd, PSTR("M200 T%i D0"), info.active_extruder);
gcode.process_subcommands_now(cmd);
}
#else
if (info.volumetric_enabled) {
dtostrf(info.filament_size, 1, 3, str_1);
sprintf_P(cmd, PSTR("M200 D%s"), str_1);
gcode.process_subcommands_now(cmd);
}
#endif
#endif
#if HAS_HEATED_BED
const int16_t bt = info.target_temperature_bed;
if (bt) {
@@ -327,9 +394,10 @@ void PrintJobRecovery::resume() {
// Restore retract and hop state
#if ENABLED(FWRETRACT)
for (uint8_t e = 0; e < EXTRUDERS; e++) {
if (info.retract[e] != 0.0)
if (info.retract[e] != 0.0) {
fwretract.current_retract[e] = info.retract[e];
fwretract.retracted[e] = true;
}
}
fwretract.current_hop = info.retract_hop;
#endif
@@ -406,7 +474,8 @@ void PrintJobRecovery::resume() {
// Resume the SD file from the last position
char *fn = info.sd_filename;
sprintf_P(cmd, PSTR("M23 %s"), fn);
extern const char M23_STR[];
sprintf_P(cmd, M23_STR, fn);
gcode.process_subcommands_now(cmd);
sprintf_P(cmd, PSTR("M24 S%ld T%ld"), resume_sdpos, info.print_job_elapsed);
gcode.process_subcommands_now(cmd);
+14 -1
View File
@@ -59,6 +59,15 @@ typedef struct {
uint8_t active_extruder;
#endif
#if DISABLED(NO_VOLUMETRICS)
bool volumetric_enabled;
#if EXTRUDERS > 1
float filament_size[EXTRUDERS];
#else
float filament_size;
#endif
#endif
#if HOTENDS
int16_t target_temperature[HOTENDS];
#endif
@@ -159,7 +168,7 @@ class PrintJobRecovery {
#if PIN_EXISTS(POWER_LOSS)
static inline void outage() {
if (enabled && IS_SD_PRINTING() && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE)
if (enabled && READ(POWER_LOSS_PIN) == POWER_LOSS_STATE)
_outage();
}
#endif
@@ -175,6 +184,10 @@ class PrintJobRecovery {
private:
static void write();
#if ENABLED(BACKUP_POWER_SUPPLY)
static void raise_z();
#endif
#if PIN_EXISTS(POWER_LOSS)
static void _outage();
#endif
+5 -5
View File
@@ -97,7 +97,7 @@ volatile int8_t MMU2::finda = 1;
volatile bool MMU2::finda_runout_valid;
int16_t MMU2::version = -1, MMU2::buildnr = -1;
millis_t MMU2::last_request, MMU2::next_P0_request;
char MMU2::rx_buffer[16], MMU2::tx_buffer[16];
char MMU2::rx_buffer[MMU_RX_SIZE], MMU2::tx_buffer[MMU_TX_SIZE];
#if HAS_LCD_MENU && ENABLED(MMU2_MENUS)
@@ -433,7 +433,7 @@ bool MMU2::rx_ok() {
void MMU2::check_version() {
if (buildnr < MMU_REQUIRED_FW_BUILDNR) {
SERIAL_ERROR_MSG("Invalid MMU2 firmware. Version >= " STRINGIFY(MMU_REQUIRED_FW_BUILDNR) " required.");
kill(MSG_MMU2_WRONG_FIRMWARE);
kill(GET_TEXT(MSG_MMU2_WRONG_FIRMWARE));
}
}
@@ -449,7 +449,7 @@ void MMU2::tool_change(uint8_t index) {
if (index != extruder) {
disable_E0();
ui.status_printf_P(0, PSTR(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
ui.status_printf_P(0, GET_TEXT(MSG_MMU2_LOADING_FILAMENT), int(index + 1));
command(MMU_CMD_T0 + index);
@@ -709,10 +709,10 @@ void MMU2::filament_runout() {
BUZZ(200, 404);
wait_for_user = true;
#if ENABLED(HOST_PROMPT_SUPPORT)
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), PSTR("Continue"));
host_prompt_do(PROMPT_USER_CONTINUE, PSTR("MMU2 Eject Recover"), CONTINUE_STR);
#endif
#if ENABLED(EXTENSIBLE_UI)
ExtUI::onUserConfirmRequired(PSTR("MMU2 Eject Recover"));
ExtUI::onUserConfirmRequired_P(PSTR("MMU2 Eject Recover"));
#endif
while (wait_for_user) idle();
BUZZ(200, 404);
+9 -1
View File
@@ -27,6 +27,14 @@
#include "../runout.h"
#endif
#if SERIAL_USB
#define MMU_RX_SIZE 256
#define MMU_TX_SIZE 256
#else
#define MMU_RX_SIZE 16
#define MMU_TX_SIZE 16
#endif
struct E_Step;
class MMU2 {
@@ -79,7 +87,7 @@ private:
static volatile bool finda_runout_valid;
static int16_t version, buildnr;
static millis_t last_request, next_P0_request;
static char rx_buffer[16], tx_buffer[16];
static char rx_buffer[MMU_RX_SIZE], tx_buffer[MMU_TX_SIZE];
static inline void set_runout_valid(const bool valid) {
finda_runout_valid = valid;
+21 -19
View File
@@ -34,14 +34,16 @@ SpindleLaser cutter;
cutter_power_t SpindleLaser::power; // = 0
#define SPINDLE_LASER_PWM_OFF ((SPINDLE_LASER_PWM_INVERT) ? 255 : 0)
void SpindleLaser::init() {
OUT_WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Init spindle to off
#if ENABLED(SPINDLE_CHANGE_DIR)
OUT_WRITE(SPINDLE_DIR_PIN, SPINDLE_INVERT_DIR ? 255 : 0); // Init rotation to clockwise (M3)
#endif
#if ENABLED(SPINDLE_LASER_PWM) && PIN_EXISTS(SPINDLE_LASER_PWM)
#if ENABLED(SPINDLE_LASER_PWM)
SET_PWM(SPINDLE_LASER_PWM_PIN);
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_INVERT ? 255 : 0); // set to lowest speed
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // set to lowest speed
#endif
}
@@ -54,34 +56,34 @@ void SpindleLaser::init() {
*/
void SpindleLaser::set_ocr(const uint8_t ocr) {
WRITE(SPINDLE_LASER_ENA_PIN, SPINDLE_LASER_ACTIVE_HIGH); // turn spindle on (active low)
#if ENABLED(SPINDLE_LASER_PWM)
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), (SPINDLE_LASER_PWM_INVERT) ? 255 - ocr : ocr);
#endif
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), ocr ^ SPINDLE_LASER_PWM_OFF);
}
#endif
void SpindleLaser::update_output() {
const bool ena = enabled();
void SpindleLaser::apply_power(const cutter_power_t inpow) {
static cutter_power_t last_power_applied = 0;
if (inpow == last_power_applied) return;
last_power_applied = inpow;
#if ENABLED(SPINDLE_LASER_PWM)
if (ena) {
if (enabled()) {
#define _scaled(F) ((F - (SPEED_POWER_INTERCEPT)) * inv_slope)
constexpr float inv_slope = RECIPROCAL(SPEED_POWER_SLOPE),
min_ocr = (SPEED_POWER_MIN - (SPEED_POWER_INTERCEPT)) * inv_slope, // Minimum allowed
max_ocr = (SPEED_POWER_MAX - (SPEED_POWER_INTERCEPT)) * inv_slope; // Maximum allowed
min_ocr = _scaled(SPEED_POWER_MIN),
max_ocr = _scaled(SPEED_POWER_MAX);
int16_t ocr_val;
if (power <= SPEED_POWER_MIN) ocr_val = min_ocr; // Use minimum if set below
else if (power >= SPEED_POWER_MAX) ocr_val = max_ocr; // Use maximum if set above
else ocr_val = (power - (SPEED_POWER_INTERCEPT)) * inv_slope; // Use calculated OCR value
set_ocr(ocr_val & 0xFF); // ...limited to Atmel PWM max
if (inpow <= SPEED_POWER_MIN) ocr_val = min_ocr; // Use minimum if set below
else if (inpow >= SPEED_POWER_MAX) ocr_val = max_ocr; // Use maximum if set above
else ocr_val = _scaled(inpow); // Use calculated OCR value
set_ocr(ocr_val & 0xFF); // ...limited to Atmel PWM max
}
else { // Convert RPM to PWM duty cycle
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off (active low)
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_INVERT ? 255 : 0); // Only write low byte
else {
WRITE(SPINDLE_LASER_ENA_PIN, !SPINDLE_LASER_ACTIVE_HIGH); // Turn spindle off (active low)
analogWrite(pin_t(SPINDLE_LASER_PWM_PIN), SPINDLE_LASER_PWM_OFF); // Only write low byte
}
#else
WRITE(SPINDLE_LASER_ENA_PIN, ena ? SPINDLE_LASER_ACTIVE_HIGH : !SPINDLE_LASER_ACTIVE_HIGH);
WRITE(SPINDLE_LASER_ENA_PIN, (SPINDLE_LASER_ACTIVE_HIGH) ? enabled() : !enabled());
#endif
power_delay(ena);
}
#if ENABLED(SPINDLE_CHANGE_DIR)
+19 -6
View File
@@ -36,24 +36,33 @@
#define MSG_CUTTER(M) _MSG_CUTTER(M)
#if SPEED_POWER_MAX > 255
#define cutter_power_t uint16_t
typedef uint16_t cutter_power_t;
#define CUTTER_MENU_TYPE uint16_5
#else
#define cutter_power_t uint8_t
typedef uint8_t cutter_power_t;
#define CUTTER_MENU_TYPE uint8
#endif
class SpindleLaser {
public:
static cutter_power_t power;
static inline uint8_t powerPercent(const uint8_t pp) { return ui8_to_percent(pp); } // for display
static void init();
static inline bool enabled() { return !!power; }
static inline void set_power(const uint8_t pwr) { power = pwr; update_output(); }
static inline void set_power(const cutter_power_t pwr) { power = pwr; }
static inline void set_enabled(const bool enable) { set_power(enable ? 255 : 0); }
static inline void refresh() { apply_power(power); }
static inline void set_enabled(const bool enable) {
const bool was = enabled();
set_power(enable ? 255 : 0);
if (was != enable) power_delay();
}
static void apply_power(const cutter_power_t inpow);
//static bool active() { return READ(SPINDLE_LASER_ENA_PIN) == SPINDLE_LASER_ACTIVE_HIGH; }
@@ -61,11 +70,15 @@ public:
#if ENABLED(SPINDLE_LASER_PWM)
static void set_ocr(const uint8_t ocr);
static inline void set_ocr_power(const uint8_t pwr) { power = pwr; set_ocr(pwr); }
static inline void set_ocr_power(const cutter_power_t pwr) { power = pwr; set_ocr(pwr); }
#endif
// Wait for spindle to spin up or spin down
static inline void power_delay(const bool on) { safe_delay(on ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY); }
static inline void power_delay() {
#if SPINDLE_LASER_POWERUP_DELAY || SPINDLE_LASER_POWERDOWN_DELAY
safe_delay(enabled() ? SPINDLE_LASER_POWERUP_DELAY : SPINDLE_LASER_POWERDOWN_DELAY);
#endif
}
#if ENABLED(SPINDLE_CHANGE_DIR)
static void set_direction(const bool reverse);

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