From 613ff2087d93422cb4e48c4468f1878cc5a8ae44 Mon Sep 17 00:00:00 2001 From: Scott Lahteine Date: Mon, 18 Nov 2024 17:00:45 -0600 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Code=20updates?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h | 2 +- Marlin/src/HAL/AVR/pinsDebug.h | 74 +++--- Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h | 2 +- Marlin/src/HAL/DUE/HAL.h | 2 +- Marlin/src/HAL/DUE/Servo.cpp | 2 +- Marlin/src/HAL/DUE/pinsDebug.h | 51 +++-- Marlin/src/HAL/DUE/usb/README.md | 29 +++ Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp | 30 ++- Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h | 16 +- Marlin/src/HAL/DUE/usb/uotghs_device_due.c | 80 ++++++- Marlin/src/HAL/ESP32/pinsDebug.h | 71 ++++++ Marlin/src/HAL/HC32/pinsDebug.h | 180 +++++++++++++++ Marlin/src/HAL/LINUX/hardware/Timer.cpp | 5 +- Marlin/src/HAL/LINUX/include/pinmapping.h | 16 +- Marlin/src/HAL/LINUX/pinsDebug.h | 60 +++-- Marlin/src/HAL/LPC1768/pinsDebug.h | 43 ++-- .../HAL/NATIVE_SIM/inc/Conditionals_post.h | 21 ++ Marlin/src/HAL/NATIVE_SIM/pinsDebug.cpp | 15 +- Marlin/src/HAL/NATIVE_SIM/pinsDebug.h | 47 ++-- Marlin/src/HAL/SAMD21/HAL.h | 2 +- Marlin/src/HAL/SAMD21/fastio.h | 2 +- Marlin/src/HAL/SAMD21/pinsDebug.h | 45 ++-- Marlin/src/HAL/SAMD51/fastio.h | 2 +- Marlin/src/HAL/SAMD51/pinsDebug.h | 44 ++-- Marlin/src/HAL/STM32/HAL.h | 2 +- Marlin/src/HAL/STM32/pinsDebug.h | 124 ++++++----- Marlin/src/HAL/STM32F1/HAL.h | 2 +- Marlin/src/HAL/STM32F1/pinsDebug.h | 58 +++-- Marlin/src/HAL/TEENSY31_32/HAL.h | 2 +- Marlin/src/HAL/TEENSY31_32/pinsDebug.h | 70 ++++++ Marlin/src/HAL/TEENSY31_32/timers.h | 2 +- Marlin/src/HAL/TEENSY35_36/HAL.h | 2 +- Marlin/src/HAL/TEENSY35_36/pinsDebug.h | 37 ++- Marlin/src/HAL/TEENSY40_41/HAL.h | 2 +- Marlin/src/HAL/TEENSY40_41/pinsDebug.h | 44 ++-- Marlin/src/HAL/TEENSY40_41/timers.h | 9 +- Marlin/src/core/boards.h | 2 +- Marlin/src/core/macros.h | 17 +- Marlin/src/core/multi_language.h | 1 + Marlin/src/core/serial.cpp | 2 +- Marlin/src/core/serial.h | 2 +- Marlin/src/core/types.h | 210 +++++++++++++----- Marlin/src/core/utility.cpp | 44 ++-- Marlin/src/feature/bedlevel/abl/bbl.cpp | 7 +- .../bedlevel/mbl/mesh_bed_leveling.cpp | 4 +- Marlin/src/feature/easythreed_ui.cpp | 4 +- Marlin/src/feature/encoder_i2c.cpp | 2 +- Marlin/src/feature/ethernet.cpp | 2 +- Marlin/src/feature/filwidth.cpp | 2 +- Marlin/src/feature/fwretract.cpp | 5 +- Marlin/src/feature/host_actions.cpp | 4 +- Marlin/src/feature/joystick.cpp | 2 +- Marlin/src/feature/leds/leds.cpp | 4 +- Marlin/src/feature/leds/neopixel.h | 2 +- Marlin/src/feature/leds/pca9632.cpp | 2 +- Marlin/src/feature/mmu/mmu2.cpp | 6 +- Marlin/src/feature/mmu/mmu2.h | 4 + Marlin/src/feature/power.cpp | 2 +- Marlin/src/feature/powerloss.cpp | 4 +- Marlin/src/feature/powerloss.h | 4 +- Marlin/src/feature/runout.cpp | 2 +- Marlin/src/feature/runout.h | 2 +- Marlin/src/feature/spindle_laser.cpp | 2 +- Marlin/src/feature/spindle_laser.h | 4 + Marlin/src/feature/tmc_util.cpp | 6 +- Marlin/src/feature/tmc_util.h | 2 +- Marlin/src/feature/x_twist.cpp | 2 +- Marlin/src/gcode/bedlevel/G26.cpp | 10 +- Marlin/src/gcode/bedlevel/G42.cpp | 67 +++--- Marlin/src/gcode/bedlevel/M420.cpp | 5 +- Marlin/src/gcode/bedlevel/abl/G29.cpp | 5 + Marlin/src/gcode/calibrate/G28.cpp | 19 +- Marlin/src/gcode/config/M43.cpp | 55 ++--- .../control/{M10-M11.cpp => M10_M11.cpp} | 5 + Marlin/src/gcode/feature/pause/G27.cpp | 9 +- Marlin/src/gcode/feature/prusa_MMU2/M403.cpp | 4 +- Marlin/src/gcode/gcode_d.cpp | 39 ++-- Marlin/src/gcode/host/M110.cpp | 3 + Marlin/src/gcode/host/M115.cpp | 4 +- Marlin/src/gcode/motion/G2_G3.cpp | 136 ++++++------ Marlin/src/gcode/motion/G5.cpp | 29 ++- Marlin/src/gcode/motion/G6.cpp | 11 +- Marlin/src/gcode/parser.cpp | 4 +- Marlin/src/gcode/parser.h | 5 +- Marlin/src/gcode/probe/G38.cpp | 2 +- Marlin/src/gcode/probe/M951.cpp | 15 ++ Marlin/src/gcode/queue.cpp | 4 +- Marlin/src/gcode/queue.h | 2 + Marlin/src/gcode/stats/M75-M78.cpp | 3 + Marlin/src/gcode/temp/M155.cpp | 4 +- Marlin/src/inc/Conditionals_LCD.h | 5 + Marlin/src/inc/Conditionals_adv.h | 16 +- Marlin/src/inc/SanityCheck.h | 2 - Marlin/src/lcd/e3v2/creality/dwin.cpp | 1 - .../src/lcd/extui/dgus/mks/DGUSDisplayDef.cpp | 6 +- .../lcd/extui/dgus/mks/DGUSScreenHandler.cpp | 2 +- Marlin/src/lcd/marlinui.cpp | 10 +- Marlin/src/lcd/marlinui.h | 2 +- Marlin/src/lcd/menu/menu_bed_tramming.cpp | 4 +- Marlin/src/libs/numtostr.cpp | 2 + Marlin/src/module/delta.cpp | 2 +- Marlin/src/module/endstops.cpp | 4 +- Marlin/src/module/motion.cpp | 6 +- Marlin/src/module/planner.cpp | 8 +- Marlin/src/module/polargraph.cpp | 2 +- Marlin/src/module/probe.cpp | 2 +- Marlin/src/module/scara.h | 8 +- Marlin/src/module/stepper.cpp | 2 +- Marlin/src/module/stepper.h | 2 +- Marlin/src/module/temperature.cpp | 4 +- Marlin/src/module/temperature.h | 26 ++- Marlin/src/module/tool_change.cpp | 2 +- Marlin/src/pins/pins.h | 2 +- Marlin/src/pins/pinsDebug.h | 62 +++--- Marlin/src/sd/SdBaseFile.cpp | 2 +- Marlin/src/sd/cardreader.cpp | 20 +- Marlin/src/sd/cardreader.h | 24 +- 117 files changed, 1502 insertions(+), 719 deletions(-) create mode 100644 Marlin/src/HAL/DUE/usb/README.md create mode 100644 Marlin/src/HAL/ESP32/pinsDebug.h create mode 100644 Marlin/src/HAL/HC32/pinsDebug.h rename Marlin/src/gcode/control/{M10-M11.cpp => M10_M11.cpp} (95%) diff --git a/Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h b/Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h index ee250b1786e7..2119d168aba4 100644 --- a/Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h +++ b/Marlin/src/HAL/AVR/fastio/fastio_AT90USB.h @@ -26,7 +26,7 @@ * * Logical Pin: 28 29 30 31 32 33 34 35 20 21 22 23 24 25 26 27 10 11 12 13 14 15 16 17 00 01 02 03 04 05 06 07 08 09(46*47)36 37 18 19 38 39 40 41 42 43 44 45 * Port: A0 A1 A2 A3 A4 A5 A6 A7 B0 B1 B2 B3 B4 B5 B6 B7 C0 C1 C2 C3 C4 C5 C6 C7 D0 D1 D2 D3 D4 D5 D6 D7 E0 E1 E2 E3 E4 E5 E6 E7 F0 F1 F2 F3 F4 F5 F6 F7 - * The logical pins 46 and 47 are not supported by Teensyduino, but are supported below as E2 and E3 + * Logical pins 46-47 aren't supported by Teensyduino, but are supported below as E2 and E3 */ #include "../fastio.h" diff --git a/Marlin/src/HAL/AVR/pinsDebug.h b/Marlin/src/HAL/AVR/pinsDebug.h index 15db63b4d7f8..e9bc09a4bf5b 100644 --- a/Marlin/src/HAL/AVR/pinsDebug.h +++ b/Marlin/src/HAL/AVR/pinsDebug.h @@ -22,7 +22,23 @@ #pragma once /** - * PWM print routines for Atmel 8 bit AVR CPUs + * Pins Debugging for Atmel 8 bit AVR CPUs + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #include "../../inc/MarlinConfig.h" @@ -39,44 +55,44 @@ #include "pinsDebug_Teensyduino.h" // Can't use the "digitalPinToPort" function from the Teensyduino type IDEs // portModeRegister takes a different argument - #define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p) - #define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p) - #define digitalPinToPort_DEBUG(p) digitalPinToPort(p) - #define GET_PINMODE(pin) (*portModeRegister(pin) & digitalPinToBitMask_DEBUG(pin)) + #define digitalPinToTimer_DEBUG(P) digitalPinToTimer(P) + #define digitalPinToBitMask_DEBUG(P) digitalPinToBitMask(P) + #define digitalPinToPort_DEBUG(P) digitalPinToPort(P) + #define getValidPinMode(P) (*portModeRegister(P) & digitalPinToBitMask_DEBUG(P)) #elif AVR_ATmega2560_FAMILY_PLUS_70 // So we can access/display all the pins on boards using more than 70 #include "pinsDebug_plus_70.h" - #define digitalPinToTimer_DEBUG(p) digitalPinToTimer_plus_70(p) - #define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask_plus_70(p) - #define digitalPinToPort_DEBUG(p) digitalPinToPort_plus_70(p) - bool GET_PINMODE(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); } + #define digitalPinToTimer_DEBUG(P) digitalPinToTimer_plus_70(P) + #define digitalPinToBitMask_DEBUG(P) digitalPinToBitMask_plus_70(P) + #define digitalPinToPort_DEBUG(P) digitalPinToPort_plus_70(P) + bool getValidPinMode(pin_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); } #else - #define digitalPinToTimer_DEBUG(p) digitalPinToTimer(p) - #define digitalPinToBitMask_DEBUG(p) digitalPinToBitMask(p) - #define digitalPinToPort_DEBUG(p) digitalPinToPort(p) - bool GET_PINMODE(int8_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); } - #define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin) + #define digitalPinToTimer_DEBUG(P) digitalPinToTimer(P) + #define digitalPinToBitMask_DEBUG(P) digitalPinToBitMask(P) + #define digitalPinToPort_DEBUG(P) digitalPinToPort(P) + bool getValidPinMode(pin_t pin) {return *portModeRegister(digitalPinToPort_DEBUG(pin)) & digitalPinToBitMask_DEBUG(pin); } + #define getPinByIndex(x) pgm_read_byte(&pin_array[x].pin) #endif -#define VALID_PIN(pin) (pin >= 0 && pin < NUM_DIGITAL_PINS ? 1 : 0) +#define isValidPin(P) (P >= 0 && P < NUMBER_PINS_TOTAL) #if AVR_ATmega1284_FAMILY - #define IS_ANALOG(P) WITHIN(P, analogInputToDigitalPin(7), analogInputToDigitalPin(0)) - #define DIGITAL_PIN_TO_ANALOG_PIN(P) int(IS_ANALOG(P) ? (P) - analogInputToDigitalPin(7) : -1) + #define isAnalogPin(P) WITHIN(P, analogInputToDigitalPin(7), analogInputToDigitalPin(0)) + #define digitalPinToAnalogIndex(P) int(isAnalogPin(P) ? (P) - analogInputToDigitalPin(7) : -1) #else #define _ANALOG1(P) WITHIN(P, analogInputToDigitalPin(0), analogInputToDigitalPin(7)) #define _ANALOG2(P) WITHIN(P, analogInputToDigitalPin(8), analogInputToDigitalPin(15)) - #define IS_ANALOG(P) (_ANALOG1(P) || _ANALOG2(P)) - #define DIGITAL_PIN_TO_ANALOG_PIN(P) int(_ANALOG1(P) ? (P) - analogInputToDigitalPin(0) : _ANALOG2(P) ? (P) - analogInputToDigitalPin(8) + 8 : -1) + #define isAnalogPin(P) (_ANALOG1(P) || _ANALOG2(P)) + #define digitalPinToAnalogIndex(P) int(_ANALOG1(P) ? (P) - analogInputToDigitalPin(0) : _ANALOG2(P) ? (P) - analogInputToDigitalPin(8) + 8 : -1) #endif -#define GET_ARRAY_PIN(p) pgm_read_byte(&pin_array[p].pin) +#define getPinByIndex(x) pgm_read_byte(&pin_array[x].pin) #define MULTI_NAME_PAD 26 // space needed to be pretty if not first name assigned to a pin -void PRINT_ARRAY_NAME(uint8_t x) { - PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[x].name); +void printPinNameByIndex(const uint8_t index) { + PGM_P const name_mem_pointer = (PGM_P)pgm_read_ptr(&pin_array[index].name); for (uint8_t y = 0; y < MAX_NAME_LENGTH; ++y) { char temp_char = pgm_read_byte(name_mem_pointer + y); if (temp_char != 0) @@ -88,7 +104,7 @@ void PRINT_ARRAY_NAME(uint8_t x) { } } -#define GET_ARRAY_IS_DIGITAL(x) pgm_read_byte(&pin_array[x].is_digital) +#define getPinIsDigitalByIndex(x) pgm_read_byte(&pin_array[x].is_digital) #if defined(__AVR_ATmega1284P__) // 1284 IDE extensions set this to the number of #undef NUM_DIGITAL_PINS // digital only pins while all other CPUs have it @@ -109,7 +125,7 @@ void PRINT_ARRAY_NAME(uint8_t x) { * Print a pin's PWM status. * Return true if it's currently a PWM pin. */ -bool pwm_status(uint8_t pin) { +bool pwm_status(const uint8_t pin) { char buffer[20]; // for the sprintf statements switch (digitalPinToTimer_DEBUG(pin)) { @@ -276,7 +292,7 @@ void timer_prefix(uint8_t T, char L, uint8_t N) { // T - timer L - pwm N - if (TEST(*TMSK, TOIE)) err_prob_interrupt(); } -void pwm_details(uint8_t pin) { +void printPinPWM(const uint8_t pin) { switch (digitalPinToTimer_DEBUG(pin)) { #if ABTEST(0) @@ -347,7 +363,7 @@ void pwm_details(uint8_t pin) { #else UNUSED(print_is_also_tied); #endif -} // pwm_details +} // printPinPWM #ifndef digitalRead_mod // Use Teensyduino's version of digitalRead - it doesn't disable the PWMs int digitalRead_mod(const pin_t pin) { // same as digitalRead except the PWM stop section has been removed @@ -356,7 +372,7 @@ void pwm_details(uint8_t pin) { } #endif -void print_port(const pin_t pin) { // print port number +void printPinPort(const pin_t pin) { // print port number #ifdef digitalPinToPort_DEBUG uint8_t x; SERIAL_ECHOPGM(" Port: "); @@ -386,7 +402,7 @@ void print_port(const pin_t pin) { // print port number #endif } -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) #undef ABTEST diff --git a/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h index c812d4fb1131..463a77ec1d08 100644 --- a/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h +++ b/Marlin/src/HAL/AVR/pinsDebug_Teensyduino.h @@ -102,7 +102,7 @@ const uint8_t PROGMEM digital_pin_to_port_PGM[] = { // digitalPinToBitMask(pin) is OK -#define digitalRead_mod(p) extDigitalRead(p) // Teensyduino's version of digitalRead doesn't +#define digitalRead_mod(P) extDigitalRead(P) // Teensyduino's version of digitalRead doesn't // disable the PWMs so we can use it as is // portModeRegister(pin) is OK diff --git a/Marlin/src/HAL/DUE/HAL.h b/Marlin/src/HAL/DUE/HAL.h index 49a8be3fe7bb..fde235ed8c03 100644 --- a/Marlin/src/HAL/DUE/HAL.h +++ b/Marlin/src/HAL/DUE/HAL.h @@ -127,7 +127,7 @@ typedef Servo hal_servo_t; #define HAL_ADC_RESOLUTION 10 #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) + #define analogInputToDigitalPin(p) pin_t((p < 12U) ? (p) + 54U : -1) #endif // diff --git a/Marlin/src/HAL/DUE/Servo.cpp b/Marlin/src/HAL/DUE/Servo.cpp index 2dab88238dd6..2f72d66b9bfc 100644 --- a/Marlin/src/HAL/DUE/Servo.cpp +++ b/Marlin/src/HAL/DUE/Servo.cpp @@ -50,7 +50,7 @@ static Flags<_Nbr_16timers> DisablePending; // ISR should disable the timer at the next timer reset // ------------------------ -/// Interrupt handler for the TC0 channel 1. +// Interrupt handler for the TC0 channel 1. // ------------------------ void Servo_Handler(const timer16_Sequence_t, Tc*, const uint8_t); diff --git a/Marlin/src/HAL/DUE/pinsDebug.h b/Marlin/src/HAL/DUE/pinsDebug.h index 1544853553f0..e9e364dcec77 100644 --- a/Marlin/src/HAL/DUE/pinsDebug.h +++ b/Marlin/src/HAL/DUE/pinsDebug.h @@ -19,13 +19,26 @@ * along with this program. If not, see . * */ +#pragma once /** - * Support routines for Due - */ - -/** - * Translation of routines & variables used by pinsDebug.h + * Pins Debugging for DUE + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #include "../shared/Marduino.h" @@ -63,20 +76,20 @@ #define NUMBER_PINS_TOTAL PINS_COUNT -#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL)) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) -#define IS_ANALOG(P) WITHIN(P, char(analogInputToDigitalPin(0)), char(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1))) -#define pwm_status(pin) (((g_pinStatus[pin] & 0xF) == PIN_STATUS_PWM) && \ - ((g_APinDescription[pin].ulPinAttribute & PIN_ATTR_PWM) == PIN_ATTR_PWM)) +#define digitalRead_mod(P) extDigitalRead(P) // AVR digitalRead disabled PWM before it read the pin +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define getPinByIndex(x) pin_array[x].pin +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0)) +#define isAnalogPin(P) WITHIN(P, pin_t(analogInputToDigitalPin(0)), pin_t(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1))) +#define pwm_status(P) (((g_pinStatus[P] & 0xF) == PIN_STATUS_PWM) && \ + ((g_APinDescription[P].ulPinAttribute & PIN_ATTR_PWM) == PIN_ATTR_PWM)) #define MULTI_NAME_PAD 14 // space needed to be pretty if not first name assigned to a pin -bool GET_PINMODE(int8_t pin) { // 1: output, 0: input +bool getValidPinMode(const pin_t pin) { // 1: output, 0: input volatile Pio* port = g_APinDescription[pin].pPort; uint32_t mask = g_APinDescription[pin].ulPin; uint8_t pin_status = g_pinStatus[pin] & 0xF; @@ -85,14 +98,14 @@ bool GET_PINMODE(int8_t pin) { // 1: output, 0: input || pwm_status(pin)); } -void pwm_details(int32_t pin) { +void printPinPWM(const int32_t pin) { if (pwm_status(pin)) { uint32_t chan = g_APinDescription[pin].ulPWMChannel; SERIAL_ECHOPGM("PWM = ", PWM_INTERFACE->PWM_CH_NUM[chan].PWM_CDTY); } } -void print_port(const pin_t) {} +void printPinPort(const pin_t) {} /** * DUE Board pin | PORT | Label diff --git a/Marlin/src/HAL/DUE/usb/README.md b/Marlin/src/HAL/DUE/usb/README.md new file mode 100644 index 000000000000..2548135aca07 --- /dev/null +++ b/Marlin/src/HAL/DUE/usb/README.md @@ -0,0 +1,29 @@ +# USB Files Source Documentation + +## Source + +We sourced the USB files in Marlin from the Atmel ASF (Advanced Software Framework). The framework provides a variety of examples which were utilized in this project. + +Atmel doesn't provide these files in a source repository but they can be extracted from ASF, which can be downloaded from Atmel. + +[Advanced Software Framework](https://www.microchip.com/en-us/tools-resources/develop/libraries/advanced-software-framework) + +## Modifications + +The files are mostly unmodified except for minor cosmetic changes but some more significant changes were needed. + +The changes that prompted the addition of this README file are listed below. Other changes may have been made prior to this. + +1. Modified `uotghs_device_due.c` to resolve race conditions that could leave interrupts asserted when freezing the peripheral clock, resulting in hangs and watchdog resets due to the ensuing interrupt storm. + +## Version Information + +We don't know the exact version of ASF used as the source. However, the copyright information in the files indicates they are from 2015. + +## Upgrade Considerations + +We looked at the ASF 3.52.0 files released in 2022 but saw no immediate benefits to justify an upgrade. It's important to note that the files in Marlin don't follow the same folder structure as the files in ASF, which complicates the process of comparing and applying updated files. + +When these files are updated it's important to carefully compare them to Marlin's versions so any improvements in the Marlin sources are brought forward. + +It would be best to make Marlin's directory structure align with ASF or at least document the source of each file to ease future updates. diff --git a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp index 65a926ff362b..8421ff34bdf6 100644 --- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp +++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.cpp @@ -18,32 +18,32 @@ extern "C" { void sd_mmc_spi_mem_init() { } +inline bool media_ready() { + return IS_SD_INSERTED() && !IS_SD_PRINTING() && !IS_SD_FILE_OPEN() && card.isMounted(); +} + +bool sd_mmc_spi_unload(bool) { return true; } + +bool sd_mmc_spi_wr_protect() { return false; } + +bool sd_mmc_spi_removal() { return !media_ready(); } + 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; + if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT; return CTRL_GOOD; } // NOTE: This function is defined as returning the address of the last block // in the card, which is cardSize() - 1 Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector) { - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; + if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT; *nb_sector = card.diskIODriver()->cardSize() - 1; return CTRL_GOOD; } -bool sd_mmc_spi_unload(bool) { return true; } - -bool sd_mmc_spi_wr_protect() { return false; } - -bool sd_mmc_spi_removal() { - return (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()); -} - #if ACCESS_USB == true /** * \name MEM <-> USB Interface @@ -61,8 +61,7 @@ Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector) { #ifdef DISABLE_DUE_SD_MMC return CTRL_NO_PRESENT; #endif - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; + if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT; #ifdef DEBUG_MMC { @@ -101,8 +100,7 @@ Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector) { #ifdef DISABLE_DUE_SD_MMC return CTRL_NO_PRESENT; #endif - if (!IS_SD_INSERTED() || IS_SD_PRINTING() || IS_SD_FILE_OPEN() || !card.isMounted()) - return CTRL_NO_PRESENT; + if (sd_mmc_spi_removal()) return CTRL_NO_PRESENT; #ifdef DEBUG_MMC { diff --git a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h index c0d3c925e80a..464d106e5293 100644 --- a/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h +++ b/Marlin/src/HAL/DUE/usb/sd_mmc_spi_mem.h @@ -74,7 +74,7 @@ //! //! @brief This function initializes the hw/sw resources required to drive the SD_MMC_SPI. //!/ -extern void sd_mmc_spi_mem_init(void); +void sd_mmc_spi_mem_init(); //! //! @brief This function tests the state of the SD_MMC memory and sends it to the Host. @@ -87,7 +87,7 @@ extern void sd_mmc_spi_mem_init(void); //! Media not present -> CTRL_NO_PRESENT //! Media has changed -> CTRL_BUSY //!/ -extern Ctrl_status sd_mmc_spi_test_unit_ready(void); +Ctrl_status sd_mmc_spi_test_unit_ready(); //! //! @brief This function gives the address of the last valid sector. @@ -98,7 +98,7 @@ extern Ctrl_status sd_mmc_spi_test_unit_ready(void); //! Media ready -> CTRL_GOOD //! Media not present -> CTRL_NO_PRESENT //!/ -extern Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector); +Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector); /*! \brief Unload/Load the SD/MMC card selected * @@ -109,7 +109,7 @@ extern Ctrl_status sd_mmc_spi_read_capacity(uint32_t *nb_sector); * * \return \c true if unload/load done success. */ -extern bool sd_mmc_spi_unload(bool unload); +bool sd_mmc_spi_unload(bool unload); //! //! @brief This function returns the write protected status of the memory. @@ -120,14 +120,14 @@ extern bool sd_mmc_spi_unload(bool unload); //! //! @return false -> the memory is not write-protected (always) //!/ -extern bool sd_mmc_spi_wr_protect(void); +bool sd_mmc_spi_wr_protect(); //! //! @brief This function tells if the memory has been removed or not. //! //! @return false -> The memory isn't removed //! -extern bool sd_mmc_spi_removal(void); +bool sd_mmc_spi_removal(); //---- ACCESS DATA FUNCTIONS ---- @@ -147,7 +147,7 @@ extern bool sd_mmc_spi_removal(void); //! It is ready -> CTRL_GOOD //! A error occur -> CTRL_FAIL //! -extern Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector); +Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector); //! This function initializes the SD/MMC memory for a write operation //! @@ -161,7 +161,7 @@ extern Ctrl_status sd_mmc_spi_usb_read_10(uint32_t addr, uint16_t nb_sector); //! It is ready -> CTRL_GOOD //! An error occurs -> CTRL_FAIL //! -extern Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector); +Ctrl_status sd_mmc_spi_usb_write_10(uint32_t addr, uint16_t nb_sector); #endif // #if ACCESS_USB == true diff --git a/Marlin/src/HAL/DUE/usb/uotghs_device_due.c b/Marlin/src/HAL/DUE/usb/uotghs_device_due.c index 6c0b133e01e8..01dda7e7fec8 100644 --- a/Marlin/src/HAL/DUE/usb/uotghs_device_due.c +++ b/Marlin/src/HAL/DUE/usb/uotghs_device_due.c @@ -116,6 +116,23 @@ //#define dbg_print printf #define dbg_print(...) +// Marlin modification: Redefine the otg_freeze_clock and otg_unfreeze_clock macros +// to add memory barriers to ensure that any accesses to USB registers aren't re-ordered +// to occur while the clock is frozen. +#undef otg_freeze_clock +#undef otg_unfreeze_clock + +#define otg_freeze_clock() do { \ + __DSB(); \ + Set_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK); \ +} while (0) + +#define otg_unfreeze_clock() \ +do { \ + Clr_bits(UOTGHS->UOTGHS_CTRL, UOTGHS_CTRL_FRZCLK); \ + __DSB(); \ +} while (0) + /** * \ingroup udd_group * \defgroup udd_udphs_group USB On-The-Go High-Speed Port for device mode (UOTGHS) @@ -604,6 +621,18 @@ ISR(UDD_USB_INT_FUN) // The wakeup interrupt is automatic acked when a suspend occur udd_disable_wake_up_interrupt(); udd_enable_suspend_interrupt(); + + // Marlin modification: The RESET, SOF, and MSOF interrupts were previously + // enabled in udd_attach, which caused a race condition where they could + // be raised and unclearable with the clock is frozen. They are now + // enabled here, after the clock has been unfrozen in response to the wake + // interrupt. + udd_enable_reset_interrupt(); + udd_enable_sof_interrupt(); +#ifdef USB_DEVICE_HS_SUPPORT + udd_enable_msof_interrupt(); +#endif + udd_sleep_mode(true); // Enter in IDLE mode #ifdef UDC_RESUME_EVENT UDC_RESUME_EVENT(); @@ -766,6 +795,28 @@ void udd_disable(void) cpu_irq_restore(flags); } +// Marlin modification: The original implementation did not use a memory +// barrier between disabling and clearing interrupts. This sometimes +// allowed interrupts to remain raised and unclearable after the clock +// was frozen. This helper was added to ensure that memory barriers +// are used consistently from all places where interrupts are disabled. +static void disable_and_ack_sync_interrupts() +{ + // Disable USB line events + udd_disable_reset_interrupt(); + udd_disable_sof_interrupt(); +#ifdef USB_DEVICE_HS_SUPPORT + udd_disable_msof_interrupt(); +#endif + __DSB(); + udd_ack_reset(); + udd_ack_sof(); +#ifdef USB_DEVICE_HS_SUPPORT + udd_ack_msof(); +#endif + __DSB(); +} + void udd_attach(void) { irqflags_t flags; @@ -785,17 +836,16 @@ void udd_attach(void) udd_attach_device(); // Enable USB line events - udd_enable_reset_interrupt(); udd_enable_suspend_interrupt(); udd_enable_wake_up_interrupt(); - udd_enable_sof_interrupt(); -#ifdef USB_DEVICE_HS_SUPPORT - udd_enable_msof_interrupt(); -#endif - // Reset following interrupts flag - udd_ack_reset(); - udd_ack_sof(); - udd_ack_msof(); + + // Marlin modification: The RESET, SOF, and MSOF interrupts were previously + // enabled here, which caused a race condition where they could be raised + // and unclearable with the clock is frozen. They are now enabled in the + // wake interrupt handler, after the clock has been unfrozen. They are now + // explicitly disabled here to ensure that they cannot be raised before + // the clock is frozen. + disable_and_ack_sync_interrupts(); // The first suspend interrupt must be forced // The first suspend interrupt is not detected else raise it @@ -812,6 +862,12 @@ void udd_detach(void) // Detach device from the bus udd_detach_device(); + + // Marlin modification: Added the explicit disabling of the RESET, SOF, and + // MSOF interrupts here, to ensure that they cannot be raised after the + // clock is frozen. + disable_and_ack_sync_interrupts(); + otg_freeze_clock(); udd_sleep_mode(false); } @@ -1997,6 +2053,12 @@ static bool udd_ep_interrupt(void) dbg_print("I "); udd_disable_in_send_interrupt(ep); // One bank is free then send a ZLP + + // Marlin modification: Add a barrier to ensure in_send is disabled + // before it is cleared. This was not an observed problem, but + // other interrupts were seen to misbehave without this barrier. + __DSB(); + udd_ack_in_send(ep); udd_ack_fifocon(ep); udd_ep_finish_job(ptr_job, false, ep); diff --git a/Marlin/src/HAL/ESP32/pinsDebug.h b/Marlin/src/HAL/ESP32/pinsDebug.h new file mode 100644 index 000000000000..42304b2a0be0 --- /dev/null +++ b/Marlin/src/HAL/ESP32/pinsDebug.h @@ -0,0 +1,71 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2024 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * Based on Sprinter and grbl. + * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +#error "PINS_DEBUGGING is not yet supported for ESP32!" + +/** + * Pins Debugging for ESP32 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) + */ + +#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS +#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin + +#define digitalRead_mod(P) extDigitalRead(P) +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define getPinByIndex(x) pin_array[x].pin +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0)) +#define isAnalogPin(P) WITHIN(P, pin_t(analogInputToDigitalPin(0)), pin_t(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1))) +bool pwm_status(const pin_t) { return false; } + +void printPinPort(const pin_t) {} + +static bool getValidPinMode(const pin_t pin) { + return isValidPin(pin) && !IS_INPUT(pin); +} + +void printPinPWM(const int32_t pin) { + if (pwm_status(pin)) { + //uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative; + //SERIAL_ECHOPGM("PWM = ", duty); + } +} diff --git a/Marlin/src/HAL/HC32/pinsDebug.h b/Marlin/src/HAL/HC32/pinsDebug.h new file mode 100644 index 000000000000..e80b5a081e4d --- /dev/null +++ b/Marlin/src/HAL/HC32/pinsDebug.h @@ -0,0 +1,180 @@ +/** + * Marlin 3D Printer Firmware + * Copyright (c) 2023 MarlinFirmware [https://github.com/MarlinFirmware/Marlin] + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + */ +#pragma once + +/** + * Pins Debugging for HC32 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) + */ + +#include "../../inc/MarlinConfig.h" +#include "fastio.h" +#include + +#ifndef BOARD_NR_GPIO_PINS + #error "Expected BOARD_NR_GPIO_PINS not found." +#endif + +#define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS +#define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS +#define isValidPin(P) IS_GPIO_PIN(P) + +// Note: pin_array is defined in `Marlin/src/pins/pinsDebug.h`, and since this file is included +// after it, it is available in this file as well. +#define getPinByIndex(x) pin_t(pin_array[x].pin) +#define digitalRead_mod(P) extDigitalRead(P) + +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(P)); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) + +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) + +#define MULTI_NAME_PAD 21 // Space needed to be pretty if not first name assigned to a pin + +// +// Pins that will cause a hang / reset / disconnect in M43 Toggle and Watch utils +// +#ifndef M43_NEVER_TOUCH + // Don't touch any of the following pins: + // - Host serial pins, and + // - Pins that could be connected to oscillators (see datasheet, Table 2.1): + // - XTAL = PH0, PH1 + // - XTAL32 = PC14, PC15 + #define IS_HOST_USART_PIN(Q) (Q == BOARD_USART2_TX_PIN || Q == BOARD_USART2_RX_PIN) + #define IS_OSC_PIN(Q) (Q == PH0 || Q == PH1 || Q == PC14 || Q == PC15) + + #define M43_NEVER_TOUCH(Q) (IS_HOST_USART_PIN(Q) || IS_OSC_PIN(Q)) +#endif + +int8_t digitalPinToAnalogIndex(const pin_t pin) { + if (!isValidPin(pin)) return -1; + const int8_t adc_channel = int8_t(PIN_MAP[pin].adc_info.channel); + return pin_t(adc_channel); +} + +bool isAnalogPin(pin_t pin) { + if (!isValidPin(pin)) return false; + + if (PIN_MAP[pin].adc_info.channel != ADC_PIN_INVALID) + return _GET_MODE(pin) == INPUT_ANALOG && !M43_NEVER_TOUCH(pin); + + return false; +} + +bool getValidPinMode(const pin_t pin) { + return isValidPin(pin) && !IS_INPUT(pin); +} + +bool getPinIsDigitalByIndex(const int16_t index) { + const pin_t pin = getPinByIndex(index); + return (!isAnalogPin(pin)); +} + +/** + * @brief print pin PWM status + * @return true if pin is currently a PWM pin, false otherwise + */ +bool pwm_status(const pin_t pin) { + // Get timer assignment for pin + timera_config_t *unit; + en_timera_channel_t channel; + en_port_func_t port_function; + if (!timera_get_assignment(pin, unit, channel, port_function) || unit == nullptr) { + // No pwm pin or no unit assigned + return false; + } + + // A pin that is PWM output is: + // - Assigned to a timerA unit (tested above) + // - Unit is initialized + // - Channel is active + // - PinMode is OUTPUT_PWM + return timera_is_unit_initialized(unit) && timera_is_channel_active(unit, channel) && getPinMode(pin) == OUTPUT_PWM; +} + +void printPinPWM(const pin_t pin) { + // Get timer assignment for pin + timera_config_t *unit; + en_timera_channel_t channel; + en_port_func_t port_function; + if (!timera_get_assignment(pin, unit, channel, port_function) || unit == nullptr) + return; // No pwm pin or no unit assigned + + // Print timer assignment of pin, eg. "TimerA1Ch2 Func4" + SERIAL_ECHOPGM("TimerA", TIMERA_REG_TO_X(unit->peripheral.register_base), + "Ch", TIMERA_CHANNEL_TO_X(channel), + " Func", int(port_function)); + SERIAL_ECHO_SP(3); // 3 spaces + + // Print timer unit state, eg. "1/16 PERAR=1234" OR "N/A" + if (timera_is_unit_initialized(unit)) { + // Unit initialized, print + // - Timer clock divider + // - Timer period value (PERAR) + const uint8_t clock_divider = timera_clk_div_to_n(unit->state.base_init->enClkDiv); + const uint16_t period = TIMERA_GetPeriodValue(unit->peripheral.register_base); + SERIAL_ECHOPGM("1/", clock_divider, " PERAR=", period); + } + else { + // Unit not initialized + SERIAL_ECHOPGM("N/A"); + return; + } + + SERIAL_ECHO_SP(3); // 3 spaces + + // Print timer channel state, e.g. "CMPAR=1234" OR "N/A" + if (timera_is_channel_active(unit, channel)) { + // Channel active, print + // - Channel compare value + const uint16_t compare = TIMERA_GetCompareValue(unit->peripheral.register_base, channel); + SERIAL_ECHOPGM("CMPAR=", compare); + } + else { + // Channel inactive + SERIAL_ECHOPGM("N/A"); + } +} + +void printPinPort(pin_t pin) { + const char port = 'A' + char(pin >> 4); // Pin div 16 + const int16_t gbit = PIN_MAP[pin].bit_pos; + char buffer[8]; + sprintf_P(buffer, PSTR("P%c%hd "), port, gbit); + if (gbit < 10) { + SERIAL_CHAR(' '); + } + + SERIAL_ECHO(buffer); +} diff --git a/Marlin/src/HAL/LINUX/hardware/Timer.cpp b/Marlin/src/HAL/LINUX/hardware/Timer.cpp index 9f0d6a8f3ae2..013690a404bf 100644 --- a/Marlin/src/HAL/LINUX/hardware/Timer.cpp +++ b/Marlin/src/HAL/LINUX/hardware/Timer.cpp @@ -37,7 +37,10 @@ Timer::Timer() { } Timer::~Timer() { - timer_delete(timerid); + if (timerid != 0) { + timer_delete(timerid); + timerid = 0; + } } void Timer::init(uint32_t sig_id, uint32_t sim_freq, callback_fn* fn) { diff --git a/Marlin/src/HAL/LINUX/include/pinmapping.h b/Marlin/src/HAL/LINUX/include/pinmapping.h index cfac5e3b48e4..9147ef82de74 100644 --- a/Marlin/src/HAL/LINUX/include/pinmapping.h +++ b/Marlin/src/HAL/LINUX/include/pinmapping.h @@ -37,29 +37,29 @@ constexpr uint8_t NUM_ANALOG_INPUTS = 16; constexpr uint8_t analog_offset = NUM_DIGITAL_PINS - NUM_ANALOG_INPUTS; // Get the digital pin for an analog index -constexpr pin_t analogInputToDigitalPin(const int8_t p) { - return (WITHIN(p, 0, NUM_ANALOG_INPUTS) ? analog_offset + p : P_NC); +constexpr pin_t analogInputToDigitalPin(const int8_t a) { + return (WITHIN(a, 0, NUM_ANALOG_INPUTS - 1) ? analog_offset + a : P_NC); } // Get the analog index for a digital pin -constexpr int8_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t p) { - return (WITHIN(p, analog_offset, NUM_DIGITAL_PINS) ? p - analog_offset : P_NC); +constexpr int8_t digitalPinToAnalogIndex(const pin_t pin) { + return (WITHIN(pin, analog_offset, NUM_DIGITAL_PINS - 1) ? pin - analog_offset : P_NC); } // Return the index of a pin number constexpr int16_t GET_PIN_MAP_INDEX(const pin_t pin) { return pin; } // Test whether the pin is valid -constexpr bool VALID_PIN(const pin_t p) { return WITHIN(p, 0, NUM_DIGITAL_PINS); } +constexpr bool isValidPin(const pin_t pin) { return WITHIN(pin, 0, NUM_DIGITAL_PINS - 1); } // Test whether the pin is PWM -constexpr bool PWM_PIN(const pin_t p) { return false; } +constexpr bool PWM_PIN(const pin_t) { return false; } // Test whether the pin is interruptible -constexpr bool INTERRUPT_PIN(const pin_t p) { return false; } +constexpr bool INTERRUPT_PIN(const pin_t) { return false; } // Get the pin number at the given index -constexpr pin_t GET_PIN_MAP_PIN(const int16_t ind) { return ind; } +constexpr pin_t GET_PIN_MAP_PIN(const int16_t index) { return pin_t(index); } // Parse a G-code word into a pin index int16_t PARSED_PIN_INDEX(const char code, const int16_t dval); diff --git a/Marlin/src/HAL/LINUX/pinsDebug.h b/Marlin/src/HAL/LINUX/pinsDebug.h index e4ee27e8dd01..aacb626105d1 100644 --- a/Marlin/src/HAL/LINUX/pinsDebug.h +++ b/Marlin/src/HAL/LINUX/pinsDebug.h @@ -19,30 +19,50 @@ * along with this program. If not, see . * */ +#pragma once /** - * Support routines for X86_64 - */ - -/** - * Translation of routines & variables used by pinsDebug.h + * Pins Debugging for Linux Native + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) -#define digitalRead_mod(p) digitalRead(p) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin +#define getPinByIndex(x) pin_array[x].pin + +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) + // active ADC function/mode/code values for PINSEL registers -constexpr int8_t ADC_pin_mode(pin_t pin) { return -1; } +constexpr int8_t ADC_pin_mode(const pin_t) { return -1; } + +// The pin and index are the same on this platform +bool getPinIsDigitalByIndex(const pin_t pin) { + return (!isAnalogPin(pin) || get_pin_mode(pin) != ADC_pin_mode(pin)); +} + +#define isAnalogPin(P) (digitalPinToAnalogIndex(P) >= 0) -int8_t get_pin_mode(const pin_t pin) { return VALID_PIN(pin) ? 0 : -1; } +#define digitalRead_mod(P) digitalRead(P) -bool GET_PINMODE(const pin_t pin) { +int8_t get_pin_mode(const pin_t pin) { return isValidPin(pin) ? 0 : -1; } + +bool getValidPinMode(const pin_t pin) { const int8_t pin_mode = get_pin_mode(pin); if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // Invalid pin or active analog pin return false; @@ -50,11 +70,11 @@ bool GET_PINMODE(const pin_t pin) { return (Gpio::getMode(pin) != 0); // Input/output state } -bool GET_ARRAY_IS_DIGITAL(const pin_t pin) { - return (!IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin)); -} - -void pwm_details(const pin_t pin) {} +void printPinPWM(const pin_t) {} bool pwm_status(const pin_t) { return false; } -void print_port(const pin_t) {} +void printPinPort(const pin_t) {} + +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0) + +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) diff --git a/Marlin/src/HAL/LPC1768/pinsDebug.h b/Marlin/src/HAL/LPC1768/pinsDebug.h index 975511be9a94..5baeadd0dd72 100644 --- a/Marlin/src/HAL/LPC1768/pinsDebug.h +++ b/Marlin/src/HAL/LPC1768/pinsDebug.h @@ -19,22 +19,35 @@ * along with this program. If not, see . * */ +#pragma once /** - * Support routines for LPC1768 - */ - -/** - * Translation of routines & variables used by pinsDebug.h + * Pins Debugging for LPC1768/9 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) -#define digitalRead_mod(p) extDigitalRead(p) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("P%d_%02d"), LPC176x::pin_port(p), LPC176x::pin_bit(p)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(pin)); SERIAL_ECHO(buffer); }while(0) +#define isAnalogPin(P) (digitalPinToAnalogIndex(P) >= 0) +#define digitalRead_mod(P) extDigitalRead(P) +#define getPinByIndex(x) pin_array[x].pin +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("P%d_%02d"), LPC176x::pin_port(P), LPC176x::pin_bit(P)); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR("_A%d "), LPC176x::pin_get_adc_channel(P)); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 17 // space needed to be pretty if not first name assigned to a pin // pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities @@ -42,15 +55,15 @@ #define M43_NEVER_TOUCH(Q) ((Q) == P0_29 || (Q) == P0_30 || (Q) == P2_09) // USB pins #endif -bool GET_PINMODE(const pin_t pin) { +bool getValidPinMode(const pin_t pin) { if (!LPC176x::pin_is_valid(pin) || LPC176x::pin_adc_enabled(pin)) // Invalid pin or active analog pin return false; return LPC176x::gpio_direction(pin); } -#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital) +#define getPinIsDigitalByIndex(x) ((bool) pin_array[x].is_digital) -void print_port(const pin_t) {} -void pwm_details(const pin_t) {} +void printPinPort(const pin_t) {} +void printPinPWM(const pin_t) {} bool pwm_status(const pin_t) { return false; } diff --git a/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h index 1ac02f118285..fc20373d6326 100644 --- a/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h +++ b/Marlin/src/HAL/NATIVE_SIM/inc/Conditionals_post.h @@ -20,3 +20,24 @@ * */ #pragma once + +// Newer simulator needs these +#define X_MIN_ENDSTOP_HIT_STATE DISABLED(X_MIN_ENDSTOP_INVERTING) +#define Y_MIN_ENDSTOP_HIT_STATE DISABLED(Y_MIN_ENDSTOP_INVERTING) +#define Z_MIN_ENDSTOP_HIT_STATE DISABLED(Z_MIN_ENDSTOP_INVERTING) +#define I_MIN_ENDSTOP_HIT_STATE DISABLED(I_MIN_ENDSTOP_INVERTING) +#define J_MIN_ENDSTOP_HIT_STATE DISABLED(J_MIN_ENDSTOP_INVERTING) +#define K_MIN_ENDSTOP_HIT_STATE DISABLED(K_MIN_ENDSTOP_INVERTING) +#define U_MIN_ENDSTOP_HIT_STATE DISABLED(U_MIN_ENDSTOP_INVERTING) +#define V_MIN_ENDSTOP_HIT_STATE DISABLED(V_MIN_ENDSTOP_INVERTING) +#define W_MIN_ENDSTOP_HIT_STATE DISABLED(W_MIN_ENDSTOP_INVERTING) +#define X_MAX_ENDSTOP_HIT_STATE DISABLED(X_MAX_ENDSTOP_INVERTING) +#define Y_MAX_ENDSTOP_HIT_STATE DISABLED(Y_MAX_ENDSTOP_INVERTING) +#define Z_MAX_ENDSTOP_HIT_STATE DISABLED(Z_MAX_ENDSTOP_INVERTING) +#define I_MAX_ENDSTOP_HIT_STATE DISABLED(I_MAX_ENDSTOP_INVERTING) +#define J_MAX_ENDSTOP_HIT_STATE DISABLED(J_MAX_ENDSTOP_INVERTING) +#define K_MAX_ENDSTOP_HIT_STATE DISABLED(K_MAX_ENDSTOP_INVERTING) +#define U_MAX_ENDSTOP_HIT_STATE DISABLED(U_MAX_ENDSTOP_INVERTING) +#define V_MAX_ENDSTOP_HIT_STATE DISABLED(V_MAX_ENDSTOP_INVERTING) +#define W_MAX_ENDSTOP_HIT_STATE DISABLED(W_MAX_ENDSTOP_INVERTING) +#define Z_MIN_PROBE_ENDSTOP_HIT_STATE DISABLED(Z_MIN_PROBE_ENDSTOP_INVERTING) diff --git a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.cpp b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.cpp index c4d56c6c218d..1354c79b31ef 100644 --- a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.cpp +++ b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.cpp @@ -25,11 +25,11 @@ #include "../../inc/MarlinConfig.h" #include "pinsDebug.h" -int8_t ADC_pin_mode(pin_t pin) { return -1; } +int8_t ADC_pin_mode(const pin_t) { return -1; } -int8_t get_pin_mode(const pin_t pin) { return VALID_PIN(pin) ? 0 : -1; } +int8_t get_pin_mode(const pin_t pin) { return isValidPin(pin) ? 0 : -1; } -bool GET_PINMODE(const pin_t pin) { +bool getValidPinMode(const pin_t pin) { const int8_t pin_mode = get_pin_mode(pin); if (pin_mode == -1 || pin_mode == ADC_pin_mode(pin)) // Invalid pin or active analog pin return false; @@ -37,12 +37,13 @@ bool GET_PINMODE(const pin_t pin) { return (Gpio::getMode(pin) != 0); // Input/output state } -bool GET_ARRAY_IS_DIGITAL(const pin_t pin) { - return !IS_ANALOG(pin) || get_pin_mode(pin) != ADC_pin_mode(pin); +// The pin and index are the same on this platform +bool getPinIsDigitalByIndex(const pin_t pin) { + return !isAnalogPin(pin) || get_pin_mode(pin) != ADC_pin_mode(pin); } -void print_port(const pin_t) {} -void pwm_details(const pin_t) {} +void printPinPort(const pin_t) {} +void printPinPWM(const pin_t) {} bool pwm_status(const pin_t) { return false; } #endif diff --git a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h index 3321d1484dbe..752802d43808 100644 --- a/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h +++ b/Marlin/src/HAL/NATIVE_SIM/pinsDebug.h @@ -19,30 +19,43 @@ * along with this program. If not, see . * */ - -/** - * Support routines for X86_64 - */ #pragma once /** - * Translation of routines & variables used by pinsDebug.h + * Pins Debugging for x86_64 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P) >= 0 ? 1 : 0) -#define digitalRead_mod(p) digitalRead(p) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define isAnalogPin(P) (digitalPinToAnalogIndex(P) >= 0) +#define digitalRead_mod(P) digitalRead(P) +#define getPinByIndex(x) pin_array[x].pin +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin // Active ADC function/mode/code values for PINSEL registers -int8_t ADC_pin_mode(pin_t pin); -int8_t get_pin_mode(const pin_t pin); -bool GET_PINMODE(const pin_t pin); -bool GET_ARRAY_IS_DIGITAL(const pin_t pin); -void print_port(const pin_t); -void pwm_details(const pin_t); +int8_t ADC_pin_mode(const pin_t); +int8_t get_pin_mode(const pin_t); +bool getValidPinMode(const pin_t); +bool getPinIsDigitalByIndex(const pin_t); +void printPinPort(const pin_t); +void printPinPWM(const pin_t); bool pwm_status(const pin_t); diff --git a/Marlin/src/HAL/SAMD21/HAL.h b/Marlin/src/HAL/SAMD21/HAL.h index b9d428ae2e8e..95f391fa8678 100644 --- a/Marlin/src/HAL/SAMD21/HAL.h +++ b/Marlin/src/HAL/SAMD21/HAL.h @@ -111,7 +111,7 @@ typedef Servo hal_servo_t; #define HAL_ADC_FILTERED 1 // Disable Marlin's oversampling. The HAL filters ADC values. #define HAL_ADC_VREF_MV 3300 -#define HAL_ADC_RESOLUTION 12 +#define HAL_ADC_RESOLUTION 12 #define HAL_ADC_AIN_START ADC_INPUTCTRL_MUXPOS_PIN3 #define HAL_ADC_AIN_NUM_SENSORS 3 #define HAL_ADC_AIN_LEN HAL_ADC_AIN_NUM_SENSORS-1 diff --git a/Marlin/src/HAL/SAMD21/fastio.h b/Marlin/src/HAL/SAMD21/fastio.h index 471e8b62abc7..32cc5575281f 100644 --- a/Marlin/src/HAL/SAMD21/fastio.h +++ b/Marlin/src/HAL/SAMD21/fastio.h @@ -152,7 +152,7 @@ : ((P) == 14) ? ADC_INPUTCTRL_MUXPOS_PIN14 \ : ADC_INPUTCTRL_MUXPOS_PIN15) -#define digitalPinToAnalogInput(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1) +#define digitalPinToAnalogIndex(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1) /** * pins diff --git a/Marlin/src/HAL/SAMD21/pinsDebug.h b/Marlin/src/HAL/SAMD21/pinsDebug.h index f94315cdf539..387516aa7930 100644 --- a/Marlin/src/HAL/SAMD21/pinsDebug.h +++ b/Marlin/src/HAL/SAMD21/pinsDebug.h @@ -22,42 +22,57 @@ #pragma once /** - * SAMD21 HAL developed by Bart Meijer (brupje) - * Based on SAMD51 HAL by Giuliano Zaro (AKA GMagician) + * Pins Debugging for SAMD21 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #define NUMBER_PINS_TOTAL PINS_COUNT -#define digitalRead_mod(p) extDigitalRead(p) -#define PRINT_PORT(p) do{ SERIAL_ECHOPGM(" Port: "); sprintf_P(buffer, PSTR("%c%02ld"), 'A' + g_APinDescription[p].ulPort, g_APinDescription[p].ulPin); SERIAL_ECHO(buffer); }while (0) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < (int8_t)NUMBER_PINS_TOTAL) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p) -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1) -#define pwm_status(pin) digitalPinHasPWM(pin) +#define digitalRead_mod(P) extDigitalRead(P) +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define getPinByIndex(x) pin_array[x].pin +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define isAnalogPin(P) (digitalPinToAnalogIndex(P) != -1) +#define pwm_status(P) digitalPinHasPWM(P) #define MULTI_NAME_PAD 27 // 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 #define M43_NEVER_TOUCH(Q) ((Q) >= 75) -bool GET_PINMODE(int8_t pin) { // 1: output, 0: input +bool getValidPinMode(const int8_t pin) { // 1: output, 0: input const EPortType samdport = g_APinDescription[pin].ulPort; const uint32_t samdpin = g_APinDescription[pin].ulPin; return PORT->Group[samdport].DIR.reg & MASK(samdpin) || (PORT->Group[samdport].PINCFG[samdpin].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN; } -void pwm_details(int32_t pin) { +void printPinPWM(const int32_t pin) { if (pwm_status(pin)) { //uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative; //SERIAL_ECHOPGM("PWM = ", duty); } } +void printPinPort(const pin_t) {} + /** * SAMD21 Board pin| PORT | Label * ----------------+--------+------- diff --git a/Marlin/src/HAL/SAMD51/fastio.h b/Marlin/src/HAL/SAMD51/fastio.h index 3d43bdb24d8b..1a67b6ce2052 100644 --- a/Marlin/src/HAL/SAMD51/fastio.h +++ b/Marlin/src/HAL/SAMD51/fastio.h @@ -174,7 +174,7 @@ : (P == 17) ? PIN_TO_SAMD_PIN(13) \ : PIN_TO_SAMD_PIN(9)) - #define digitalPinToAnalogInput(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1) + #define digitalPinToAnalogIndex(P) (WITHIN(P, 67, 74) ? (P) - 67 : WITHIN(P, 54, 61) ? 8 + (P) - 54 : WITHIN(P, 12, 13) ? 16 + (P) - 12 : P == 9 ? 18 : -1) /** * pins diff --git a/Marlin/src/HAL/SAMD51/pinsDebug.h b/Marlin/src/HAL/SAMD51/pinsDebug.h index 94f91c77bcce..1518c615c934 100644 --- a/Marlin/src/HAL/SAMD51/pinsDebug.h +++ b/Marlin/src/HAL/SAMD51/pinsDebug.h @@ -22,41 +22,57 @@ #pragma once /** - * SAMD51 HAL developed by Giuliano Zaro (AKA GMagician) + * Pins Debugging for SAMD51 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #define NUMBER_PINS_TOTAL PINS_COUNT -#define digitalRead_mod(p) extDigitalRead(p) -#define PRINT_PORT(p) do{ SERIAL_ECHOPGM(" Port: "); sprintf_P(buffer, PSTR("%c%02ld"), 'A' + g_APinDescription[p].ulPort, g_APinDescription[p].ulPin); SERIAL_ECHO(buffer); }while (0) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3d "), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL)) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) digitalPinToAnalogInput(p) -#define IS_ANALOG(P) (DIGITAL_PIN_TO_ANALOG_PIN(P)!=-1) -#define pwm_status(pin) digitalPinHasPWM(pin) +#define digitalRead_mod(P) extDigitalRead(P) +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3d "), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define getPinByIndex(x) pin_array[x].pin +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define isAnalogPin(P) (digitalPinToAnalogIndex(P) != -1) +#define pwm_status(P) digitalPinHasPWM(P) #define MULTI_NAME_PAD 27 // 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 #define M43_NEVER_TOUCH(Q) ((Q) >= 75) -bool GET_PINMODE(int8_t pin) { // 1: output, 0: input +bool getValidPinMode(const int8_t pin) { // 1: output, 0: input const EPortType samdport = g_APinDescription[pin].ulPort; const uint32_t samdpin = g_APinDescription[pin].ulPin; return PORT->Group[samdport].DIR.reg & MASK(samdpin) || (PORT->Group[samdport].PINCFG[samdpin].reg & (PORT_PINCFG_INEN | PORT_PINCFG_PULLEN)) == PORT_PINCFG_PULLEN; } -void pwm_details(int32_t pin) { +void printPinPWM(const int32_t pin) { if (pwm_status(pin)) { //uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative; //SERIAL_ECHOPGM("PWM = ", duty); } } +void printPinPort(const pin_t) {} + /** * AGCM4 Board pin | PORT | Label * ----------------+--------+------- diff --git a/Marlin/src/HAL/STM32/HAL.h b/Marlin/src/HAL/STM32/HAL.h index 88cbaa536a5c..d6e9bc9aaba2 100644 --- a/Marlin/src/HAL/STM32/HAL.h +++ b/Marlin/src/HAL/STM32/HAL.h @@ -120,7 +120,7 @@ * TODO: review this to return 1 for pins that are not analog input */ #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) (p) + #define analogInputToDigitalPin(p) pin_t(p) #endif // diff --git a/Marlin/src/HAL/STM32/pinsDebug.h b/Marlin/src/HAL/STM32/pinsDebug.h index 13990a69f5ef..21cd2de39fef 100644 --- a/Marlin/src/HAL/STM32/pinsDebug.h +++ b/Marlin/src/HAL/STM32/pinsDebug.h @@ -21,6 +21,26 @@ */ #pragma once +/** + * Pins Debugging for STM32 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) + */ + #include #ifndef NUM_DIGITAL_PINS @@ -34,11 +54,11 @@ * that a CPU has. * * VARIABLES: - * Ard_num - Arduino pin number - defined by the platform. It is used by digitalRead and - * digitalWrite commands and by M42. - * - does not contain port/pin info - * - is not in port/pin order - * - typically a variant will only assign Ard_num to port/pins that are actually used + * A - Arduino pin number - defined by the platform. It is used by digitalRead and + * digitalWrite commands and by M42. + * - does not contain port/pin info + * - is not in port/pin order + * - typically a variant will only assign Ard_num to port/pins that are actually used * Index - M43 counter - only used to get Ard_num * x - a parameter/argument used to search the pin_array to try to find a signal name * associated with a Ard_num @@ -98,15 +118,11 @@ const XrefInfo pin_xref[] PROGMEM = { #define MODE_PIN_ALT 2 // Alternate function mode #define MODE_PIN_ANALOG 3 // Analog mode -#define PIN_NUM(P) (P & 0x000F) -#define PIN_NUM_ALPHA_LEFT(P) (((P & 0x000F) < 10) ? ('0' + (P & 0x000F)) : '1') -#define PIN_NUM_ALPHA_RIGHT(P) (((P & 0x000F) > 9) ? ('0' + (P & 0x000F) - 10) : 0 ) -#define PORT_NUM(P) ((P >> 4) & 0x0007) -#define PORT_ALPHA(P) ('A' + (P >> 4)) - -/** - * Translation of routines & variables used by pinsDebug.h - */ +#define PIN_NUM(P) ((P) & 0x000F) +#define PIN_NUM_ALPHA_LEFT(P) ((((P) & 0x000F) < 10) ? ('0' + ((P) & 0x000F)) : '1') +#define PIN_NUM_ALPHA_RIGHT(P) ((((P) & 0x000F) > 9) ? ('0' + ((P) & 0x000F) - 10) : 0 ) +#define PORT_NUM(P) (((P) >> 4) & 0x0007) +#define PORT_ALPHA(P) ('A' + ((P) >> 4)) #if NUM_ANALOG_FIRST >= NUM_DIGITAL_PINS #define HAS_HIGH_ANALOG_PINS 1 @@ -115,42 +131,42 @@ const XrefInfo pin_xref[] PROGMEM = { #define NUM_ANALOG_LAST ((NUM_ANALOG_FIRST) + (NUM_ANALOG_INPUTS) - 1) #endif #define NUMBER_PINS_TOTAL ((NUM_DIGITAL_PINS) + TERN0(HAS_HIGH_ANALOG_PINS, NUM_ANALOG_INPUTS)) -#define VALID_PIN(P) (WITHIN(P, 0, (NUM_DIGITAL_PINS) - 1) || TERN0(HAS_HIGH_ANALOG_PINS, WITHIN(P, NUM_ANALOG_FIRST, NUM_ANALOG_LAST))) -#define digitalRead_mod(Ard_num) extDigitalRead(Ard_num) // must use Arduino pin numbers when doing reads -#define PRINT_PIN(Q) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define DIGITAL_PIN_TO_ANALOG_PIN(ANUM) -1 // will report analog pin number in the print port routine +#define isValidPin(P) (WITHIN(P, 0, (NUM_DIGITAL_PINS) - 1) || TERN0(HAS_HIGH_ANALOG_PINS, WITHIN(P, NUM_ANALOG_FIRST, NUM_ANALOG_LAST))) +#define digitalRead_mod(A) extDigitalRead(A) // must use Arduino pin numbers when doing reads +#define printPinNumber(Q) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define digitalPinToAnalogIndex(P) -1 // will report analog pin number in the print port routine // x is a variable used to search pin_array -#define GET_ARRAY_IS_DIGITAL(x) ((bool) pin_array[x].is_digital) -#define GET_ARRAY_PIN(x) ((pin_t) pin_array[x].pin) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define getPinIsDigitalByIndex(x) ((bool) pin_array[x].is_digital) +#define getPinByIndex(x) ((pin_t) pin_array[x].pin) +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 33 // space needed to be pretty if not first name assigned to a pin // // Pin Mapping for M43 // -#define GET_PIN_MAP_PIN_M43(Index) pin_xref[Index].Ard_num +#define GET_PIN_MAP_PIN_M43(x) pin_xref[x].Ard_num #ifndef M43_NEVER_TOUCH - #define _M43_NEVER_TOUCH(Index) (Index >= 9 && Index <= 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP) + #define _M43_NEVER_TOUCH(x) WITHIN(x, 9, 12) // SERIAL/USB pins: PA9(TX) PA10(RX) PA11(USB_DM) PA12(USB_DP) #ifdef KILL_PIN - #define M43_NEVER_TOUCH(Index) m43_never_touch(Index) + #define M43_NEVER_TOUCH(x) m43_never_touch(x) - bool m43_never_touch(const pin_t Index) { + bool m43_never_touch(const pin_t index) { static pin_t M43_kill_index = -1; if (M43_kill_index < 0) for (M43_kill_index = 0; M43_kill_index < NUMBER_PINS_TOTAL; M43_kill_index++) if (KILL_PIN == GET_PIN_MAP_PIN_M43(M43_kill_index)) break; - return _M43_NEVER_TOUCH(Index) || Index == M43_kill_index; // KILL_PIN and SERIAL/USB + return _M43_NEVER_TOUCH(index) || index == M43_kill_index; // KILL_PIN and SERIAL/USB } #else - #define M43_NEVER_TOUCH(Index) _M43_NEVER_TOUCH(Index) + #define M43_NEVER_TOUCH(index) _M43_NEVER_TOUCH(index) #endif #endif -uint8_t get_pin_mode(const pin_t Ard_num) { - const PinName dp = digitalPinToPinName(Ard_num); +uint8_t get_pin_mode(const pin_t pin) { + const PinName dp = digitalPinToPinName(pin); uint32_t ll_pin = STM_LL_GPIO_PIN(dp); GPIO_TypeDef *port = get_GPIO_Port(STM_PORT(dp)); uint32_t mode = LL_GPIO_GetPinMode(port, ll_pin); @@ -164,41 +180,41 @@ uint8_t get_pin_mode(const pin_t Ard_num) { } } -bool GET_PINMODE(const pin_t Ard_num) { - const uint8_t pin_mode = get_pin_mode(Ard_num); +bool getValidPinMode(const pin_t pin) { + const uint8_t pin_mode = get_pin_mode(pin); return pin_mode == MODE_PIN_OUTPUT || pin_mode == MODE_PIN_ALT; // assume all alt definitions are PWM } -int8_t digital_pin_to_analog_pin(const pin_t Ard_num) { - if (WITHIN(Ard_num, NUM_ANALOG_FIRST, NUM_ANALOG_LAST)) - return Ard_num - NUM_ANALOG_FIRST; +int8_t digital_pin_to_analog_pin(const pin_t pin) { + if (WITHIN(pin, NUM_ANALOG_FIRST, NUM_ANALOG_LAST)) + return pin - NUM_ANALOG_FIRST; - const uint32_t ind = digitalPinToAnalogInput(Ard_num); + const int8_t ind = digitalPinToAnalogIndex(pin); return (ind < NUM_ANALOG_INPUTS) ? ind : -1; } -bool IS_ANALOG(const pin_t Ard_num) { - return get_pin_mode(Ard_num) == MODE_PIN_ANALOG; +bool isAnalogPin(const pin_t pin) { + return get_pin_mode(pin) == MODE_PIN_ANALOG; } -bool is_digital(const pin_t Ard_num) { - const uint8_t pin_mode = get_pin_mode(pin_array[Ard_num].pin); +bool is_digital(const pin_t pin) { + const uint8_t pin_mode = get_pin_mode(pin_array[pin].pin); return pin_mode == MODE_PIN_INPUT || pin_mode == MODE_PIN_OUTPUT; } -void print_port(const pin_t Ard_num) { +void printPinPort(const pin_t pin) { char buffer[16]; - pin_t Index; - for (Index = 0; Index < NUMBER_PINS_TOTAL; Index++) - if (Ard_num == GET_PIN_MAP_PIN_M43(Index)) break; + pin_t index; + for (index = 0; index < NUMBER_PINS_TOTAL; index++) + if (pin == GET_PIN_MAP_PIN_M43(index)) break; - const char * ppa = pin_xref[Index].Port_pin_alpha; + const char * ppa = pin_xref[index].Port_pin_alpha; sprintf_P(buffer, PSTR("%s"), ppa); SERIAL_ECHO(buffer); if (ppa[3] == '\0') SERIAL_CHAR(' '); // print analog pin number - const int8_t Port_pin = digital_pin_to_analog_pin(Ard_num); + const int8_t Port_pin = digital_pin_to_analog_pin(pin); if (Port_pin >= 0) { sprintf_P(buffer, PSTR(" (A%d) "), Port_pin); SERIAL_ECHO(buffer); @@ -208,8 +224,8 @@ void print_port(const pin_t Ard_num) { SERIAL_ECHO_SP(7); // Print number to be used with M42 - int calc_p = Ard_num; - if (Ard_num > NUM_DIGITAL_PINS) { + int calc_p = pin; + if (pin > NUM_DIGITAL_PINS) { calc_p -= NUM_ANALOG_FIRST; if (calc_p > 7) calc_p += 8; } @@ -222,15 +238,15 @@ void print_port(const pin_t Ard_num) { } } -bool pwm_status(const pin_t Ard_num) { - return get_pin_mode(Ard_num) == MODE_PIN_ALT; +bool pwm_status(const pin_t pin) { + return get_pin_mode(pin) == MODE_PIN_ALT; } -void pwm_details(const pin_t Ard_num) { +void printPinPWM(const pin_t pin) { #ifndef STM32F1xx - if (pwm_status(Ard_num)) { + if (pwm_status(pin)) { uint32_t alt_all = 0; - const PinName dp = digitalPinToPinName(Ard_num); + const PinName dp = digitalPinToPinName(pin); pin_t pin_number = uint8_t(PIN_NUM(dp)); const bool over_7 = pin_number >= 8; const uint8_t ind = over_7 ? 1 : 0; @@ -285,4 +301,4 @@ void pwm_details(const pin_t Ard_num) { #else // TODO: F1 doesn't support changing pins function, so we need to check the function of the PIN and if it's enabled #endif -} // pwm_details +} // printPinPWM diff --git a/Marlin/src/HAL/STM32F1/HAL.h b/Marlin/src/HAL/STM32F1/HAL.h index 52d3b805e611..1319af9c213e 100644 --- a/Marlin/src/HAL/STM32F1/HAL.h +++ b/Marlin/src/HAL/STM32F1/HAL.h @@ -147,7 +147,7 @@ * TODO: review this to return 1 for pins that are not analog input */ #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) (p) + #define analogInputToDigitalPin(p) pin_t(p) #endif #ifndef digitalPinHasPWM diff --git a/Marlin/src/HAL/STM32F1/pinsDebug.h b/Marlin/src/HAL/STM32F1/pinsDebug.h index 6f8e48f455bd..9191614587b4 100644 --- a/Marlin/src/HAL/STM32F1/pinsDebug.h +++ b/Marlin/src/HAL/STM32F1/pinsDebug.h @@ -22,11 +22,23 @@ #pragma once /** - * Support routines for MAPLE_STM32F1 - */ - -/** - * Translation of routines & variables used by pinsDebug.h + * Pins Debugging for Maple STM32F1 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #ifndef BOARD_NR_GPIO_PINS // Only in MAPLE_STM32F1 @@ -39,12 +51,12 @@ extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS]; #define NUM_DIGITAL_PINS BOARD_NR_GPIO_PINS #define NUMBER_PINS_TOTAL BOARD_NR_GPIO_PINS -#define VALID_PIN(pin) (pin >= 0 && pin < BOARD_NR_GPIO_PINS) -#define GET_ARRAY_PIN(p) pin_t(pin_array[p].pin) -#define digitalRead_mod(p) extDigitalRead(p) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(p)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define isValidPin(P) (P >= 0 && P < BOARD_NR_GPIO_PINS) +#define getPinByIndex(x) pin_t(pin_array[x].pin) +#define digitalRead_mod(P) extDigitalRead(P) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%3hd "), int16_t(P)); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 21 // space needed to be pretty if not first name assigned to a pin // pins that will cause hang/reset/disconnect in M43 Toggle and Watch utilities @@ -52,10 +64,10 @@ extern const stm32_pin_info PIN_MAP[BOARD_NR_GPIO_PINS]; #define M43_NEVER_TOUCH(Q) (Q >= 9 && Q <= 12) // SERIAL/USB pins PA9(TX) PA10(RX) #endif -int8_t get_pin_mode(const pin_t pin) { return VALID_PIN(pin) ? _GET_MODE(pin) : -1; } +int8_t get_pin_mode(const pin_t pin) { return isValidPin(pin) ? _GET_MODE(pin) : -1; } -pin_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) { - if (!VALID_PIN(pin)) return -1; +int8_t digitalPinToAnalogIndex(const pin_t pin) { + if (!isValidPin(pin)) return -1; pin_t adc_channel = pin_t(PIN_MAP[pin].adc_channel); #ifdef NUM_ANALOG_INPUTS if (adc_channel >= NUM_ANALOG_INPUTS) adc_channel = (pin_t)ADCx; @@ -63,8 +75,8 @@ pin_t DIGITAL_PIN_TO_ANALOG_PIN(const pin_t pin) { return adc_channel; } -bool IS_ANALOG(const pin_t pin) { - if (!VALID_PIN(pin)) return false; +bool isAnalogPin(const pin_t pin) { + if (!isValidPin(pin)) return false; if (PIN_MAP[pin].adc_channel != ADCx) { #ifdef NUM_ANALOG_INPUTS if (PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS) return false; @@ -74,13 +86,13 @@ bool IS_ANALOG(const pin_t pin) { return false; } -bool GET_PINMODE(const pin_t pin) { - return VALID_PIN(pin) && !IS_INPUT(pin); +bool getValidPinMode(const pin_t pin) { + return isValidPin(pin) && !IS_INPUT(pin); } -bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) { - const pin_t pin = GET_ARRAY_PIN(array_pin); - return (!IS_ANALOG(pin) +bool getPinIsDigitalByIndex(const int16_t index) { + const pin_t pin = getPinByIndex(index); + return (!isAnalogPin(pin) #ifdef NUM_ANALOG_INPUTS || PIN_MAP[pin].adc_channel >= NUM_ANALOG_INPUTS #endif @@ -89,7 +101,7 @@ bool GET_ARRAY_IS_DIGITAL(const int16_t array_pin) { #include "../../inc/MarlinConfig.h" // Allow pins/pins.h to set density -void pwm_details(const pin_t pin) { +void printPinPWM(const pin_t pin) { if (PWM_PIN(pin)) { timer_dev * const tdev = PIN_MAP[pin].timer_device; const uint8_t channel = PIN_MAP[pin].timer_channel; @@ -111,7 +123,7 @@ void pwm_details(const pin_t pin) { bool pwm_status(const pin_t pin) { return PWM_PIN(pin); } -void print_port(const pin_t pin) { +void printPinPort(const pin_t pin) { const char port = 'A' + char(pin >> 4); // pin div 16 const int16_t gbit = PIN_MAP[pin].gpio_bit; char buffer[8]; diff --git a/Marlin/src/HAL/TEENSY31_32/HAL.h b/Marlin/src/HAL/TEENSY31_32/HAL.h index 16594c16a821..659fcb72e56e 100644 --- a/Marlin/src/HAL/TEENSY31_32/HAL.h +++ b/Marlin/src/HAL/TEENSY31_32/HAL.h @@ -98,7 +98,7 @@ uint32_t __get_PRIMASK(void); // CMSIS // ------------------------ #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) + #define analogInputToDigitalPin(p) pin_t((p < 12U) ? (p) + 54U : -1) #endif #define HAL_ADC_VREF_MV 3300 diff --git a/Marlin/src/HAL/TEENSY31_32/pinsDebug.h b/Marlin/src/HAL/TEENSY31_32/pinsDebug.h index d4a91ce801c2..741909bf0a40 100644 --- a/Marlin/src/HAL/TEENSY31_32/pinsDebug.h +++ b/Marlin/src/HAL/TEENSY31_32/pinsDebug.h @@ -1 +1,71 @@ +/** + * 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 . + * + */ +#pragma once + #error "PINS_DEBUGGING is not yet supported for Teensy 3.1 / 3.2!" + +/** + * Pins Debugging for ESP32 + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) + */ + +#define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS +#define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin + +#define digitalRead_mod(P) extDigitalRead(P) +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) +#define getPinByIndex(x) pin_array[x].pin +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0)) +#define isAnalogPin(P) WITHIN(P, pin_t(analogInputToDigitalPin(0)), pin_t(analogInputToDigitalPin(NUM_ANALOG_INPUTS - 1))) +bool pwm_status(const pin_t) { return false; } + +void printPinPort(const pin_t) {} + +static bool getValidPinMode(const pin_t pin) { + return isValidPin(pin) /* && !IS_INPUT(pin) */ ; +} + +void printPinPWM(const int32_t pin) { + if (pwm_status(pin)) { + //uint32_t chan = g_APinDescription[pin].ulPWMChannel TODO when fast pwm is operative; + //SERIAL_ECHOPGM("PWM = ", duty); + } +} diff --git a/Marlin/src/HAL/TEENSY31_32/timers.h b/Marlin/src/HAL/TEENSY31_32/timers.h index 9fcbb6f232c9..3bbc2421e006 100644 --- a/Marlin/src/HAL/TEENSY31_32/timers.h +++ b/Marlin/src/HAL/TEENSY31_32/timers.h @@ -41,7 +41,7 @@ typedef uint32_t hal_timer_t; #define FTM0_TIMER_PRESCALE_BITS 0b011 #define FTM1_TIMER_PRESCALE_BITS 0b010 -#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7500kHz +#define FTM0_TIMER_RATE (F_BUS / (FTM0_TIMER_PRESCALE)) // 60MHz / 8 = 7.5MHz #define FTM1_TIMER_RATE (F_BUS / (FTM1_TIMER_PRESCALE)) // 60MHz / 4 = 15MHz #define HAL_TIMER_RATE (FTM0_TIMER_RATE) diff --git a/Marlin/src/HAL/TEENSY35_36/HAL.h b/Marlin/src/HAL/TEENSY35_36/HAL.h index 692133400390..44eafe5e6d1b 100644 --- a/Marlin/src/HAL/TEENSY35_36/HAL.h +++ b/Marlin/src/HAL/TEENSY35_36/HAL.h @@ -103,7 +103,7 @@ typedef int8_t pin_t; // ------------------------ #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) + #define analogInputToDigitalPin(p) pin_t((p < 12U) ? (p) + 54U : -1) #endif #define HAL_ADC_VREF_MV 3300 diff --git a/Marlin/src/HAL/TEENSY35_36/pinsDebug.h b/Marlin/src/HAL/TEENSY35_36/pinsDebug.h index 8526febf10e3..f0f61b8bbe8f 100644 --- a/Marlin/src/HAL/TEENSY35_36/pinsDebug.h +++ b/Marlin/src/HAL/TEENSY35_36/pinsDebug.h @@ -22,7 +22,23 @@ #pragma once /** - * HAL Pins Debugging for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + * Pins Debugging for Teensy 3.5 (MK64FX512) and Teensy 3.6 (MK66FX1M0) + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS @@ -53,9 +69,18 @@ #define TPM1_CH1_PIN 17 #endif -#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(9)) || ((P) >= analogInputToDigitalPin(12) && (P) <= analogInputToDigitalPin(20)) +#define getPinByIndex(x) pin_array[x].pin +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0)) +#define getValidPinMode(P) (isValidPin(P) && IS_OUTPUT(P)) +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) + +#define isAnalogPin(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(9)) || ((P) >= analogInputToDigitalPin(12) && (P) <= analogInputToDigitalPin(20)) -void print_analog_pin(char buffer[], int8_t pin) { +void printAnalogPin(char buffer[], int8_t pin) { if (pin <= 23) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 14)); else if (pin <= 39) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 19)); } @@ -77,7 +102,7 @@ void analog_pin_state(char buffer[], int8_t pin) { * Print a pin's PWM status. * Return true if it's currently a PWM pin. */ -bool pwm_status(int8_t pin) { +bool pwm_status(const int8_t pin) { char buffer[20]; // for the sprintf statements switch (pin) { FTM_CASE(0,0); @@ -108,4 +133,6 @@ bool pwm_status(int8_t pin) { SERIAL_ECHOPGM(" "); } -void pwm_details(uint8_t pin) { /* TODO */ } +void printPinPWM(const pin_t) { /* TODO */ } + +void printPinPort(const pin_t) {} diff --git a/Marlin/src/HAL/TEENSY40_41/HAL.h b/Marlin/src/HAL/TEENSY40_41/HAL.h index fa5971a68102..355d1d75ac53 100644 --- a/Marlin/src/HAL/TEENSY40_41/HAL.h +++ b/Marlin/src/HAL/TEENSY40_41/HAL.h @@ -133,7 +133,7 @@ typedef int8_t pin_t; // ------------------------ #ifndef analogInputToDigitalPin - #define analogInputToDigitalPin(p) ((p < 12U) ? (p) + 54U : -1) + #define analogInputToDigitalPin(p) pin_t((p < 12U) ? (p) + 54U : -1) #endif #define HAL_ADC_VREF_MV 3300 diff --git a/Marlin/src/HAL/TEENSY40_41/pinsDebug.h b/Marlin/src/HAL/TEENSY40_41/pinsDebug.h index 54f3cb5885a3..3307b3f71fd6 100644 --- a/Marlin/src/HAL/TEENSY40_41/pinsDebug.h +++ b/Marlin/src/HAL/TEENSY40_41/pinsDebug.h @@ -22,23 +22,39 @@ #pragma once /** - * HAL Pins Debugging for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + * Pins Debugging for Teensy 4.0 (IMXRT1062DVL6A) / 4.1 (IMXRT1062DVJ6A) + * + * - NUMBER_PINS_TOTAL + * - MULTI_NAME_PAD + * - getPinByIndex(index) + * - printPinNameByIndex(index) + * - getPinIsDigitalByIndex(index) + * - digitalPinToAnalogIndex(pin) + * - getValidPinMode(pin) + * - isValidPin(pin) + * - isAnalogPin(pin) + * - digitalRead_mod(pin) + * - pwm_status(pin) + * - printPinPWM(pin) + * - printPinPort(pin) + * - printPinNumber(pin) + * - printPinAnalog(pin) */ #warning "PINS_DEBUGGING is not fully supported for Teensy 4.0 / 4.1 so 'M43' may cause hangs." #define NUMBER_PINS_TOTAL NUM_DIGITAL_PINS -#define digitalRead_mod(p) extDigitalRead(p) // AVR digitalRead disabled PWM before it read the pin -#define PRINT_ARRAY_NAME(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN(p) do{ sprintf_P(buffer, PSTR("%02d"), p); SERIAL_ECHO(buffer); }while(0) -#define PRINT_PIN_ANALOG(p) do{ sprintf_P(buffer, PSTR(" (A%2d) "), DIGITAL_PIN_TO_ANALOG_PIN(pin)); SERIAL_ECHO(buffer); }while(0) -#define GET_ARRAY_PIN(p) pin_array[p].pin -#define GET_ARRAY_IS_DIGITAL(p) pin_array[p].is_digital -#define VALID_PIN(pin) (pin >= 0 && pin < int8_t(NUMBER_PINS_TOTAL)) -#define DIGITAL_PIN_TO_ANALOG_PIN(p) int(p - analogInputToDigitalPin(0)) -#define IS_ANALOG(P) ((P) >= analogInputToDigitalPin(0) && (P) <= analogInputToDigitalPin(13)) || ((P) >= analogInputToDigitalPin(14) && (P) <= analogInputToDigitalPin(17)) -#define GET_PINMODE(PIN) (VALID_PIN(pin) && IS_OUTPUT(pin)) +#define getPinByIndex(x) pin_array[x].pin +#define printPinNameByIndex(x) do{ sprintf_P(buffer, PSTR("%-" STRINGIFY(MAX_NAME_LENGTH) "s"), pin_array[x].name); SERIAL_ECHO(buffer); }while(0) +#define getPinIsDigitalByIndex(x) pin_array[x].is_digital +#define digitalPinToAnalogIndex(P) int(P - analogInputToDigitalPin(0)) +#define getValidPinMode(P) (isValidPin(P) && IS_OUTPUT(P)) +#define isValidPin(P) (P >= 0 && P < pin_t(NUMBER_PINS_TOTAL)) +#define isAnalogPin(P) (pin_t(P) >= analogInputToDigitalPin(0) && pin_t(P) <= analogInputToDigitalPin(13)) || (pin_t(P) >= analogInputToDigitalPin(14) && pin_t(P) <= analogInputToDigitalPin(17)) +#define digitalRead_mod(P) extDigitalRead(P) // AVR digitalRead disabled PWM before it read the pin +#define printPinNumber(P) do{ sprintf_P(buffer, PSTR("%02d"), P); SERIAL_ECHO(buffer); }while(0) +#define printPinAnalog(P) do{ sprintf_P(buffer, PSTR(" (A%2d) "), digitalPinToAnalogIndex(P)); SERIAL_ECHO(buffer); }while(0) #define MULTI_NAME_PAD 16 // space needed to be pretty if not first name assigned to a pin struct pwm_pin_info_struct { @@ -118,7 +134,7 @@ const struct pwm_pin_info_struct pwm_pin_info[] = { #endif }; -void print_analog_pin(char buffer[], const pin_t pin) { +void printAnalogPin(char buffer[], const pin_t pin) { if (pin <= 23) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 14)); else if (pin <= 41) sprintf_P(buffer, PSTR("(A%2d) "), int(pin - 24)); } @@ -149,6 +165,6 @@ bool pwm_status(const pin_t pin) { return (*(portConfigRegister(pin)) == info->muxval); } -void pwm_details(const pin_t) { /* TODO */ } +void printPinPWM(const pin_t) { /* TODO */ } -void print_port(const pin_t) {} +void printPinPort(const pin_t) {} diff --git a/Marlin/src/HAL/TEENSY40_41/timers.h b/Marlin/src/HAL/TEENSY40_41/timers.h index 3c7cda0b4e66..fc160ab8b895 100644 --- a/Marlin/src/HAL/TEENSY40_41/timers.h +++ b/Marlin/src/HAL/TEENSY40_41/timers.h @@ -36,13 +36,13 @@ typedef uint32_t hal_timer_t; #define HAL_TIMER_TYPE_MAX 0xFFFFFFFE -#define GPT_TIMER_RATE F_BUS_ACTUAL // 150MHz +#define GPT_TIMER_RATE (F_CPU / 4) // 150MHz (Can't use F_BUS_ACTUAL because it's extern volatile) #define GPT1_TIMER_PRESCALE 2 #define GPT2_TIMER_PRESCALE 10 -#define GPT1_TIMER_RATE (GPT_TIMER_RATE / GPT1_TIMER_PRESCALE) // 75MHz -#define GPT2_TIMER_RATE (GPT_TIMER_RATE / GPT2_TIMER_PRESCALE) // 15MHz +#define GPT1_TIMER_RATE (GPT_TIMER_RATE / GPT1_TIMER_PRESCALE) // 150MHz / 2 = 75MHz +#define GPT2_TIMER_RATE (GPT_TIMER_RATE / GPT2_TIMER_PRESCALE) // 150MHz / 10 = 15MHz #ifndef MF_TIMER_STEP #define MF_TIMER_STEP 0 // Timer Index for Stepper @@ -57,7 +57,8 @@ typedef uint32_t hal_timer_t; #define TEMP_TIMER_RATE 1000000 #define TEMP_TIMER_FREQUENCY 1000 -#define STEPPER_TIMER_RATE GPT1_TIMER_RATE +#define HAL_TIMER_RATE GPT1_TIMER_RATE +#define STEPPER_TIMER_RATE HAL_TIMER_RATE #define STEPPER_TIMER_TICKS_PER_US ((STEPPER_TIMER_RATE) / 1000000) #define STEPPER_TIMER_PRESCALE ((GPT_TIMER_RATE / 1000000) / STEPPER_TIMER_TICKS_PER_US) diff --git a/Marlin/src/core/boards.h b/Marlin/src/core/boards.h index ed5b649f240d..a459f2329a00 100644 --- a/Marlin/src/core/boards.h +++ b/Marlin/src/core/boards.h @@ -443,7 +443,7 @@ #define BOARD_OPULO_LUMEN_REV4 5241 // Opulo Lumen PnP Controller REV4 (STM32F407VE / STM32F407VG) #define BOARD_FYSETC_SPIDER_KING407 5242 // FYSETC Spider King407 (STM32F407ZG) #define BOARD_MKS_SKIPR_V1 5243 // MKS SKIPR v1.0 all-in-one board (STM32F407VE) -#define BOARD_TRONXY_V10 5244 // TRONXY V10 (STM32F446ZE) +#define BOARD_TRONXY_CXY_446_V10 5244 // TRONXY CXY-446-V10-220413/CXY-V6-191121 (STM32F446ZE) // // ARM Cortex-M7 diff --git a/Marlin/src/core/macros.h b/Marlin/src/core/macros.h index e91187584dc7..65fabf3f54ba 100644 --- a/Marlin/src/core/macros.h +++ b/Marlin/src/core/macros.h @@ -112,7 +112,7 @@ // Macros for bit masks #undef _BV -#define _BV(n) (1<<(n)) +#define _BV(b) (1 << (b)) #define TEST(n,b) (!!((n)&_BV(b))) #define SET_BIT_TO(N,B,TF) do{ if (TF) SBI(N,B); else CBI(N,B); }while(0) #ifndef SBI @@ -134,7 +134,8 @@ #define HYPOT2(x,y) (sq(x)+sq(y)) #define NORMSQ(x,y,z) (sq(x)+sq(y)+sq(z)) -#define CIRCLE_AREA(R) (float(M_PI) * sq(float(R))) +#define FLOAT_SQ(I) sq(float(I)) +#define CIRCLE_AREA(R) (float(M_PI) * FLOAT_SQ(R)) #define CIRCLE_CIRC(R) (2 * float(M_PI) * float(R)) #define SIGN(a) ({__typeof__(a) _a = (a); (_a>0)-(_a<0);}) @@ -240,7 +241,11 @@ #define _DIS_1(O) NOT(_ENA_1(O)) #define ENABLED(V...) DO(ENA,&&,V) #define DISABLED(V...) DO(DIS,&&,V) +#define ANY(V...) !DISABLED(V) +#define ALL(V...) ENABLED(V) +#define NONE(V...) DISABLED(V) #define COUNT_ENABLED(V...) DO(ENA,+,V) +#define MANY(V...) (COUNT_ENABLED(V) > 1) // Ternary pre-compiler macros conceal non-emitted content from the compiler #define TERN(O,A,B) _TERN(_ENA_1(O),B,A) // OPTION ? 'A' : 'B' @@ -250,6 +255,7 @@ #define _TERN(E,V...) __TERN(_CAT(T_,E),V) // Prepend 'T_' to get 'T_0' or 'T_1' #define __TERN(T,V...) ___TERN(_CAT(_NO,T),V) // Prepend '_NO' to get '_NOT_0' or '_NOT_1' #define ___TERN(P,V...) THIRD(P,V) // If first argument has a comma, A. Else B. +#define IF_DISABLED(O,A) TERN(O,,A) // Macros to conditionally emit array items and function arguments #define _OPTITEM(A...) A, @@ -270,15 +276,8 @@ #define MUL_TERN(O,B,A) ((B) MUL_TERN1(O,A)) // ((B) (OPTION ? '* (A)' : '')) #define DIV_TERN(O,B,A) ((B) DIV_TERN1(O,A)) // ((B) (OPTION ? '/ (A)' : '')) -#define IF_ENABLED TERN_ -#define IF_DISABLED(O,A) TERN(O,,A) - -#define ANY(V...) !DISABLED(V) -#define NONE(V...) DISABLED(V) -#define ALL(V...) ENABLED(V) #define BOTH(V1,V2) ALL(V1,V2) #define EITHER(V1,V2) ANY(V1,V2) -#define MANY(V...) (COUNT_ENABLED(V) > 1) // Macros to support pins/buttons exist testing #define PIN_EXISTS(PN) (defined(PN##_PIN) && PN##_PIN >= 0) diff --git a/Marlin/src/core/multi_language.h b/Marlin/src/core/multi_language.h index 2c0eb7aa7297..81a1754d5ef4 100644 --- a/Marlin/src/core/multi_language.h +++ b/Marlin/src/core/multi_language.h @@ -91,6 +91,7 @@ typedef const char Language_Str[]; #define LANG_CHARSIZE GET_TEXT(CHARSIZE) #define USE_WIDE_GLYPH (LANG_CHARSIZE > 2) +// The final "\0" is added invisibly by the compiler #define MSG_1_LINE(A) A "\0" "\0" #define MSG_2_LINE(A,B) A "\0" B "\0" #define MSG_3_LINE(A,B,C) A "\0" B "\0" C diff --git a/Marlin/src/core/serial.cpp b/Marlin/src/core/serial.cpp index 96a333d49b1f..2ff3fd4c3f37 100644 --- a/Marlin/src/core/serial.cpp +++ b/Marlin/src/core/serial.cpp @@ -97,7 +97,7 @@ void print_bin(uint16_t val) { } } -void print_pos(NUM_AXIS_ARGS(const_float_t), FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { +void print_pos(NUM_AXIS_ARGS_LC(const_float_t), FSTR_P const prefix/*=nullptr*/, FSTR_P const suffix/*=nullptr*/) { if (prefix) serial_print(prefix); SERIAL_ECHOPGM_P( LIST_N(DOUBLE(NUM_AXES), SP_X_STR, x, SP_Y_STR, y, SP_Z_STR, z, SP_I_STR, i, SP_J_STR, j, SP_K_STR, k, SP_U_STR, u, SP_V_STR, v, SP_W_STR, w) diff --git a/Marlin/src/core/serial.h b/Marlin/src/core/serial.h index 43777f5f0d29..15c83f77e860 100644 --- a/Marlin/src/core/serial.h +++ b/Marlin/src/core/serial.h @@ -336,7 +336,7 @@ void serial_spaces(uint8_t count); void serial_offset(const_float_t v, const uint8_t sp=0); // For v==0 draw space (sp==1) or plus (sp==2) void print_bin(const uint16_t val); -void print_pos(NUM_AXIS_ARGS(const_float_t), FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); +void print_pos(NUM_AXIS_ARGS_LC(const_float_t), FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr); inline void print_pos(const xyze_pos_t &xyze, FSTR_P const prefix=nullptr, FSTR_P const suffix=nullptr) { print_pos(NUM_AXIS_ELEM(xyze), prefix, suffix); diff --git a/Marlin/src/core/types.h b/Marlin/src/core/types.h index 75dcce4e3cbd..f973b81f6957 100644 --- a/Marlin/src/core/types.h +++ b/Marlin/src/core/types.h @@ -42,33 +42,44 @@ template struct IF { typedef L type; }; #define NUM_AXIS_LIST_1(V) LIST_N_1(NUM_AXES, V) #define NUM_AXIS_ARRAY(V...) { NUM_AXIS_LIST(V) } #define NUM_AXIS_ARRAY_1(V) { NUM_AXIS_LIST_1(V) } -#define NUM_AXIS_ARGS(T) NUM_AXIS_LIST(T x, T y, T z, T i, T j, T k, T u, T v, T w) -#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w) -#define NUM_AXIS_DECL(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V) +#define NUM_AXIS_ARGS(T) NUM_AXIS_LIST(T X, T Y, T Z, T I, T J, T K, T U, T V, T W) +#define NUM_AXIS_ARGS_LC(T) NUM_AXIS_LIST(T x, T y, T z, T i, T j, T k, T u, T v, T w) +#define NUM_AXIS_ELEM(O) NUM_AXIS_LIST(O.X, O.Y, O.Z, O.I, O.J, O.K, O.U, O.V, O.W) +#define NUM_AXIS_ELEM_LC(O) NUM_AXIS_LIST(O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w) +#define NUM_AXIS_DECL(T,V) NUM_AXIS_LIST(T X=V, T Y=V, T Z=V, T I=V, T J=V, T K=V, T U=V, T V=V, T W=V) +#define NUM_AXIS_DECL_LC(T,V) NUM_AXIS_LIST(T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V) #define MAIN_AXIS_NAMES NUM_AXIS_LIST(X, Y, Z, I, J, K, U, V, W) +#define MAIN_AXIS_NAMES_LC NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w) #define STR_AXES_MAIN NUM_AXIS_GANG("X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W) -#define LOGICAL_AXIS_GANG(E,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(E) -#define LOGICAL_AXIS_CODE(E,V...) NUM_AXIS_CODE(V) CODE_ITEM_E(E) -#define LOGICAL_AXIS_LIST(E,V...) NUM_AXIS_LIST(V) LIST_ITEM_E(E) +#define LOGICAL_AXIS_GANG(N,V...) NUM_AXIS_GANG(V) GANG_ITEM_E(N) +#define LOGICAL_AXIS_CODE(N,V...) NUM_AXIS_CODE(V) CODE_ITEM_E(N) +#define LOGICAL_AXIS_LIST(N,V...) NUM_AXIS_LIST(V) LIST_ITEM_E(N) #define LOGICAL_AXIS_LIST_1(V) NUM_AXIS_LIST_1(V) LIST_ITEM_E(V) -#define LOGICAL_AXIS_ARRAY(E,V...) { LOGICAL_AXIS_LIST(E,V) } +#define LOGICAL_AXIS_ARRAY(N,V...) { LOGICAL_AXIS_LIST(N,V) } #define LOGICAL_AXIS_ARRAY_1(V) { LOGICAL_AXIS_LIST_1(V) } -#define LOGICAL_AXIS_ARGS(T) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k, T u, T v, T w) -#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w) -#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V) +#define LOGICAL_AXIS_ARGS(T) LOGICAL_AXIS_LIST(T E, T X, T Y, T Z, T I, T J, T K, T U, T V, T W) +#define LOGICAL_AXIS_ARGS_LC(T) LOGICAL_AXIS_LIST(T e, T x, T y, T z, T i, T j, T k, T u, T v, T w) +#define LOGICAL_AXIS_ELEM(O) LOGICAL_AXIS_LIST(O.E, O.X, O.Y, O.Z, O.I, O.J, O.K, O.U, O.V, O.W) +#define LOGICAL_AXIS_ELEM_LC(O) LOGICAL_AXIS_LIST(O.e, O.x, O.y, O.z, O.i, O.j, O.k, O.u, O.v, O.w) +#define LOGICAL_AXIS_DECL(T,V) LOGICAL_AXIS_LIST(T E=V, T X=V, T Y=V, T Z=V, T I=V, T J=V, T K=V, T U=V, T V=V, T W=V) +#define LOGICAL_AXIS_DECL_LC(T,V) LOGICAL_AXIS_LIST(T e=V, T x=V, T y=V, T z=V, T i=V, T j=V, T k=V, T u=V, T v=V, T w=V) #define LOGICAL_AXIS_NAMES LOGICAL_AXIS_LIST(E, X, Y, Z, I, J, K, U, V, W) +#define LOGICAL_AXIS_NAMES_LC LOGICAL_AXIS_LIST(e, x, y, z, i, j, k, u, v, w) #define LOGICAL_AXIS_MAP(F) MAP(F, LOGICAL_AXIS_NAMES) +#define LOGICAL_AXIS_MAP_LC(F) MAP(F, LOGICAL_AXIS_NAMES_LC) #define STR_AXES_LOGICAL LOGICAL_AXIS_GANG("E", "X", "Y", "Z", STR_I, STR_J, STR_K, STR_U, STR_V, STR_W) #if NUM_AXES #define NUM_AXES_SEP , #define MAIN_AXIS_MAP(F) MAP(F, MAIN_AXIS_NAMES) - #define OPTARGS_NUM(T) , NUM_AXIS_ARGS(T) - #define OPTARGS_LOGICAL(T) , LOGICAL_AXIS_ARGS(T) + #define MAIN_AXIS_MAP_LC(F) MAP(F, MAIN_AXIS_NAMES_LC) + #define OPTARGS_NUM(T) , NUM_AXIS_ARGS_LC(T) + #define OPTARGS_LOGICAL(T) , LOGICAL_AXIS_ARGS_LC(T) #else #define NUM_AXES_SEP #define MAIN_AXIS_MAP(F) + #define MAIN_AXIS_MAP_LC(F) #define OPTARGS_NUM(T) #define OPTARGS_LOGICAL(T) #endif @@ -76,9 +87,10 @@ template struct IF { typedef L type; }; #define NUM_AXIS_GANG_(V...) NUM_AXIS_GANG(V) NUM_AXES_SEP #define NUM_AXIS_LIST_(V...) NUM_AXIS_LIST(V) NUM_AXES_SEP #define NUM_AXIS_LIST_1_(V...) NUM_AXIS_LIST_1(V) NUM_AXES_SEP -#define NUM_AXIS_ARGS_(T) NUM_AXIS_ARGS(T) NUM_AXES_SEP -#define NUM_AXIS_ELEM_(T) NUM_AXIS_ELEM(T) NUM_AXES_SEP +#define NUM_AXIS_ARGS_(T) NUM_AXIS_ARGS_LC(T) NUM_AXES_SEP +#define NUM_AXIS_ELEM_(T) NUM_AXIS_ELEM_LC(T) NUM_AXES_SEP #define MAIN_AXIS_NAMES_ MAIN_AXIS_NAMES NUM_AXES_SEP +#define MAIN_AXIS_NAMES_LC_ MAIN_AXIS_NAMES_LC NUM_AXES_SEP #if LOGICAL_AXES #define LOGICAL_AXES_SEP , @@ -89,14 +101,26 @@ template struct IF { typedef L type; }; #define LOGICAL_AXIS_GANG_(V...) LOGICAL_AXIS_GANG(V) LOGICAL_AXES_SEP #define LOGICAL_AXIS_LIST_(V...) LOGICAL_AXIS_LIST(V) LOGICAL_AXES_SEP #define LOGICAL_AXIS_LIST_1_(V...) LOGICAL_AXIS_LIST_1(V) LOGICAL_AXES_SEP -#define LOGICAL_AXIS_ARGS_(T) LOGICAL_AXIS_ARGS(T) LOGICAL_AXES_SEP +#define LOGICAL_AXIS_ARGS_(T) LOGICAL_AXIS_ARGS_LC(T) LOGICAL_AXES_SEP #define LOGICAL_AXIS_ELEM_(T) LOGICAL_AXIS_ELEM(T) LOGICAL_AXES_SEP +#define LOGICAL_AXIS_ELEM_LC_(T) LOGICAL_AXIS_ELEM_LC(T) LOGICAL_AXES_SEP #define LOGICAL_AXIS_NAMES_ LOGICAL_AXIS_NAMES LOGICAL_AXES_SEP +#define LOGICAL_AXIS_NAMES_LC_ LOGICAL_AXIS_NAMES_LC LOGICAL_AXES_SEP #define SECONDARY_AXIS_GANG(V...) GANG_N(SECONDARY_AXES, V) #define SECONDARY_AXIS_CODE(V...) CODE_N(SECONDARY_AXES, V) #define SECONDARY_AXIS_LIST(V...) LIST_N(SECONDARY_AXES, V) -#define SECONDARY_AXIS_ARGS(T) SECONDARY_AXIS_LIST(T i, T j, T k, T u, T v, T w) +#if SECONDARY_AXES + #define SECONDARY_AXIS_NAMES SECONDARY_AXIS_LIST(I, J, K, U, V, W) + #define SECONDARY_AXIS_NAMES_LC SECONDARY_AXIS_LIST(i, j, k, u, v, w) + #define SECONDARY_AXIS_ARGS(T) SECONDARY_AXIS_LIST(T I, T J, T K, T U, T V, T W) + #define SECONDARY_AXIS_ARGS_LC(T) SECONDARY_AXIS_LIST(T i, T j, T k, T u, T v, T w) + #define SECONDARY_AXIS_MAP(F) MAP(F, SECONDARY_AXIS_NAMES) + #define SECONDARY_AXIS_MAP_LC(F) MAP(F, SECONDARY_AXIS_NAMES_LC) +#else + #define SECONDARY_AXIS_MAP(F) + #define SECONDARY_AXIS_MAP_LC(F) +#endif // Just the XY or XYZ elements #if HAS_Z_AXIS @@ -152,36 +176,90 @@ template struct IF { typedef L type; }; #define FI FORCE_INLINE // Define types based on largest bit width stored value required -#define bits_t(W) typename IF<((W)> 16), uint32_t, typename IF<((W)> 8), uint16_t, uint8_t>::type>::type +#define bits_t(W) typename IF<((W)> 32), uint64_t, typename IF<((W)> 16), uint32_t, typename IF<((W)>8), uint16_t, uint8_t>::type>::type>::type #define uvalue_t(V) typename IF<((V)>65535), uint32_t, typename IF<((V)>255), uint16_t, uint8_t>::type>::type #define value_t(V) typename IF<((V)>32767), int32_t, typename IF<((V)>127), int16_t, int8_t>::type>::type -// General Flags for some number of states +// Define a template for a bit field of N bits, using the smallest type that can hold N bits +template 64)> +struct Flags; + +// Flag bits for <= 64 states template -struct Flags { - typedef uvalue_t(N) flagbits_t; - typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } N8; - typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1; } N16; - typedef struct { bool b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1, b8:1, b9:1, b10:1, b11:1, b12:1, b13:1, b14:1, b15:1, - b16:1, b17:1, b18:1, b19:1, b20:1, b21:1, b22:1, b23:1, b24:1, b25:1, b26:1, b27:1, b28:1, b29:1, b30:1, b31:1; } N32; - union { - flagbits_t b; - typename IF<(N>16), N32, typename IF<(N>8), N16, N8>::type>::type flag; +struct Flags { + typedef bits_t(N) flagbits_t; + flagbits_t b; + + class BitProxy { + public: + BitProxy(flagbits_t& data, int bit) : data_(data), bit_(bit) {} + + BitProxy& operator=(const bool value) { + if (value) + data_ |= (flagbits_t(1) << bit_); + else + data_ &= ~(flagbits_t(1) << bit_); + return *this; + } + + operator bool() const { return bool(data_ & (flagbits_t(1) << bit_)); } + + private: + flagbits_t& data_; + uint8_t bit_; }; + FI void reset() { b = 0; } FI void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); } - FI void set(const int n) { b |= (flagbits_t)_BV(n); } - FI void clear(const int n) { b &= ~(flagbits_t)_BV(n); } - FI bool test(const int n) const { return TEST(b, n); } - FI bool operator[](const int n) { return test(n); } + FI void set(const int n) { b |= (flagbits_t(1) << n); } + FI void clear(const int n) { b &= ~(flagbits_t(1) << n); } + FI bool test(const int n) const { return bool(b & (flagbits_t(1) << n)); } + FI BitProxy operator[](const int n) { return BitProxy(b, n); } FI bool operator[](const int n) const { return test(n); } FI int size() const { return sizeof(b); } - FI operator bool() const { return b; } + FI operator bool() const { return b != 0; } +}; + +// Flag bits for more than 64 states +template +struct Flags { + uint8_t bitmask[(N+7)>>3]; + // Proxy class for handling bit assignment + class BitProxy { + public: + BitProxy(uint8_t data[], int n) : data_(data[n >> 3]), bit_(n & 7) {} + + // Assignment operator + BitProxy& operator=(const bool value) { + if (value) + data_ |= _BV(bit_); + else + data_ &= ~_BV(bit_); + return *this; + } + + // Conversion operator to bool + operator bool() const { return TEST(data_, bit_); } + + private: + uint8_t& data_; + uint8_t bit_; + }; + + FI void reset() { for (uint8_t b = 0; b < sizeof(bitmask); ++b) bitmask[b] = 0; } + FI void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); } + FI void set(const int n) { bitmask[n >> 3] |= _BV(n & 7); } + FI void clear(const int n) { bitmask[n >> 3] &= ~_BV(n & 7); } + FI bool test(const int n) const { return TEST(bitmask[n >> 3], n & 7); } + FI BitProxy operator[](const int n) { return BitProxy(bitmask, n); } + FI bool operator[](const int n) const { return test(n); } + FI int size() const { return sizeof(bitmask); } + FI operator bool() const { for (uint8_t b : bitmask) if (b) return true; return false; } }; // Specialization for a single bool flag template<> -struct Flags<1> { +struct Flags<1, false> { bool b; FI void reset() { b = false; } FI void set(const int n, const bool onoff) { onoff ? set(n) : clear(n); } @@ -211,7 +289,7 @@ typedef struct { FI bool operator[](const int n) { return flags[n]; } FI bool operator[](const int n) const { return flags[n]; } FI int size() const { return sizeof(flags); } - FI operator bool() const { return flags; } + FI operator bool() const { return (bool)flags; } } AxisFlags; // @@ -219,7 +297,7 @@ typedef struct { // // - X_AXIS, Y_AXIS, and Z_AXIS should be used for axes in Cartesian space // - A_AXIS, B_AXIS, and C_AXIS should be used for Steppers, corresponding to XYZ on Cartesians -// - X_HEAD, Y_HEAD, and Z_HEAD should be used for Steppers on Core kinematics +// - X_HEAD, Y_HEAD, and Z_HEAD should be used for axes on Core kinematics // enum AxisEnum : uint8_t { @@ -236,7 +314,7 @@ enum AxisEnum : uint8_t { #endif // Distinct axes, including all E and Core - NUM_AXIS_ENUMS, + NUM_AXIS_HEADS, // Most of the time we refer only to the single E_AXIS #if HAS_EXTRUDERS @@ -258,7 +336,7 @@ enum AxisEnum : uint8_t { ALL_AXES_ENUM = 0xFE, NO_AXIS_ENUM = 0xFF }; -typedef IF<(NUM_AXIS_ENUMS > 8), uint16_t, uint8_t>::type axis_bits_t; +typedef IF<(NUM_AXIS_HEADS > 8), uint16_t, uint8_t>::type axis_bits_t; // // Loop over axes @@ -423,7 +501,9 @@ template struct XYval { union { struct { T x, y; }; + struct { T X, Y; }; struct { T a, b; }; + struct { T A, B; }; T pos[2]; }; @@ -549,7 +629,9 @@ struct XYZval { union { #if NUM_AXES struct { NUM_AXIS_CODE(T x, T y, T z, T i, T j, T k, T u, T v, T w); }; + struct { NUM_AXIS_CODE(T X, T Y, T Z, T I, T J, T K, T U, T V, T W); }; struct { NUM_AXIS_CODE(T a, T b, T c, T _i, T _j, T _k, T _u, T _v, T _w); }; + struct { NUM_AXIS_CODE(T A, T B, T C, T II, T JJ, T KK, T UU, T VV, T WW); }; #endif T pos[NUM_AXES]; }; @@ -563,14 +645,14 @@ struct XYZval { FI void set(const T (&arr)[NUM_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } #if LOGICAL_AXES > NUM_AXES FI void set(const T (&arr)[LOGICAL_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } - FI void set(LOGICAL_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } + FI void set(LOGICAL_AXIS_ARGS_LC(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } #if DISTINCT_AXES > LOGICAL_AXES FI void set(const T (&arr)[DISTINCT_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } #endif #endif // Setter for all individual args - FI void set(NUM_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } + FI void set(NUM_AXIS_ARGS_LC(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } // Setters with fewer elements leave the rest untouched #if HAS_Y_AXIS @@ -605,9 +687,9 @@ struct XYZval { // If any element is true then it's true FI constexpr operator bool() const { return 0 NUM_AXIS_GANG(|| x, || y, || z, || i, || j, || k, || u, || v, || w); } // Smallest element - FI constexpr T small() const { return TERN(HAS_X_AXIS, _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)), 0); } + FI constexpr T small() const { return TERN0(HAS_X_AXIS, _MIN(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w))); } // Largest element - FI constexpr T large() const { return TERN(HAS_X_AXIS, _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w)), 0); } + FI constexpr T large() const { return TERN0(HAS_X_AXIS, _MAX(NUM_AXIS_LIST(x, y, z, i, j, k, u, v, w))); } // Explicit copy and copies with conversion FI constexpr XYZval copy() const { XYZval o = *this; return o; } @@ -636,7 +718,7 @@ struct XYZval { // Assignment operator overrides do the expected thing FI XYZval& operator= (const T v) { set(ARRAY_N_1(NUM_AXES, v)); return *this; } FI XYZval& operator= (const XYval &rs) { set(rs.x, rs.y); return *this; } - FI XYZval& operator= (const XYZEval &rs) { set(NUM_AXIS_ELEM(rs)); return *this; } + FI XYZval& operator= (const XYZEval &rs) { set(NUM_AXIS_ELEM_LC(rs)); return *this; } // Override other operators to get intuitive behaviors FI constexpr XYZval operator+ (const XYval &rs) const { return NUM_AXIS_ARRAY(x + rs.x, y + rs.y, z, i, j, k, u, v, w ); } @@ -695,8 +777,10 @@ struct XYZval { template struct XYZEval { union { + struct { T LOGICAL_AXIS_ARGS_LC(); }; struct { T LOGICAL_AXIS_ARGS(); }; struct { T LOGICAL_AXIS_LIST(_e, a, b, c, _i, _j, _k, _u, _v, _w); }; + struct { T LOGICAL_AXIS_LIST(EE, A, B, C, II, JJ, KK, UU, VV, WW); }; T pos[LOGICAL_AXES]; }; // Reset all to 0 @@ -705,20 +789,20 @@ struct XYZEval { // Setters taking struct types and arrays FI void set(const XYval pxy) { XY_CODE(x = pxy.x, y = pxy.y); } FI void set(const XYval pxy, const T pz) { XYZ_CODE(x = pxy.x, y = pxy.y, z = pz); } - FI void set(const XYZval pxyz) { set(NUM_AXIS_ELEM(pxyz)); } + FI void set(const XYZval pxyz) { set(NUM_AXIS_ELEM_LC(pxyz)); } FI void set(const T (&arr)[NUM_AXES]) { NUM_AXIS_CODE(x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } #if LOGICAL_AXES > NUM_AXES FI void set(const T (&arr)[LOGICAL_AXES]) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } FI void set(const XYval pxy, const T pz, const T pe) { set(pxy, pz); e = pe; } FI void set(const XYZval pxyz, const T pe) { set(pxyz); e = pe; } - FI void set(LOGICAL_AXIS_ARGS(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } + FI void set(LOGICAL_AXIS_ARGS_LC(const T)) { LOGICAL_AXIS_CODE(_e = e, a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } #if DISTINCT_AXES > LOGICAL_AXES FI void set(const T (&arr)[DISTINCT_AXES]) { LOGICAL_AXIS_CODE(e = arr[LOGICAL_AXES-1], x = arr[0], y = arr[1], z = arr[2], i = arr[3], j = arr[4], k = arr[5], u = arr[6], v = arr[7], w = arr[8]); } #endif #endif // Setter for all individual args - FI void set(NUM_AXIS_ARGS(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } + FI void set(NUM_AXIS_ARGS_LC(const T)) { NUM_AXIS_CODE(a = x, b = y, c = z, _i = i, _j = j, _k = k, _u = u, _v = v, _w = w); } // Setters with fewer elements leave the rest untouched #if HAS_Y_AXIS @@ -783,7 +867,7 @@ struct XYZEval { // Assignment operator overrides do the expected thing FI XYZEval& operator= (const T v) { set(LOGICAL_AXIS_LIST_1(v)); return *this; } FI XYZEval& operator= (const XYval &rs) { set(rs.x, rs.y); return *this; } - FI XYZEval& operator= (const XYZval &rs) { set(NUM_AXIS_ELEM(rs)); return *this; } + FI XYZEval& operator= (const XYZval &rs) { set(NUM_AXIS_ELEM_LC(rs)); return *this; } // Override other operators to get intuitive behaviors FI constexpr XYZEval operator+ (const XYval &rs) const { return LOGICAL_AXIS_ARRAY(e, x + rs.x, y + rs.y, z, i, j, k, u, v, w); } @@ -843,7 +927,9 @@ struct XYZarray { union { el data[LOGICAL_AXES]; struct { NUM_AXIS_CODE(T x, T y, T z, T i, T j, T k, T u, T v, T w); }; + struct { NUM_AXIS_CODE(T X, T Y, T Z, T I, T J, T K, T U, T V, T W); }; struct { NUM_AXIS_CODE(T a, T b, T c, T _i, T _j, T _k, T _u, T _v, T _w); }; + struct { NUM_AXIS_CODE(T A, T B, T C, T II, T JJ, T KK, T UU, T VV, T WW); }; }; FI void reset() { ZERO(data); } @@ -889,6 +975,8 @@ struct XYZEarray { union { el data[LOGICAL_AXES]; struct { el LOGICAL_AXIS_ARGS(); }; + struct { el LOGICAL_AXIS_ARGS_LC(); }; + struct { el LOGICAL_AXIS_LIST(EE, A, B, C, II, JJ, KK, UU, VV, WW); }; struct { el LOGICAL_AXIS_LIST(_e, a, b, c, _i, _j, _k, _u, _v, _w); }; }; FI void reset() { ZERO(data); } @@ -900,7 +988,7 @@ struct XYZEarray { // Setter for all individual args FI void set(const int n OPTARGS_NUM(const T)) { NUM_AXIS_CODE(a[n] = x, b[n] = y, c[n] = z, _i[n] = i, _j[n] = j, _k[n] = k, _u[n] = u, _v[n] = v, _w[n] = w); } #if LOGICAL_AXES > NUM_AXES - FI void set(const int n, LOGICAL_AXIS_ARGS(const T)) { LOGICAL_AXIS_CODE(_e[n] = e, a[n] = x, b[n] = y, c[n] = z, _i[n] = i, _j[n] = j, _k[n] = k, _u[n] = u, _v[n] = v, _w[n] = w); } + FI void set(const int n, LOGICAL_AXIS_ARGS_LC(const T)) { LOGICAL_AXIS_CODE(_e[n] = e, a[n] = x, b[n] = y, c[n] = z, _i[n] = i, _j[n] = j, _k[n] = k, _u[n] = u, _v[n] = v, _w[n] = w); } #endif // Setters with fewer elements leave the rest untouched @@ -936,7 +1024,7 @@ class AxisBits; class AxisBits { public: - typedef bits_t(NUM_AXIS_ENUMS) el; + typedef bits_t(NUM_AXIS_HEADS) el; union { el bits; // Axes x, y, z ... e0, e1, e2 ... hx, hy, hz @@ -989,6 +1077,25 @@ class AxisBits { }; }; + class BitProxy { + public: + BitProxy(el& data, int bit) : data_(data), bit_(bit) {} + + BitProxy& operator=(const bool value) { + if (value) + data_ |= (el(1) << bit_); + else + data_ &= ~(el(1) << bit_); + return *this; + } + + operator bool() const { return bool(data_ & (el(1) << bit_)); } + + private: + el& data_; + uint8_t bit_; + }; + AxisBits() { reset(); } // Constructor, setter, and operator= for bit mask @@ -997,7 +1104,7 @@ class AxisBits { FI AxisBits& operator=(const el p) { set(p); return *this; } FI void reset() { set(0); } - FI void fill() { set(_BV(NUM_AXIS_ENUMS) - 1); } + FI void fill() { set(_BV(NUM_AXIS_HEADS) - 1); } #define MSET(pE,pX,pY,pZ,pI,pJ,pK,pU,pV,pW) LOGICAL_AXIS_CODE(e=pE, x=pX, y=pY, z=pZ, i=pI, j=pJ, k=pK, u=pU, v=pV, w=pW) @@ -1086,9 +1193,12 @@ class AxisBits { FI bool toggle(const AxisEnum n) { TBI(bits, n); return TEST(bits, n); } FI void bset(const AxisEnum n) { SBI(bits, n); } FI void bclr(const AxisEnum n) { CBI(bits, n); } + FI void bset(const AxisEnum n, const bool b) { if (b) bset(n); else bclr(n); } // Accessor via an AxisEnum (or any integer) [index] - FI bool operator[](const int n) const { return TEST(bits, n); } + FI BitProxy operator[](const int n) { return BitProxy(bits, n); } + FI BitProxy operator[](const AxisEnum n) { return BitProxy(bits, n); } + FI bool operator[](const int n) const { return TEST(bits, n); } FI bool operator[](const AxisEnum n) const { return TEST(bits, n); } FI AxisBits& operator|=(const el &p) { bits |= el(p); return *this; } diff --git a/Marlin/src/core/utility.cpp b/Marlin/src/core/utility.cpp index 64f083e19718..f1e841356a21 100644 --- a/Marlin/src/core/utility.cpp +++ b/Marlin/src/core/utility.cpp @@ -56,27 +56,35 @@ void safe_delay(millis_t ms) { #include "../feature/bedlevel/bedlevel.h" void log_machine_info() { - SERIAL_ECHOLNPGM("Machine Type: " - TERN_(DELTA, "Delta") - TERN_(IS_SCARA, "SCARA") - TERN_(IS_CORE, "Core") - TERN_(MARKFORGED_XY, "MarkForgedXY") - TERN_(MARKFORGED_YX, "MarkForgedYX") - TERN_(IS_CARTESIAN, "Cartesian") + SERIAL_ECHOLNPGM("Machine Type:" + TERN_(DELTA, " Delta") + TERN_(IS_SCARA, " SCARA") + TERN_(AXEL_TPARA, " TPARA") + TERN_(IS_CORE, " Core") + TERN_(BELTPRINTER, " Belt Printer") + TERN_(MARKFORGED_XY, " MarkForgedXY") + TERN_(MARKFORGED_YX, " MarkForgedYX") + TERN_(POLARGRAPH, " Polargraph") + TERN_(ARTICULATED_ROBOT_ARM, " Robot Arm") + TERN_(FOAMCUTTER_XYUV, " Foam Cutter") + TERN_(IS_CARTESIAN, " Cartesian") ); SERIAL_ECHOLNPGM("Probe: " - TERN_(PROBE_MANUALLY, "PROBE_MANUALLY") - TERN_(NOZZLE_AS_PROBE, "NOZZLE_AS_PROBE") - TERN_(FIX_MOUNTED_PROBE, "FIX_MOUNTED_PROBE") - TERN_(HAS_Z_SERVO_PROBE, TERN(BLTOUCH, "BLTOUCH", "SERVO PROBE")) - TERN_(BD_SENSOR, "BD_SENSOR") - TERN_(TOUCH_MI_PROBE, "TOUCH_MI_PROBE") - TERN_(Z_PROBE_SLED, "Z_PROBE_SLED") - TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY") - TERN_(SOLENOID_PROBE, "SOLENOID_PROBE") - TERN_(MAGLEV4, "MAGLEV4") - IF_DISABLED(PROBE_SELECTED, "NONE") + TERN_(PROBE_MANUALLY, "PROBE_MANUALLY") + TERN_(NOZZLE_AS_PROBE, "NOZZLE_AS_PROBE") + TERN_(FIX_MOUNTED_PROBE, "FIX_MOUNTED_PROBE") + TERN_(HAS_Z_SERVO_PROBE, TERN(BLTOUCH, "BLTOUCH", "SERVO PROBE")) + TERN_(BD_SENSOR, "BD_SENSOR") + TERN_(TOUCH_MI_PROBE, "TOUCH_MI_PROBE") + TERN_(Z_PROBE_ALLEN_KEY, "Z_PROBE_ALLEN_KEY") + TERN_(Z_PROBE_SLED, "Z_PROBE_SLED") + TERN_(RACK_AND_PINION_PROBE, "RACK_AND_PINION_PROBE") + TERN_(SOLENOID_PROBE, "SOLENOID_PROBE") + TERN_(SENSORLESS_PROBING, "SENSORLESS_PROBING") + TERN_(MAGLEV4, "MAGLEV4") + TERN_(MAG_MOUNTED_PROBE, "MAG_MOUNTED_PROBE") + IF_DISABLED(PROBE_SELECTED, "NONE") ); #if HAS_BED_PROBE diff --git a/Marlin/src/feature/bedlevel/abl/bbl.cpp b/Marlin/src/feature/bedlevel/abl/bbl.cpp index 68d29071aae1..14c4bd24bcf0 100644 --- a/Marlin/src/feature/bedlevel/abl/bbl.cpp +++ b/Marlin/src/feature/bedlevel/abl/bbl.cpp @@ -250,12 +250,7 @@ void LevelingBilinear::print_leveling_grid(const bed_mesh_t* _z_values/*=nullptr if ((ty && y == (GRID_MAX_POINTS_Y) - 1) || (tx && x == (GRID_MAX_POINTS_X) - 1)) continue; z_values_virt[x * (BILINEAR_SUBDIVISIONS) + tx][y * (BILINEAR_SUBDIVISIONS) + ty] = - virt_2cmr( - x + 1, - y + 1, - (float)tx / (BILINEAR_SUBDIVISIONS), - (float)ty / (BILINEAR_SUBDIVISIONS) - ); + virt_2cmr(x + 1, y + 1, (float)tx / (BILINEAR_SUBDIVISIONS), (float)ty / (BILINEAR_SUBDIVISIONS)); } } diff --git a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp index 787827bb9bfc..05c9ea8031d0 100644 --- a/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp +++ b/Marlin/src/feature/bedlevel/mbl/mesh_bed_leveling.cpp @@ -63,7 +63,7 @@ */ void mesh_bed_leveling::line_to_destination(const_feedRate_t scaled_fr_mm_s, uint8_t x_splits, uint8_t y_splits) { // Get current and destination cells for this line - xy_int8_t scel = cell_indexes(current_position), ecel = cell_indexes(destination); + xy_uint8_t scel = cell_indexes(current_position), ecel = cell_indexes(destination); NOMORE(scel.x, GRID_MAX_CELLS_X - 1); NOMORE(scel.y, GRID_MAX_CELLS_Y - 1); NOMORE(ecel.x, GRID_MAX_CELLS_X - 1); @@ -80,7 +80,7 @@ float normalized_dist; xyze_pos_t dest; - const int8_t gcx = _MAX(scel.x, ecel.x), gcy = _MAX(scel.y, ecel.y); + const uint8_t gcx = _MAX(scel.x, ecel.x), gcy = _MAX(scel.y, ecel.y); // Crosses on the X and not already split on this X? // The x_splits flags are insurance against rounding errors. diff --git a/Marlin/src/feature/easythreed_ui.cpp b/Marlin/src/feature/easythreed_ui.cpp index 40969e3949c9..9617c62eb945 100644 --- a/Marlin/src/feature/easythreed_ui.cpp +++ b/Marlin/src/feature/easythreed_ui.cpp @@ -189,7 +189,7 @@ void EasythreedUI::printButton() { blink_interval_ms = LED_BLINK_2; // Blink the indicator LED at 1 second intervals print_key_flag = PF_PAUSE; // The "Print" button now pauses the print card.mount(); // Force SD card to mount - now! - if (!card.isMounted) { // Failed to mount? + if (!card.isMounted()) { // Failed to mount? blink_interval_ms = LED_OFF; // Turn off LED print_key_flag = PF_START; return; // Bail out @@ -197,7 +197,7 @@ void EasythreedUI::printButton() { card.ls(); // List all files to serial output const int16_t filecnt = card.get_num_items(); // Count printable files in cwd if (filecnt == 0) return; // None are printable? - card.selectFileByIndex(filecnt); // Select the last file (without sort) + card.selectFileByIndex(filecnt); // Select the last file according to current sort options card.openAndPrintFile(card.filename); // Start printing it } break; case PF_PAUSE: { // Pause printing (not currently firing) diff --git a/Marlin/src/feature/encoder_i2c.cpp b/Marlin/src/feature/encoder_i2c.cpp index 0386b5ccdb35..95a4d47ee7fd 100644 --- a/Marlin/src/feature/encoder_i2c.cpp +++ b/Marlin/src/feature/encoder_i2c.cpp @@ -36,7 +36,7 @@ #include "../module/stepper.h" #include "../gcode/parser.h" -#include "../feature/babystep.h" +#include "babystep.h" #include diff --git a/Marlin/src/feature/ethernet.cpp b/Marlin/src/feature/ethernet.cpp index c5bfa932cb5b..9b022b4e17e3 100644 --- a/Marlin/src/feature/ethernet.cpp +++ b/Marlin/src/feature/ethernet.cpp @@ -141,7 +141,7 @@ void MarlinEthernet::check() { case CONNECTING: telnetClient.println("Marlin " SHORT_BUILD_VERSION); - #if defined(STRING_DISTRIBUTION_DATE) && defined(STRING_CONFIG_H_AUTHOR) + #ifdef STRING_DISTRIBUTION_DATE telnetClient.println( " Last Updated: " STRING_DISTRIBUTION_DATE " | Author: " STRING_CONFIG_H_AUTHOR diff --git a/Marlin/src/feature/filwidth.cpp b/Marlin/src/feature/filwidth.cpp index 3befd7752a6e..1142423cf77a 100644 --- a/Marlin/src/feature/filwidth.cpp +++ b/Marlin/src/feature/filwidth.cpp @@ -28,7 +28,7 @@ FilamentWidthSensor filwidth; -bool FilamentWidthSensor::enabled; // = false; // (M405-M406) Filament Width Sensor ON/OFF. +bool FilamentWidthSensor::enabled; // = false // (M405-M406) Filament Width Sensor ON/OFF. uint32_t FilamentWidthSensor::accum; // = 0 // ADC accumulator uint16_t FilamentWidthSensor::raw; // = 0 // Measured filament diameter - one extruder only float FilamentWidthSensor::nominal_mm = DEFAULT_NOMINAL_FILAMENT_DIA, // (M104) Nominal filament width diff --git a/Marlin/src/feature/fwretract.cpp b/Marlin/src/feature/fwretract.cpp index 8f2edad158dd..23ab878e4386 100644 --- a/Marlin/src/feature/fwretract.cpp +++ b/Marlin/src/feature/fwretract.cpp @@ -137,7 +137,7 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/)) // Retract by moving from a faux E position back to the current E position current_retract[active_extruder] = base_retract; prepare_internal_move_to_destination( // set current from destination - settings.retract_feedrate_mm_s * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) + MUL_TERN(RETRACT_SYNC_MIXING, settings.retract_feedrate_mm_s, MIXING_STEPPERS) ); // Is a Z hop set, and has the hop not yet been done? @@ -165,8 +165,7 @@ void FWRetract::retract(const bool retracting E_OPTARG(bool swapping/*=false*/)) // Recover E, set_current_to_destination prepare_internal_move_to_destination( - (swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s) - * TERN1(RETRACT_SYNC_MIXING, (MIXING_STEPPERS)) + MUL_TERN(RETRACT_SYNC_MIXING, swapping ? settings.swap_retract_recover_feedrate_mm_s : settings.retract_recover_feedrate_mm_s, MIXING_STEPPERS) ); } diff --git a/Marlin/src/feature/host_actions.cpp b/Marlin/src/feature/host_actions.cpp index 235253b5a345..5a57ea1feb54 100644 --- a/Marlin/src/feature/host_actions.cpp +++ b/Marlin/src/feature/host_actions.cpp @@ -187,13 +187,13 @@ void HostUI::action(FSTR_P const fstr, const bool eol) { switch (response) { case 0: // "Purge More" button - #if ALL(M600_PURGE_MORE_RESUMABLE, ADVANCED_PAUSE_FEATURE) + #if ENABLED(M600_PURGE_MORE_RESUMABLE) pause_menu_response = PAUSE_RESPONSE_EXTRUDE_MORE; // Simulate menu selection (menu exits, doesn't extrude more) #endif break; case 1: // "Continue" / "Disable Runout" button - #if ALL(M600_PURGE_MORE_RESUMABLE, ADVANCED_PAUSE_FEATURE) + #if ENABLED(M600_PURGE_MORE_RESUMABLE) pause_menu_response = PAUSE_RESPONSE_RESUME_PRINT; // Simulate menu selection #endif #if HAS_FILAMENT_SENSOR diff --git a/Marlin/src/feature/joystick.cpp b/Marlin/src/feature/joystick.cpp index acab5d7437a2..29addfcf1eba 100644 --- a/Marlin/src/feature/joystick.cpp +++ b/Marlin/src/feature/joystick.cpp @@ -123,7 +123,7 @@ Joystick joystick; void Joystick::inject_jog_moves() { // Recursion barrier - static bool injecting_now; // = false; + static bool injecting_now; // = false if (injecting_now) return; #if ENABLED(NO_MOTION_BEFORE_HOMING) diff --git a/Marlin/src/feature/leds/leds.cpp b/Marlin/src/feature/leds/leds.cpp index ac7f1815162b..8e381ac7f31e 100644 --- a/Marlin/src/feature/leds/leds.cpp +++ b/Marlin/src/feature/leds/leds.cpp @@ -31,7 +31,7 @@ #include "leds.h" #if ANY(CASE_LIGHT_USE_RGB_LED, CASE_LIGHT_USE_NEOPIXEL) - #include "../../feature/caselight.h" + #include "../caselight.h" #endif #if ENABLED(LED_COLOR_PRESETS) @@ -83,7 +83,7 @@ void LEDLights::setup() { if (i == 1 && PWM_PIN(RGB_LED_G_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_G_PIN), led_pwm); else WRITE(RGB_LED_G_PIN, b < 100 ? HIGH : LOW); if (i == 2 && PWM_PIN(RGB_LED_B_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_B_PIN), led_pwm); else WRITE(RGB_LED_B_PIN, b < 100 ? HIGH : LOW); #if ENABLED(RGBW_LED) - if (i == 3){ + if (i == 3) { if (PWM_PIN(RGB_LED_W_PIN)) hal.set_pwm_duty(pin_t(RGB_LED_W_PIN), led_pwm); else WRITE(RGB_LED_W_PIN, b < 100 ? HIGH : LOW); delay(RGB_STARTUP_TEST_INNER_MS);//More slowing for ending diff --git a/Marlin/src/feature/leds/neopixel.h b/Marlin/src/feature/leds/neopixel.h index a724083f1761..bb5d5d938897 100644 --- a/Marlin/src/feature/leds/neopixel.h +++ b/Marlin/src/feature/leds/neopixel.h @@ -129,7 +129,7 @@ class Marlin_NeoPixel { } // Accessors - static uint16_t pixels() { return adaneo1.numPixels() * TERN1(NEOPIXEL2_INSERIES, 2); } + static uint16_t pixels() { return MUL_TERN(NEOPIXEL2_INSERIES, adaneo1.numPixels(), 2); } static uint32_t pixel_color(const uint16_t n) { #if ENABLED(NEOPIXEL2_INSERIES) diff --git a/Marlin/src/feature/leds/pca9632.cpp b/Marlin/src/feature/leds/pca9632.cpp index 07c379a8154a..40c16a9276a6 100644 --- a/Marlin/src/feature/leds/pca9632.cpp +++ b/Marlin/src/feature/leds/pca9632.cpp @@ -148,7 +148,7 @@ void PCA9632_set_led_color(const LEDColor &color) { #if ENABLED(PCA9632_BUZZER) - void PCA9632_buzz(const long, const uint16_t=0) { + void PCA9632_buzz(const long, const uint16_t/*=0*/) { uint8_t data[] = PCA9632_BUZZER_DATA; Wire.beginTransmission(I2C_ADDRESS(PCA9632_ADDRESS)); Wire.write(data, sizeof(data)); diff --git a/Marlin/src/feature/mmu/mmu2.cpp b/Marlin/src/feature/mmu/mmu2.cpp index 4e65cd431b73..35dc850dd53a 100644 --- a/Marlin/src/feature/mmu/mmu2.cpp +++ b/Marlin/src/feature/mmu/mmu2.cpp @@ -24,6 +24,10 @@ #if HAS_PRUSA_MMU2 +/** + * mmu2.cpp - Support for Průša MMU2 and MMU2S + */ + #include "mmu2.h" #include "../../lcd/menu/menu_mmu2.h" @@ -39,7 +43,7 @@ MMU2 mmu2; #include "../../MarlinCore.h" #if ENABLED(HOST_PROMPT_SUPPORT) - #include "../../feature/host_actions.h" + #include "../host_actions.h" #endif #if ENABLED(EXTENSIBLE_UI) diff --git a/Marlin/src/feature/mmu/mmu2.h b/Marlin/src/feature/mmu/mmu2.h index 515f400b4ce3..fff7a8f83fd2 100644 --- a/Marlin/src/feature/mmu/mmu2.h +++ b/Marlin/src/feature/mmu/mmu2.h @@ -21,6 +21,10 @@ */ #pragma once +/** + * mmu2.h - Support for Průša MMU2 and MMU2S + */ + #include "../../inc/MarlinConfig.h" #if HAS_FILAMENT_SENSOR diff --git a/Marlin/src/feature/power.cpp b/Marlin/src/feature/power.cpp index 3774a8cbae5d..1855b1650c2e 100644 --- a/Marlin/src/feature/power.cpp +++ b/Marlin/src/feature/power.cpp @@ -175,7 +175,7 @@ void Power::power_off() { /** * Check all conditions that would signal power needing to be on. * - * @returns bool if power is needed + * @return bool if power is needed */ bool Power::is_power_needed() { diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp index 69e23f4a3230..3c72ed51039b 100644 --- a/Marlin/src/feature/powerloss.cpp +++ b/Marlin/src/feature/powerloss.cpp @@ -35,7 +35,7 @@ #include "../lcd/extui/ui_api.h" #endif -bool PrintJobRecovery::enabled; // Initialized by settings.load() +bool PrintJobRecovery::enabled; // Initialized by settings.load MediaFile PrintJobRecovery::file; job_recovery_info_t PrintJobRecovery::info; @@ -92,7 +92,7 @@ PrintJobRecovery recovery; /** * Clear the recovery info */ -void PrintJobRecovery::init() { memset(&info, 0, sizeof(info)); } +void PrintJobRecovery::init() { info = {}; } /** * Enable or disable then call changed() diff --git a/Marlin/src/feature/powerloss.h b/Marlin/src/feature/powerloss.h index 09ceab5c7ee4..29cba5fdf398 100644 --- a/Marlin/src/feature/powerloss.h +++ b/Marlin/src/feature/powerloss.h @@ -31,11 +31,11 @@ #include "../inc/MarlinConfig.h" #if ENABLED(GCODE_REPEAT_MARKERS) - #include "../feature/repeat.h" + #include "repeat.h" #endif #if ENABLED(MIXING_EXTRUDER) - #include "../feature/mixing.h" + #include "mixing.h" #endif #if !defined(POWER_LOSS_STATE) && PIN_EXISTS(POWER_LOSS) diff --git a/Marlin/src/feature/runout.cpp b/Marlin/src/feature/runout.cpp index 98b6bd051061..aac1cc9c339e 100644 --- a/Marlin/src/feature/runout.cpp +++ b/Marlin/src/feature/runout.cpp @@ -59,7 +59,7 @@ bool FilamentMonitorBase::enabled = true, // Filament Runout event handler // #include "../MarlinCore.h" -#include "../feature/pause.h" +#include "pause.h" #include "../gcode/queue.h" #if ENABLED(HOST_ACTION_COMMANDS) diff --git a/Marlin/src/feature/runout.h b/Marlin/src/feature/runout.h index 252f11a45915..b5e32e0def78 100644 --- a/Marlin/src/feature/runout.h +++ b/Marlin/src/feature/runout.h @@ -30,7 +30,7 @@ #include "../module/planner.h" #include "../module/stepper.h" // for block_t #include "../gcode/queue.h" -#include "../feature/pause.h" +#include "pause.h" // for did_pause_print #include "../inc/MarlinConfig.h" diff --git a/Marlin/src/feature/spindle_laser.cpp b/Marlin/src/feature/spindle_laser.cpp index c0635c72206f..b83c1c17972f 100644 --- a/Marlin/src/feature/spindle_laser.cpp +++ b/Marlin/src/feature/spindle_laser.cpp @@ -35,7 +35,7 @@ #endif #if ENABLED(I2C_AMMETER) - #include "../feature/ammeter.h" + #include "ammeter.h" #endif SpindleLaser cutter; diff --git a/Marlin/src/feature/spindle_laser.h b/Marlin/src/feature/spindle_laser.h index 681df2f081e7..a443d7df5e0c 100644 --- a/Marlin/src/feature/spindle_laser.h +++ b/Marlin/src/feature/spindle_laser.h @@ -35,8 +35,12 @@ // Inline laser power #include "../module/planner.h" +#define RPM_TO_PWM(X) ((X) * 255 / (SPEED_POWER_MAX)) +#define PWM_TO_RPM(X) ((X) * (SPEED_POWER_MAX) / 255) #define PCT_TO_PWM(X) ((X) * 255 / 100) +#define PWM_TO_PCT(X) ((X) * 100 / 255) #define PCT_TO_SERVO(X) ((X) * 180 / 100) +#define CUTTER_PWM_TO_SPWR(X) (CUTTER_UNIT_IS(PERCENT) ? PWM_TO_PCT(X) : (CUTTER_UNIT_IS(RPM) ? PWM_TO_RPM(X) : X)) // Laser/Cutter operation mode enum CutterMode : int8_t { diff --git a/Marlin/src/feature/tmc_util.cpp b/Marlin/src/feature/tmc_util.cpp index a3f15e1129a3..228ab27ac0cc 100644 --- a/Marlin/src/feature/tmc_util.cpp +++ b/Marlin/src/feature/tmc_util.cpp @@ -943,7 +943,7 @@ * M122 report functions */ - void tmc_report_all(LOGICAL_AXIS_ARGS(const bool)) { + void tmc_report_all(LOGICAL_AXIS_ARGS_LC(const bool)) { #define TMC_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_debug_loop(ITEM OPTARGS_LOGICAL()); }while(0) #define DRV_REPORT(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); drv_status_loop(ITEM OPTARGS_LOGICAL()); }while(0) @@ -1153,7 +1153,7 @@ SERIAL_EOL(); } - void tmc_get_registers(LOGICAL_AXIS_ARGS(bool)) { + void tmc_get_registers(LOGICAL_AXIS_ARGS_LC(bool)) { #define _TMC_GET_REG(LABEL, ITEM) do{ SERIAL_ECHOPGM(LABEL); tmc_get_registers(ITEM OPTARGS_LOGICAL()); }while(0) #define TMC_GET_REG(NAME, TABS) _TMC_GET_REG(STRINGIFY(NAME) TABS, TMC_GET_##NAME) _TMC_GET_REG("\t", TMC_AXIS_CODES); @@ -1233,7 +1233,7 @@ static bool test_connection(TMC &st) { return test_result; } -void test_tmc_connection(LOGICAL_AXIS_ARGS(const bool)) { +void test_tmc_connection(LOGICAL_AXIS_ARGS_LC(const bool)) { uint8_t axis_connection = 0; if (TERN0(HAS_X_AXIS, x)) { diff --git a/Marlin/src/feature/tmc_util.h b/Marlin/src/feature/tmc_util.h index 4ba38359069a..b884016bec39 100644 --- a/Marlin/src/feature/tmc_util.h +++ b/Marlin/src/feature/tmc_util.h @@ -335,7 +335,7 @@ void test_tmc_connection(LOGICAL_AXIS_DECL(const bool, true)); void tmc_set_report_interval(const uint16_t update_interval); #endif void tmc_report_all(LOGICAL_AXIS_DECL(const bool, true)); - void tmc_get_registers(LOGICAL_AXIS_ARGS(const bool)); + void tmc_get_registers(LOGICAL_AXIS_ARGS_LC(const bool)); #endif /** diff --git a/Marlin/src/feature/x_twist.cpp b/Marlin/src/feature/x_twist.cpp index b8f7e52ab6d5..2b7924707e9a 100644 --- a/Marlin/src/feature/x_twist.cpp +++ b/Marlin/src/feature/x_twist.cpp @@ -30,7 +30,7 @@ XATC xatc; bool XATC::enabled; float XATC::spacing, XATC::start; -xatc_array_t XATC::z_offset; // Initialized by settings.load() +xatc_array_t XATC::z_offset; // Initialized by settings.load void XATC::reset() { constexpr float xzo[] = XATC_Z_OFFSETS; diff --git a/Marlin/src/gcode/bedlevel/G26.cpp b/Marlin/src/gcode/bedlevel/G26.cpp index 30643cb84e9b..209ae4a2754a 100644 --- a/Marlin/src/gcode/bedlevel/G26.cpp +++ b/Marlin/src/gcode/bedlevel/G26.cpp @@ -58,10 +58,10 @@ * * L # Layer Layer height. (Height of nozzle above bed) If not specified .20mm will be used. * - * O # Ooooze How much your nozzle will Ooooze filament while getting in position to print. This - * is over kill, but using this parameter will let you get the very first 'circle' perfect - * so you have a trophy to peel off of the bed and hang up to show how perfectly you have your - * Mesh calibrated. If not specified, a filament length of .3mm is assumed. + * O # Ooze How much your nozzle will Ooooze filament while getting in position to print. If not + * specified, a filament length of .3mm is assumed. This might be overkill, but this + * parameter ensures the very first 'circle' is perfect (providing an ideal trophy to hang + * up to show off your perfectly calibrated Mesh). * * P # Prime Prime the nozzle with specified length of filament. If this parameter is not * given, no prime action will take place. If the parameter specifies an amount, that much @@ -102,7 +102,7 @@ #define G26_OK false #define G26_ERR true -#include "../../gcode/gcode.h" +#include "../gcode.h" #include "../../feature/bedlevel/bedlevel.h" #include "../../MarlinCore.h" diff --git a/Marlin/src/gcode/bedlevel/G42.cpp b/Marlin/src/gcode/bedlevel/G42.cpp index cb5ed9740604..44f5ceada884 100644 --- a/Marlin/src/gcode/bedlevel/G42.cpp +++ b/Marlin/src/gcode/bedlevel/G42.cpp @@ -27,47 +27,56 @@ #include "../gcode.h" #include "../../MarlinCore.h" // for IsRunning() #include "../../module/motion.h" -#include "../../module/probe.h" // for probe.offset #include "../../feature/bedlevel/bedlevel.h" +#if HAS_PROBE_XY_OFFSET + #include "../../module/probe.h" // for probe.offset +#endif + /** * G42: Move X & Y axes to mesh coordinates (I & J) + * + * Parameters: + * F : Feedrate in mm/min + * I : X axis point index + * J : Y axis point index + * P : Flag to put the probe at the given point */ void GcodeSuite::G42() { - if (MOTION_CONDITIONS) { - const bool hasI = parser.seenval('I'); - const int8_t ix = hasI ? parser.value_int() : 0; - const bool hasJ = parser.seenval('J'); - const int8_t iy = hasJ ? parser.value_int() : 0; + if (!MOTION_CONDITIONS) return; - if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) { - SERIAL_ECHOLNPGM(STR_ERR_MESH_XY); - return; - } + const bool hasI = parser.seenval('I'); + const int8_t ix = hasI ? parser.value_int() : 0; + const bool hasJ = parser.seenval('J'); + const int8_t iy = hasJ ? parser.value_int() : 0; - // Move to current_position, as modified by I, J, P parameters - destination = current_position; + if ((hasI && !WITHIN(ix, 0, GRID_MAX_POINTS_X - 1)) || (hasJ && !WITHIN(iy, 0, GRID_MAX_POINTS_Y - 1))) { + SERIAL_ECHOLNPGM(STR_ERR_MESH_XY); + return; + } - if (hasI) destination.x = bedlevel.get_mesh_x(ix); - if (hasJ) destination.y = bedlevel.get_mesh_y(iy); + // Move to current_position, as modified by I, J, P parameters + destination = current_position; - #if HAS_PROBE_XY_OFFSET - if (parser.boolval('P')) { - if (hasI) destination.x -= probe.offset_xy.x; - if (hasJ) destination.y -= probe.offset_xy.y; - } - #endif + if (hasI) destination.x = bedlevel.get_mesh_x(ix); + if (hasJ) destination.y = bedlevel.get_mesh_y(iy); - const feedRate_t fval = parser.linearval('F'), - fr_mm_s = MMM_TO_MMS(fval > 0 ? fval : 0.0f); + #if HAS_PROBE_XY_OFFSET + if (parser.seen_test('P')) { + if (hasI) destination.x -= probe.offset_xy.x; + if (hasJ) destination.y -= probe.offset_xy.y; + } + #endif - // SCARA kinematic has "safe" XY raw moves - #if IS_SCARA - prepare_internal_fast_move_to_destination(fr_mm_s); - #else - prepare_internal_move_to_destination(fr_mm_s); - #endif - } + const feedRate_t fval = parser.linearval('F'), + fr_mm_s = MMM_TO_MMS(fval > 0 ? fval : 0.0f); + + // SCARA kinematic has "safe" XY raw moves + #if IS_SCARA + prepare_internal_fast_move_to_destination(fr_mm_s); + #else + prepare_internal_move_to_destination(fr_mm_s); + #endif } #endif // HAS_MESH diff --git a/Marlin/src/gcode/bedlevel/M420.cpp b/Marlin/src/gcode/bedlevel/M420.cpp index 277f95b9ffe1..8852d38dc0cb 100644 --- a/Marlin/src/gcode/bedlevel/M420.cpp +++ b/Marlin/src/gcode/bedlevel/M420.cpp @@ -27,7 +27,10 @@ #include "../gcode.h" #include "../../feature/bedlevel/bedlevel.h" #include "../../module/planner.h" -#include "../../module/probe.h" + +#if ENABLED(MARLIN_DEV_MODE) + #include "../../module/probe.h" +#endif #if ENABLED(EEPROM_SETTINGS) #include "../../module/settings.h" diff --git a/Marlin/src/gcode/bedlevel/abl/G29.cpp b/Marlin/src/gcode/bedlevel/abl/G29.cpp index 2d0ef57b26ee..282fe0867b3a 100644 --- a/Marlin/src/gcode/bedlevel/abl/G29.cpp +++ b/Marlin/src/gcode/bedlevel/abl/G29.cpp @@ -73,6 +73,11 @@ #endif #endif +/** + * @brief Do some things before returning from G29. + * @param retry : true if the G29 can and should be retried. false if the failure is too serious. + * @param did : true if the leveling procedure completed successfully. + */ static void pre_g29_return(const bool retry, const bool did) { if (!retry) { TERN_(FULL_REPORT_TO_HOST_FEATURE, set_and_report_grblstate(M_IDLE, false)); diff --git a/Marlin/src/gcode/calibrate/G28.cpp b/Marlin/src/gcode/calibrate/G28.cpp index fe1f87409afb..c345343d986f 100644 --- a/Marlin/src/gcode/calibrate/G28.cpp +++ b/Marlin/src/gcode/calibrate/G28.cpp @@ -28,6 +28,10 @@ #include "../../module/planner.h" #include "../../module/stepper.h" // for various +#if HAS_HOMING_CURRENT + #include "../../module/motion.h" // for set/restore_homing_current +#endif + #if HAS_MULTI_HOTEND #include "../../module/tool_change.h" #endif @@ -44,7 +48,9 @@ #include "../../feature/tmc_util.h" #endif -#include "../../module/probe.h" +#if HAS_BED_PROBE + #include "../../module/probe.h" +#endif #if ENABLED(BLTOUCH) #include "../../feature/bltouch.h" @@ -124,14 +130,7 @@ * (Z is already at the right height) */ constexpr xy_float_t safe_homing_xy = { Z_SAFE_HOMING_X_POINT, Z_SAFE_HOMING_Y_POINT }; - #if HAS_HOME_OFFSET - xy_float_t okay_homing_xy = safe_homing_xy; - okay_homing_xy -= home_offset; - #else - constexpr xy_float_t okay_homing_xy = safe_homing_xy; - #endif - - destination.set(okay_homing_xy, current_position.z); + destination.set(safe_homing_xy, current_position.z); TERN_(HOMING_Z_WITH_PROBE, destination -= probe.offset_xy); @@ -503,7 +502,7 @@ void GcodeSuite::G28() { #else homeaxis(Z_AXIS); #endif - probe.move_z_after_homing(); + TERN_(HAS_BED_PROBE, probe.move_z_after_homing()); } #endif diff --git a/Marlin/src/gcode/config/M43.cpp b/Marlin/src/gcode/config/M43.cpp index de511d9e0e50..52ede7d2314f 100644 --- a/Marlin/src/gcode/config/M43.cpp +++ b/Marlin/src/gcode/config/M43.cpp @@ -63,19 +63,21 @@ inline void toggle_pins() { for (uint8_t i = start; i <= end; ++i) { pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (!VALID_PIN(pin)) continue; + if (!isValidPin(pin)) continue; if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) { - report_pin_state_extended(pin, ignore_protection, true, F("Untouched ")); + printPinStateExt(pin, ignore_protection, true, F("Untouched ")); SERIAL_EOL(); } else { hal.watchdog_refresh(); - report_pin_state_extended(pin, ignore_protection, true, F("Pulsing ")); - #ifdef __STM32F1__ - const auto prior_mode = _GET_MODE(i); - #else - const bool prior_mode = GET_PINMODE(pin); - #endif + printPinStateExt(pin, ignore_protection, true, F("Pulsing ")); + const auto prior_mode = ( + #ifdef __STM32F1__ + _GET_MODE(i) + #else + getValidPinMode(pin) + #endif + ); #if AVR_AT90USB1286_FAMILY // Teensy IDEs don't know about these pins so must use FASTIO if (pin == TEENSY_E2) { SET_OUTPUT(TEENSY_E2); @@ -118,7 +120,7 @@ inline void toggle_pins() { inline void servo_probe_test() { - #if !(NUM_SERVOS > 0 && HAS_SERVO_0) + #if !HAS_SERVO_0 SERIAL_ERROR_MSG("SERVO not set up."); @@ -139,24 +141,15 @@ inline void servo_probe_test() { bool deploy_state = false, stow_state; #if ENABLED(Z_MIN_PROBE_USES_Z_MIN_ENDSTOP_PIN) - #define PROBE_TEST_PIN Z_MIN_PIN - constexpr bool probe_inverting = Z_MIN_ENDSTOP_INVERTING; - - SERIAL_ECHOLNPGM(". Probe Z_MIN_PIN: ", PROBE_TEST_PIN); - SERIAL_ECHOPGM(". Z_MIN_ENDSTOP_INVERTING: "); - + #define _PROBE_PREF "Z_MIN" #else - #define PROBE_TEST_PIN Z_MIN_PROBE_PIN - constexpr bool probe_inverting = Z_MIN_PROBE_ENDSTOP_INVERTING; - - SERIAL_ECHOLNPGM(". Probe Z_MIN_PROBE_PIN: ", PROBE_TEST_PIN); - SERIAL_ECHOPGM( ". Z_MIN_PROBE_ENDSTOP_INVERTING: "); - + #define _PROBE_PREF "Z_MIN_PROBE" #endif - serialprint_truefalse(probe_inverting); + SERIAL_ECHOLNPGM(". Probe " _PROBE_PREF "_PIN: ", PROBE_TEST_PIN); + serial_ternary(F(". " _PROBE_PREF "_ENDSTOP_HIT_STATE: "), PROBE_HIT_STATE, F("HIGH"), F("LOW")); SERIAL_EOL(); SET_INPUT_PULLUP(PROBE_TEST_PIN); @@ -205,7 +198,7 @@ inline void servo_probe_test() { stow_state = READ(PROBE_TEST_PIN); } - if (probe_inverting != deploy_state) SERIAL_ECHOLNPGM("WARNING: INVERTING setting probably backwards."); + if (probe_inverting != deploy_state) SERIAL_ECHOLNPGM("WARNING: " _PROBE_PREF "_ENDSTOP_HIT_STATE is probably wrong."); if (deploy_state != stow_state) { SERIAL_ECHOLNPGM("= Mechanical Switch detected"); @@ -337,14 +330,14 @@ void GcodeSuite::M43() { bool can_watch = false; for (uint8_t i = first_pin; i <= last_pin; ++i) { pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (!VALID_PIN(pin)) continue; + if (!isValidPin(pin)) continue; if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; can_watch = true; pinMode(pin, INPUT_PULLUP); delay(1); /* - if (IS_ANALOG(pin)) - pin_state[pin - first_pin] = analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)); // int16_t pin_state[...] + if (isAnalogPin(pin)) + pin_state[pin - first_pin] = analogRead(digitalPinToAnalogIndex(pin)); // int16_t pin_state[...] else //*/ pin_state[i - first_pin] = extDigitalRead(pin); @@ -380,17 +373,17 @@ void GcodeSuite::M43() { for (;;) { for (uint8_t i = first_pin; i <= last_pin; ++i) { const pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (!VALID_PIN(pin)) continue; + if (!isValidPin(pin)) continue; if (M43_NEVER_TOUCH(i) || (!ignore_protection && pin_is_protected(pin))) continue; const byte val = /* - IS_ANALOG(pin) - ? analogRead(DIGITAL_PIN_TO_ANALOG_PIN(pin)) : // int16_t val + isAnalogPin(pin) + ? analogRead(digitalPinToAnalogIndex(pin)) : // int16_t val : //*/ extDigitalRead(pin); if (val != pin_state[i - first_pin]) { - report_pin_state_extended(pin, ignore_protection, true); + printPinStateExt(pin, ignore_protection, true); pin_state[i - first_pin] = val; } } @@ -409,7 +402,7 @@ void GcodeSuite::M43() { // Report current state of selected pin(s) for (uint8_t i = first_pin; i <= last_pin; ++i) { const pin_t pin = GET_PIN_MAP_PIN_M43(i); - if (VALID_PIN(pin)) report_pin_state_extended(pin, ignore_protection, true); + if (isValidPin(pin)) printPinStateExt(pin, ignore_protection, true); } } } diff --git a/Marlin/src/gcode/control/M10-M11.cpp b/Marlin/src/gcode/control/M10_M11.cpp similarity index 95% rename from Marlin/src/gcode/control/M10-M11.cpp rename to Marlin/src/gcode/control/M10_M11.cpp index d5a69dcfccfb..8fd299c5465b 100644 --- a/Marlin/src/gcode/control/M10-M11.cpp +++ b/Marlin/src/gcode/control/M10_M11.cpp @@ -20,6 +20,11 @@ * */ +/** + * gcode/control/M10_M11.cpp + * Air Evacuation + */ + #include "../../inc/MarlinConfig.h" #if ENABLED(AIR_EVACUATION) diff --git a/Marlin/src/gcode/feature/pause/G27.cpp b/Marlin/src/gcode/feature/pause/G27.cpp index f61453e6fb75..229b22a96c0a 100644 --- a/Marlin/src/gcode/feature/pause/G27.cpp +++ b/Marlin/src/gcode/feature/pause/G27.cpp @@ -29,7 +29,14 @@ #include "../../../module/motion.h" /** - * G27: Park the nozzle + * G27: Park the nozzle according with the given style + * + * P